test_ringbuf.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. Test for multicore FreeRTOS ringbuffer.
  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/ringbuf.h"
  12. #include "freertos/xtensa_api.h"
  13. #include "unity.h"
  14. #include "soc/uart_reg.h"
  15. #include "soc/dport_reg.h"
  16. #include "soc/io_mux_reg.h"
  17. #include <string.h>
  18. #include <stdio.h>
  19. void ets_isr_unmask(uint32_t unmask);
  20. static RingbufHandle_t rb;
  21. typedef enum {
  22. TST_MOSTLYFILLED,
  23. TST_MOSTLYEMPTY,
  24. TST_INTTOTASK,
  25. TST_TASKTOINT,
  26. } testtype_t;
  27. static volatile testtype_t testtype;
  28. static void task1(void *arg)
  29. {
  30. testtype_t oldtest;
  31. char buf[100];
  32. int i = 0;
  33. int x, r;
  34. while (1) {
  35. oldtest = testtype;
  36. if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) {
  37. for (x = 0; x < 10; x++) {
  38. sprintf(buf, "This is test %d item %d.", (int)testtype, i++);
  39. ets_printf("TSK w");
  40. xRingbufferPrintInfo(rb);
  41. r = xRingbufferSend(rb, buf, strlen(buf) + 1, 2000 / portTICK_PERIOD_MS);
  42. if (!r) {
  43. printf("Test %d: Timeout on send!\n", (int)testtype);
  44. }
  45. if (testtype == TST_MOSTLYEMPTY) {
  46. vTaskDelay(1000 / portTICK_PERIOD_MS);
  47. }
  48. }
  49. //Send NULL event to stop other side.
  50. r = xRingbufferSend(rb, NULL, 0, 10000 / portTICK_PERIOD_MS);
  51. }
  52. while (oldtest == testtype) {
  53. vTaskDelay(1000 / portTICK_PERIOD_MS);
  54. }
  55. }
  56. }
  57. static void task2(void *arg)
  58. {
  59. testtype_t oldtest;
  60. char *buf;
  61. size_t len;
  62. while (1) {
  63. oldtest = testtype;
  64. if (testtype == TST_MOSTLYFILLED || testtype == TST_MOSTLYEMPTY) {
  65. while (1) {
  66. ets_printf("TSK r");
  67. xRingbufferPrintInfo(rb);
  68. buf = xRingbufferReceive(rb, &len, 2000 / portTICK_PERIOD_MS);
  69. if (buf == NULL) {
  70. printf("Test %d: Timeout on recv!\n", (int)testtype);
  71. } else if (len == 0) {
  72. printf("End packet received.\n");
  73. vRingbufferReturnItem(rb, buf);
  74. break;
  75. } else {
  76. printf("Received: %s (%d bytes, %p)\n", buf, len, buf);
  77. vRingbufferReturnItem(rb, buf);
  78. }
  79. if (testtype == TST_MOSTLYFILLED) {
  80. vTaskDelay(1000 / portTICK_PERIOD_MS);
  81. }
  82. }
  83. }
  84. while (oldtest == testtype) {
  85. vTaskDelay(1000 / portTICK_PERIOD_MS);
  86. }
  87. }
  88. }
  89. static void uartIsrHdl(void *arg)
  90. {
  91. char c;
  92. char buf[50];
  93. char *item;
  94. int r;
  95. size_t len;
  96. BaseType_t xHigherPriorityTaskWoken;
  97. SET_PERI_REG_MASK(UART_INT_CLR_REG(0), UART_RXFIFO_FULL_INT_CLR);
  98. while (READ_PERI_REG(UART_STATUS_REG(0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
  99. c = READ_PERI_REG(UART_FIFO_REG(0));
  100. if (c == 'r') {
  101. ets_printf("ISR r");
  102. xRingbufferPrintInfo(rb);
  103. item = xRingbufferReceiveFromISR(rb, &len);
  104. if (item == NULL) {
  105. ets_printf("ISR recv fail!\n");
  106. } else if (len == 0) {
  107. ets_printf("ISR recv NULL!\n");
  108. vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
  109. } else {
  110. ets_printf("ISR recv '%s' (%d bytes, %p)\n", buf, len, buf);
  111. vRingbufferReturnItemFromISR(rb, item, &xHigherPriorityTaskWoken);
  112. }
  113. } else {
  114. sprintf(buf, "UART: %c", c);
  115. ets_printf("ISR w");
  116. xRingbufferPrintInfo(rb);
  117. r = xRingbufferSendFromISR(rb, buf, strlen(buf) + 1, &xHigherPriorityTaskWoken);
  118. if (!r) {
  119. ets_printf("ISR send fail\n");
  120. }
  121. }
  122. }
  123. if (xHigherPriorityTaskWoken) {
  124. portYIELD_FROM_ISR();
  125. }
  126. }
  127. static void uartRxInit()
  128. {
  129. uint32_t reg_val;
  130. PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
  131. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
  132. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
  133. // reg_val = READ_PERI_REG(UART_CONF1(0));
  134. reg_val = (1 << UART_RXFIFO_FULL_THRHD_S);
  135. WRITE_PERI_REG(UART_CONF1_REG(0), reg_val);
  136. CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_TXFIFO_EMPTY_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
  137. SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RXFIFO_FULL_INT_ENA);
  138. printf("Enabling int %d\n", ETS_UART0_INUM);
  139. REG_SET_FIELD(DPORT_PRO_UART_INTR_MAP_REG, DPORT_PRO_UART_INTR_MAP, ETS_UART0_INUM);
  140. REG_SET_FIELD(DPORT_PRO_UART1_INTR_MAP_REG, DPORT_PRO_UART1_INTR_MAP, ETS_UART0_INUM);
  141. xt_set_interrupt_handler(ETS_UART0_INUM, uartIsrHdl, NULL);
  142. xt_ints_on(1 << ETS_UART0_INUM);
  143. }
  144. static void testRingbuffer(int type)
  145. {
  146. TaskHandle_t th[2];
  147. int i;
  148. rb = xRingbufferCreate(32 * 3, type);
  149. testtype = TST_MOSTLYFILLED;
  150. xTaskCreatePinnedToCore(task1 , "tskone" , 2048, NULL, 3, &th[0], 0);
  151. xTaskCreatePinnedToCore(task2 , "tsktwo" , 2048, NULL, 3, &th[1], 0);
  152. uartRxInit();
  153. printf("Press 'r' to read an event in isr, any other key to write one.\n");
  154. printf("Test: mostlyfilled; putting 10 items in ringbuff ASAP, reading 1 a second\n");
  155. vTaskDelay(15000 / portTICK_PERIOD_MS);
  156. printf("Test: mostlyempty; putting 10 items in ringbuff @ 1/sec, reading as fast as possible\n");
  157. testtype = TST_MOSTLYEMPTY;
  158. vTaskDelay(15000 / portTICK_PERIOD_MS);
  159. //Shut down all the tasks
  160. for (i = 0; i < 2; i++) {
  161. vTaskDelete(th[i]);
  162. }
  163. xt_ints_off(1 << ETS_UART0_INUM);
  164. }
  165. // TODO: split this thing into separate orthogonal tests
  166. TEST_CASE("FreeRTOS ringbuffer test, no splitting items", "[freertos][ignore]")
  167. {
  168. testRingbuffer(0);
  169. }
  170. TEST_CASE("FreeRTOS ringbuffer test, w/ splitting items", "[freertos][ignore]")
  171. {
  172. testRingbuffer(1);
  173. }