test_freertos.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. Test for multicore FreeRTOS. This test spins up threads, fiddles with queues etc.
  3. */
  4. #include <esp_types.h>
  5. #include <stdio.h>
  6. #include "rom/ets_sys.h"
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "freertos/semphr.h"
  10. #include "freertos/queue.h"
  11. #include "freertos/xtensa_api.h"
  12. #include "unity.h"
  13. #include "soc/uart_reg.h"
  14. #include "soc/dport_reg.h"
  15. #include "soc/io_mux_reg.h"
  16. void ets_isr_unmask(uint32_t unmask);
  17. static xQueueHandle myQueue;
  18. static xQueueHandle uartRxQueue;
  19. int ctr;
  20. #if 1
  21. //Idle-loop for delay. Tests involuntary yielding
  22. static void cvTaskDelay(int dummy)
  23. {
  24. volatile int i;
  25. for (i = 0; i < (1 << 17); i++);
  26. }
  27. #else
  28. //Delay task execution using FreeRTOS methods. Tests voluntary yielding.
  29. #define cvTaskDelay(x) vTaskDelay(x)
  30. #endif
  31. #if 0
  32. static void dosegfault3(int i)
  33. {
  34. volatile char *p = (volatile char *)0;
  35. *p = i;
  36. }
  37. static void dosegfault2(int i)
  38. {
  39. if (i > 3) {
  40. dosegfault3(i);
  41. }
  42. }
  43. static void dosegfault(int i)
  44. {
  45. if (i < 5) {
  46. dosegfault(i + 1);
  47. }
  48. dosegfault2(i);
  49. }
  50. #endif
  51. static void queueSender(void *pvParameters)
  52. {
  53. int myCtr = xPortGetCoreID() * 100000;
  54. while (1) {
  55. printf("Core %d: Send to queue: %d\n", xPortGetCoreID(), myCtr);
  56. xQueueSend(myQueue, (void *)(&myCtr), portMAX_DELAY);
  57. printf("Send to queue done.\n");
  58. cvTaskDelay(100);
  59. myCtr++;
  60. }
  61. }
  62. static void queueReceiver(void *pvParameters)
  63. {
  64. int theCtr;
  65. while (1) {
  66. xQueueReceive(myQueue, &theCtr, portMAX_DELAY);
  67. printf("Core %d: Receive from queue: %d\n", xPortGetCoreID(), theCtr);
  68. }
  69. }
  70. static void tskone(void *pvParameters)
  71. {
  72. // char *p=(char *)0;
  73. while (1) {
  74. ctr++;
  75. // if (ctr>60) dosegfault(3);
  76. printf("Task1, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
  77. cvTaskDelay(500);
  78. }
  79. }
  80. static void tsktwo(void *pvParameters)
  81. {
  82. while (1) {
  83. ctr++;
  84. printf("Task2, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
  85. cvTaskDelay(500);
  86. }
  87. }
  88. static void tskthree(void *pvParameters)
  89. {
  90. while (1) {
  91. ctr++;
  92. printf("Task3, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
  93. cvTaskDelay(500);
  94. }
  95. }
  96. static void tskfour(void *pvParameters)
  97. {
  98. while (1) {
  99. ctr++;
  100. printf("Task4, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
  101. cvTaskDelay(500);
  102. }
  103. }
  104. static void tskfive(void *pvParameters)
  105. {
  106. while (1) {
  107. ctr++;
  108. printf("Task5, core %d, ctr=%d\n", xPortGetCoreID(), ctr);
  109. cvTaskDelay(500);
  110. }
  111. }
  112. static void tskyield(void *pvParameters)
  113. {
  114. while (1) {
  115. portYIELD();
  116. }
  117. }
  118. static void tskUartRecv(void *pvParameters)
  119. {
  120. char c;
  121. while (1) {
  122. xQueueReceive(uartRxQueue, &c, portMAX_DELAY);
  123. printf("Uart received %c!\n", c);
  124. }
  125. }
  126. static void uartIsrHdl(void *arg)
  127. {
  128. char c;
  129. BaseType_t xHigherPriorityTaskWoken;
  130. SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR);
  131. while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
  132. c = READ_PERI_REG(UART_FIFO_REG(0));
  133. xQueueSendFromISR(uartRxQueue, &c, &xHigherPriorityTaskWoken);
  134. printf("ISR: %c\n", c);
  135. }
  136. if (xHigherPriorityTaskWoken) {
  137. portYIELD_FROM_ISR();
  138. }
  139. }
  140. static void uartRxInit(xQueueHandle q)
  141. {
  142. uint32_t reg_val;
  143. PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
  144. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
  145. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
  146. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
  147. // reg_val = READ_PERI_REG(UART_CONF1(0));
  148. reg_val = (1 << UART_RXFIFO_FULL_THRHD_S);
  149. WRITE_PERI_REG(UART_CONF1_REG(0), reg_val);
  150. CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
  151. SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA);
  152. printf("Enabling int %d\n", ETS_UART0_INUM);
  153. REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM);
  154. REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM);
  155. xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL);
  156. xt_ints_on(1 << ETS_UART0_INUM);
  157. }
  158. // TODO: split this thing into separate orthogonal tests
  159. TEST_CASE("Bunch of FreeRTOS tests", "[freertos][ignore]")
  160. {
  161. char *tst;
  162. TaskHandle_t th[12];
  163. int i;
  164. printf("%s\n", __FUNCTION__);
  165. tst = pvPortMalloc(16);
  166. printf("Test malloc returns addr %p\n", tst);
  167. printf("Free heap: %u\n", xPortGetFreeHeapSize());
  168. myQueue = xQueueCreate(10, sizeof(int));
  169. uartRxQueue = xQueueCreate(256, sizeof(char));
  170. printf("Free heap: %u\n", xPortGetFreeHeapSize());
  171. printf("Creating tasks\n");
  172. xTaskCreatePinnedToCore(tskyield , "tskyield1" , 2048, NULL, 3, &th[0], 0);
  173. xTaskCreatePinnedToCore(tskyield , "tskyield2" , 2048, NULL, 3, &th[1], 1);
  174. xTaskCreatePinnedToCore(tskone , "tskone" , 2048, NULL, 3, &th[2], 0);
  175. xTaskCreatePinnedToCore(tsktwo , "tsktwo" , 2048, NULL, 3, &th[3], 1);
  176. xTaskCreatePinnedToCore(tskthree, "tskthree", 2048, NULL, 3, &th[4], 0);
  177. xTaskCreatePinnedToCore(tskfour , "tskfour" , 2048, NULL, 3, &th[5], tskNO_AFFINITY);
  178. xTaskCreatePinnedToCore(tskfive , "tskfive" , 2048, NULL, 3, &th[6], tskNO_AFFINITY);
  179. xTaskCreatePinnedToCore(queueSender , "qsend1" , 2048, NULL, 3, &th[7], 0);
  180. xTaskCreatePinnedToCore(queueSender , "qsend2" , 2048, NULL, 3, &th[8], 1);
  181. xTaskCreatePinnedToCore(queueReceiver , "qrecv1" , 2048, NULL, 3, &th[9], 1);
  182. xTaskCreatePinnedToCore(queueReceiver , "qrecv2" , 2048, NULL, 3, &th[10], 0);
  183. xTaskCreatePinnedToCore(tskUartRecv , "tskuart" , 2048, NULL, 4, &th[11], 1);
  184. printf("Free heap: %u\n", xPortGetFreeHeapSize());
  185. uartRxInit(uartRxQueue);
  186. // Let stuff run for 20s
  187. vTaskDelay(20000 / portTICK_PERIOD_MS);
  188. //Shut down all the tasks
  189. for (i = 0; i < 12; i++) {
  190. vTaskDelete(th[i]);
  191. }
  192. xt_ints_off(1 << ETS_UART0_INUM);
  193. }