messagequeue_tc.c 6.1 KB

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