messagequeue_tc.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-28 Sherman the first version
  9. * 2023-09-15 xqyjlj change stack size in cpu64
  10. * fix in smp
  11. */
  12. #include <rtthread.h>
  13. #include "utest.h"
  14. #define THREAD_STACKSIZE UTEST_THR_STACK_SIZE
  15. #define MSG_SIZE 4
  16. #define MAX_MSGS 5
  17. static struct rt_messagequeue static_mq;
  18. static rt_uint8_t mq_buf[RT_MQ_BUF_SIZE(MSG_SIZE, MAX_MSGS)];
  19. static struct rt_thread mq_send_thread;
  20. static struct rt_thread mq_recv_thread;
  21. static rt_uint8_t mq_send_stack[UTEST_THR_STACK_SIZE];
  22. static rt_uint8_t mq_recv_stack[UTEST_THR_STACK_SIZE];
  23. static struct rt_event finish_e;
  24. #define MQSEND_FINISH 0x01
  25. #define MQRECV_FINIHS 0x02
  26. #ifdef RT_USING_HEAP
  27. static rt_mq_t dynamic_mq;
  28. #endif /* RT_USING_HEAP */
  29. static void test_mq_init(void)
  30. {
  31. rt_err_t ret;
  32. ret = rt_mq_init(&static_mq,"testmq1", mq_buf, MSG_SIZE, sizeof(mq_buf), RT_IPC_FLAG_FIFO);
  33. uassert_true(ret == RT_EOK);
  34. }
  35. static void test_mq_create(void)
  36. {
  37. #ifdef RT_USING_HEAP
  38. dynamic_mq = rt_mq_create("testmq2", MSG_SIZE, MAX_MSGS, RT_IPC_FLAG_FIFO);
  39. uassert_true(dynamic_mq != RT_NULL);
  40. #endif /* RT_USING_HEAP */
  41. }
  42. static void mq_send_case(rt_mq_t testmq)
  43. {
  44. rt_uint32_t send_buf[MAX_MSGS+1] = {0};
  45. rt_err_t ret = RT_EOK;
  46. for (int var = 0; var < MAX_MSGS; ++var)
  47. {
  48. send_buf[var] = var + 1;
  49. ret = rt_mq_send_wait(testmq, &send_buf[var], sizeof(send_buf[0]), RT_WAITING_FOREVER);
  50. uassert_true(ret == RT_EOK);
  51. }
  52. send_buf[MAX_MSGS] = MAX_MSGS + 1;
  53. ret = rt_mq_send(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0]));
  54. uassert_true(ret == -RT_EFULL);
  55. ret = rt_mq_send_wait(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0]), RT_WAITING_FOREVER);
  56. uassert_true(ret == RT_EOK);
  57. while (testmq->entry != 0)
  58. {
  59. rt_thread_delay(100);
  60. }
  61. ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0]));
  62. uassert_true(ret == RT_EOK);
  63. ret = rt_mq_send(testmq, &send_buf[2], sizeof(send_buf[0]));
  64. uassert_true(ret == RT_EOK);
  65. ret = rt_mq_urgent(testmq, &send_buf[0], sizeof(send_buf[0]));
  66. uassert_true(ret == RT_EOK);
  67. while (testmq->entry != 0)
  68. {
  69. rt_thread_delay(100);
  70. }
  71. #ifdef RT_USING_MESSAGEQUEUE_PRIORITY
  72. ret = rt_mq_send_wait_prio(testmq, &send_buf[3], sizeof(send_buf[0]), 3, 0, RT_UNINTERRUPTIBLE);
  73. uassert_true(ret == RT_EOK);
  74. ret = rt_mq_send_wait_prio(testmq, &send_buf[0], sizeof(send_buf[0]), 0, 0, RT_UNINTERRUPTIBLE);
  75. uassert_true(ret == RT_EOK);
  76. ret = rt_mq_send_wait_prio(testmq, &send_buf[2], sizeof(send_buf[0]), 1, 0, RT_UNINTERRUPTIBLE);
  77. uassert_true(ret == RT_EOK);
  78. ret = rt_mq_send_wait_prio(testmq, &send_buf[4], sizeof(send_buf[0]), 4, 0, RT_UNINTERRUPTIBLE);
  79. uassert_true(ret == RT_EOK);
  80. ret = rt_mq_send_wait_prio(testmq, &send_buf[1], sizeof(send_buf[0]), 1, 0, RT_UNINTERRUPTIBLE);
  81. uassert_true(ret == RT_EOK);
  82. while (testmq->entry != 0)
  83. {
  84. rt_thread_delay(100);
  85. }
  86. #endif
  87. ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0]));
  88. uassert_true(ret == RT_EOK);
  89. ret = rt_mq_control(testmq, RT_IPC_CMD_RESET, RT_NULL);
  90. uassert_true(ret == RT_EOK);
  91. uassert_true(testmq->entry == 0);
  92. }
  93. static void mq_send_entry(void *param)
  94. {
  95. mq_send_case(&static_mq);
  96. #ifdef RT_USING_HEAP
  97. if(dynamic_mq != RT_NULL)
  98. {
  99. mq_send_case(dynamic_mq);
  100. }
  101. #endif /* RT_USING_HEAP */
  102. rt_event_send(&finish_e, MQSEND_FINISH);
  103. }
  104. static void mq_recv_case(rt_mq_t testmq)
  105. {
  106. rt_uint32_t recv_buf[MAX_MSGS+1] = {0};
  107. rt_ssize_t ret = RT_EOK;
  108. for (int var = 0; var < MAX_MSGS + 1; ++var)
  109. {
  110. ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER);
  111. uassert_true(ret >= 0);
  112. uassert_true(recv_buf[var] == (var + 1));
  113. }
  114. for (int var = 0; var < 3; ++var)
  115. {
  116. ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER);
  117. uassert_true(ret >= 0);
  118. uassert_true(recv_buf[var] == (var + 1));
  119. }
  120. #ifdef RT_USING_MESSAGEQUEUE_PRIORITY
  121. rt_int32_t msg_prio;
  122. while (testmq->entry == MAX_MSGS)
  123. {
  124. rt_thread_delay(100);
  125. }
  126. for (int var = 0; var < MAX_MSGS; ++var)
  127. {
  128. ret = rt_mq_recv_prio(testmq, &recv_buf[var], sizeof(recv_buf[0]), &msg_prio, RT_WAITING_FOREVER, RT_UNINTERRUPTIBLE);
  129. rt_kprintf("msg_prio = %d\r\n", msg_prio);
  130. uassert_true(ret >= 0);
  131. uassert_true(recv_buf[var] == (MAX_MSGS - var));
  132. }
  133. #endif
  134. }
  135. static void mq_recv_entry(void *param)
  136. {
  137. mq_recv_case(&static_mq);
  138. #ifdef RT_USING_HEAP
  139. if(dynamic_mq != RT_NULL)
  140. {
  141. mq_recv_case(dynamic_mq);
  142. }
  143. #endif /* RT_USING_HEAP */
  144. rt_event_send(&finish_e, MQRECV_FINIHS);
  145. }
  146. static void test_mq_testcase(void)
  147. {
  148. rt_thread_startup(&mq_send_thread);
  149. rt_thread_startup(&mq_recv_thread);
  150. rt_event_recv(&finish_e, MQSEND_FINISH | MQRECV_FINIHS, RT_EVENT_FLAG_AND, RT_WAITING_FOREVER, RT_NULL);
  151. }
  152. static void test_mq_detach(void)
  153. {
  154. rt_err_t ret = rt_mq_detach(&static_mq);
  155. uassert_true(ret == RT_EOK);
  156. }
  157. static void test_mq_delete(void)
  158. {
  159. #ifdef RT_USING_HEAP
  160. rt_err_t ret = rt_mq_delete(dynamic_mq);
  161. uassert_true(ret == RT_EOK);
  162. #endif /* RT_USING_HEAP */
  163. }
  164. static rt_err_t utest_tc_init(void)
  165. {
  166. rt_err_t ret ;
  167. ret = rt_thread_init(&mq_send_thread, "mq_send", mq_send_entry, RT_NULL, mq_send_stack, sizeof(mq_send_stack), 22, 20);
  168. if(ret != RT_EOK)
  169. return -RT_ERROR;
  170. ret = rt_thread_init(&mq_recv_thread, "mq_recv", mq_recv_entry, RT_NULL, mq_recv_stack, sizeof(mq_recv_stack), 23, 20);
  171. if(ret != RT_EOK)
  172. return -RT_ERROR;
  173. #ifdef RT_USING_SMP
  174. rt_thread_control(&mq_send_thread, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  175. rt_thread_control(&mq_recv_thread, RT_THREAD_CTRL_BIND_CPU, (void *)0);
  176. #endif
  177. ret = rt_event_init(&finish_e, "finish", RT_IPC_FLAG_FIFO);
  178. if(ret != RT_EOK)
  179. return -RT_ERROR;
  180. return RT_EOK;
  181. }
  182. static rt_err_t utest_tc_cleanup(void)
  183. {
  184. return RT_EOK;
  185. }
  186. static void testcase(void)
  187. {
  188. UTEST_UNIT_RUN(test_mq_init);
  189. UTEST_UNIT_RUN(test_mq_create);
  190. UTEST_UNIT_RUN(test_mq_testcase);
  191. UTEST_UNIT_RUN(test_mq_detach);
  192. UTEST_UNIT_RUN(test_mq_delete);
  193. }
  194. UTEST_TC_EXPORT(testcase, "testcases.kernel.messagequeue_tc", utest_tc_init, utest_tc_cleanup, 1000);