smp_demo.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2022-8-16 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtthread.h>
  13. #if defined(RT_USING_SMP)
  14. #include "drv_common.h"
  15. #define DEF_COUNTER_ADDR_RTP (3*1024*1024)
  16. #define DEF_COUNTER_ADDR_A35 ((0x80000000+DEF_COUNTER_ADDR_RTP)|UNCACHEABLE)
  17. #if defined(USE_MA35D1_SUBM)
  18. #define DEF_COUNTER_ADDR DEF_COUNTER_ADDR_RTP
  19. #else
  20. #define DEF_COUNTER_ADDR DEF_COUNTER_ADDR_A35
  21. #endif
  22. void happy_counter(void *pdata)
  23. {
  24. uint32_t counter = 0;
  25. while (1)
  26. {
  27. rt_kprintf("cpu-%d %d\r\n", rt_hw_cpu_id(), counter++);
  28. rt_thread_mdelay(1000);
  29. }
  30. }
  31. void go_happy_counter(void)
  32. {
  33. rt_thread_t tid = rt_thread_create("cpu-1", happy_counter, RT_NULL, 2048, 10, 20);
  34. RT_ASSERT(tid != RT_NULL);
  35. rt_thread_control(tid, RT_THREAD_CTRL_BIND_CPU, (void *)1);
  36. rt_thread_startup(tid);
  37. }
  38. MSH_CMD_EXPORT(go_happy_counter, go happy counter);
  39. void happy_memcpy(void *pdata)
  40. {
  41. volatile uint32_t counter = 0;
  42. void *srcbuf, *dstbuf;
  43. rt_tick_t last, now;
  44. #define DEF_BUF_SIZE 4096
  45. #define DEF_TIMES 500000
  46. srcbuf = rt_malloc_align(DEF_BUF_SIZE, nu_cpu_dcache_line_size());
  47. dstbuf = rt_malloc_align(DEF_BUF_SIZE, nu_cpu_dcache_line_size());
  48. now = rt_tick_get();
  49. while (counter < DEF_TIMES)
  50. {
  51. rt_memcpy(dstbuf, srcbuf, DEF_BUF_SIZE);
  52. counter++;
  53. }
  54. last = rt_tick_get();
  55. if (rt_hw_cpu_id() == 1)
  56. rt_thread_mdelay(1000);
  57. rt_kprintf("%d Bytes copied by cpu-%d in %d ms\n", DEF_TIMES * DEF_BUF_SIZE, rt_hw_cpu_id(), last - now);
  58. rt_free_align(srcbuf);
  59. rt_free_align(dstbuf);
  60. }
  61. void go_happy_memcpy_0_1(void)
  62. {
  63. rt_thread_t tid0, tid1;
  64. tid0 = rt_thread_create("cpu-0", happy_memcpy, RT_NULL, 2048, 10, 20);
  65. RT_ASSERT(tid0 != RT_NULL);
  66. rt_thread_control(tid0, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  67. tid1 = rt_thread_create("cpu-1", happy_memcpy, RT_NULL, 2048, 10, 20);
  68. RT_ASSERT(tid1 != RT_NULL);
  69. rt_thread_control(tid1, RT_THREAD_CTRL_BIND_CPU, (void *)1);
  70. rt_thread_startup(tid0);
  71. rt_thread_startup(tid1);
  72. }
  73. MSH_CMD_EXPORT(go_happy_memcpy_0_1, go happy memcpy on dual - core);
  74. void go_happy_memcpy_0(void)
  75. {
  76. rt_thread_t tid0;
  77. tid0 = rt_thread_create("cpu-0", happy_memcpy, RT_NULL, 2048, 10, 20);
  78. RT_ASSERT(tid0 != RT_NULL);
  79. rt_thread_control(tid0, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  80. rt_thread_startup(tid0);
  81. }
  82. MSH_CMD_EXPORT(go_happy_memcpy_0, go happy memcpy on core0);
  83. void go_happy_memcpy_1(void)
  84. {
  85. rt_thread_t tid1;
  86. tid1 = rt_thread_create("cpu-1", happy_memcpy, RT_NULL, 2048, 10, 20);
  87. RT_ASSERT(tid1 != RT_NULL);
  88. rt_thread_control(tid1, RT_THREAD_CTRL_BIND_CPU, (void *)1);
  89. rt_thread_startup(tid1);
  90. }
  91. MSH_CMD_EXPORT(go_happy_memcpy_1, go happy memcpy on core1);
  92. static void happy_mutex(void *parameter)
  93. {
  94. rt_err_t ret;
  95. rt_mutex_t psMutex = (rt_mutex_t)parameter;
  96. uint32_t *pu32Counter = (uint32_t *)DEF_COUNTER_ADDR;
  97. *pu32Counter = 0;
  98. while (1)
  99. {
  100. ret = rt_mutex_take(psMutex, RT_WAITING_FOREVER);
  101. if (ret != RT_EOK)
  102. continue;
  103. if (*pu32Counter >= 1000)
  104. {
  105. rt_mutex_release(psMutex);
  106. break;
  107. }
  108. else
  109. *pu32Counter = *pu32Counter + 1;
  110. #ifdef RT_USING_SMP
  111. rt_kprintf("[%08x@CPU-%d] ->Inc %d@%08x\n", rt_thread_self(), rt_hw_cpu_id(), *pu32Counter, DEF_COUNTER_ADDR);
  112. #else
  113. rt_kprintf("[%08x]-> Inc %d@%08x\n", rt_thread_self(), *pu32Counter, DEF_COUNTER_ADDR);
  114. #endif /* RT_USING_SMP */
  115. rt_mutex_release(psMutex);
  116. }
  117. }
  118. static int go_happy_mutex(void)
  119. {
  120. rt_thread_t thread;
  121. rt_mutex_t sem = rt_mutex_create("mutexsem", RT_IPC_FLAG_PRIO);
  122. if(sem == RT_NULL)
  123. {
  124. rt_kprintf("create mutex failed");
  125. return (int)-RT_ERROR;
  126. }
  127. thread = rt_thread_create("mutex0", happy_mutex, (void *)sem, 2048, 25, 20);
  128. if (thread != RT_NULL)
  129. {
  130. #ifdef RT_USING_SMP
  131. rt_thread_control(thread, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  132. #endif
  133. rt_thread_startup(thread);
  134. }
  135. thread = rt_thread_create("mutex1", happy_mutex, (void *)sem, 2048, 25, 20);
  136. if (thread != RT_NULL)
  137. {
  138. #ifdef RT_USING_SMP
  139. rt_thread_control(thread, RT_THREAD_CTRL_BIND_CPU, (void *)1);
  140. #endif
  141. rt_thread_startup(thread);
  142. }
  143. return 0;
  144. }
  145. MSH_CMD_EXPORT(go_happy_mutex, demo mutex);
  146. #endif