rbb_test.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. * 2018-08-31 armink the first version
  9. */
  10. #include <string.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <stdlib.h>
  14. static rt_bool_t put_finish = RT_FALSE;
  15. static void put_thread(void *param)
  16. {
  17. rt_rbb_t rbb = (rt_rbb_t)param;
  18. rt_rbb_blk_t block;
  19. rt_uint8_t put_count = 0;
  20. put_finish = RT_FALSE;
  21. while (put_count < 255)
  22. {
  23. if (put_count == 10)
  24. {
  25. put_count = 10;
  26. }
  27. block = rt_rbb_blk_alloc(rbb, rand() % 10 + 1);
  28. if (block)
  29. {
  30. block->buf[0] = put_count++;
  31. rt_rbb_blk_put(block);
  32. }
  33. rt_thread_mdelay(rand() % 10);
  34. }
  35. rt_kprintf("Put block data finish.\n");
  36. put_finish = RT_TRUE;
  37. }
  38. static void get_thread(void *param)
  39. {
  40. rt_rbb_t rbb = (rt_rbb_t)param;
  41. rt_rbb_blk_t block;
  42. rt_uint8_t get_count = 0;
  43. while (get_count < 255)
  44. {
  45. if (get_count == 10)
  46. {
  47. get_count = 10;
  48. }
  49. block = rt_rbb_blk_get(rbb);
  50. if (block)
  51. {
  52. if (block->buf[0] != get_count++)
  53. {
  54. rt_kprintf("Error: get data (times %d) has an error!\n", get_count);
  55. }
  56. rt_rbb_blk_free(rbb, block);
  57. }
  58. else if (put_finish)
  59. {
  60. break;
  61. }
  62. rt_thread_mdelay(rand() % 10);
  63. }
  64. rt_kprintf("Get block data finish.\n");
  65. rt_kprintf("\n====================== rbb dynamic test finish =====================\n");
  66. }
  67. void rbb_test(void)
  68. {
  69. rt_rbb_t rbb;
  70. rt_rbb_blk_t blk1, blk2, blk3, blk4, blk5, blk6, _blk1, _blk2;
  71. rt_size_t i, j, k, req_size, size;
  72. struct rt_rbb_blk_queue blk_queue1;
  73. rt_thread_t thread;
  74. /* create ring block buffer */
  75. rt_kprintf("\n====================== rbb create test =====================\n");
  76. rbb = rt_rbb_create(52, 6);
  77. if (rbb)
  78. {
  79. rt_kprintf("6 blocks in 52 bytes ring block buffer object create success.\n");
  80. }
  81. else
  82. {
  83. rt_kprintf("Test error: 6 blocks in 52 bytes ring block buffer object create failed.\n");
  84. }
  85. /* allocate block */
  86. rt_kprintf("\n====================== rbb alloc test =====================\n");
  87. blk1 = rt_rbb_blk_alloc(rbb, 2);
  88. if (blk1 && blk1->size == 2)
  89. {
  90. memset(blk1->buf, 1, blk1->size);
  91. rt_kprintf("Block1 (2 bytes) allocate success.\n");
  92. }
  93. else
  94. {
  95. rt_kprintf("Test error: block1 (2 bytes) allocate failed.\n");
  96. goto __exit;
  97. }
  98. blk2 = rt_rbb_blk_alloc(rbb, 4);
  99. if (blk2 && blk2->size == 4)
  100. {
  101. memset(blk2->buf, 2, blk2->size);
  102. rt_kprintf("Block2 (4 bytes) allocate success.\n");
  103. }
  104. else
  105. {
  106. rt_kprintf("Test error: block2 (4 bytes) allocate failed.\n");
  107. goto __exit;
  108. }
  109. blk3 = rt_rbb_blk_alloc(rbb, 8);
  110. if (blk3 && blk3->size == 8)
  111. {
  112. memset(blk3->buf, 3, blk3->size);
  113. rt_kprintf("Block3 (8 bytes) allocate success.\n");
  114. }
  115. else
  116. {
  117. rt_kprintf("Test error: block3 (8 bytes) allocate failed.\n");
  118. goto __exit;
  119. }
  120. blk4 = rt_rbb_blk_alloc(rbb, 16);
  121. if (blk4 && blk4->size == 16)
  122. {
  123. memset(blk4->buf, 4, blk4->size);
  124. rt_kprintf("Block4 (16 bytes) allocate success.\n");
  125. }
  126. else
  127. {
  128. rt_kprintf("Test error: block4 (16 bytes) allocate failed.\n");
  129. goto __exit;
  130. }
  131. blk5 = rt_rbb_blk_alloc(rbb, 32);
  132. if (blk5 && blk5->size == 32)
  133. {
  134. memset(blk5->buf, 5, blk5->size);
  135. rt_kprintf("Block5 (32 bytes) allocate success.\n");
  136. }
  137. else
  138. {
  139. rt_kprintf("Block5 (32 bytes) allocate failed.\n");
  140. }
  141. blk5 = rt_rbb_blk_alloc(rbb, 18);
  142. if (blk5 && blk5->size == 18)
  143. {
  144. memset(blk5->buf, 5, blk5->size);
  145. rt_kprintf("Block5 (18 bytes) allocate success.\n");
  146. }
  147. else
  148. {
  149. rt_kprintf("Test error: block5 (18 bytes) allocate failed.\n");
  150. goto __exit;
  151. }
  152. rt_kprintf("Ring block buffer current status:\n");
  153. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  154. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  155. rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  156. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  157. rt_kprintf("| blcok1 | block2 | block3 | block4 | block5 | empty |\n");
  158. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  159. rt_kprintf("| inited | inited | inited | inited | inited | |\n");
  160. /* put block */
  161. rt_kprintf("\n====================== rbb put test =====================\n");
  162. rt_rbb_blk_put(blk1);
  163. rt_rbb_blk_put(blk2);
  164. rt_rbb_blk_put(blk3);
  165. rt_rbb_blk_put(blk4);
  166. rt_rbb_blk_put(blk5);
  167. rt_kprintf("Block1 to block5 put success.\n");
  168. rt_kprintf("Ring block buffer current status:\n");
  169. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  170. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  171. rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  172. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  173. rt_kprintf("| blcok1 | block2 | block3 | block4 | block5 | empty |\n");
  174. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  175. rt_kprintf("| put | put | put | put | put | |\n");
  176. /* get block */
  177. rt_kprintf("\n====================== rbb get test =====================\n");
  178. _blk1 = rt_rbb_blk_get(rbb);
  179. _blk2 = rt_rbb_blk_get(rbb);
  180. for (i = 0; i < _blk1->size; i++)
  181. {
  182. if (_blk1->buf[i] != 1) break;
  183. }
  184. for (j = 0; j < _blk2->size; j++)
  185. {
  186. if (_blk2->buf[j] != 2) break;
  187. }
  188. if (blk1 == _blk1 && blk2 == _blk2 && i == _blk1->size && j == _blk2->size)
  189. {
  190. rt_kprintf("Block1 and block2 get success.\n");
  191. }
  192. else
  193. {
  194. rt_kprintf("Test error: block1 and block2 get failed.\n");
  195. goto __exit;
  196. }
  197. rt_kprintf("Ring block buffer current status:\n");
  198. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  199. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  200. rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  201. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  202. rt_kprintf("| blcok1 | block2 | block3 | block4 | block5 | empty |\n");
  203. rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
  204. rt_kprintf("| get | get | put | put | put | |\n");
  205. /* free block */
  206. rt_kprintf("\n====================== rbb free test =====================\n");
  207. rt_rbb_blk_free(rbb, blk2);
  208. rt_kprintf("Block2 free success.\n");
  209. rt_rbb_blk_free(rbb, blk1);
  210. rt_kprintf("Block1 free success.\n");
  211. rt_kprintf("Ring block buffer current status:\n");
  212. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  213. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  214. rt_kprintf("|<------- 6 ------>|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  215. rt_kprintf("+------------------+--------------+---------------------+------------------+-------------+\n");
  216. rt_kprintf("| empty2 | block3 | block4 | block5 | empty1 |\n");
  217. rt_kprintf("+------------------+--------------+---------------------+------------------+-------------+\n");
  218. rt_kprintf("| | put | put | put | |\n");
  219. blk6 = rt_rbb_blk_alloc(rbb, 5);
  220. if (blk6)
  221. {
  222. rt_kprintf("Block6 (5 bytes) allocate success.\n");
  223. }
  224. else
  225. {
  226. rt_kprintf("Test error: block6 (5 bytes) allocate failed.\n");
  227. goto __exit;
  228. }
  229. rt_rbb_blk_put(blk6);
  230. rt_kprintf("Block6 put success.\n");
  231. rt_kprintf("Ring block buffer current status:\n");
  232. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  233. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  234. rt_kprintf("|<--- 5 ---->|< 1 >|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  235. rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
  236. rt_kprintf("| block6 |empty| block3 | block4 | block5 | fragment |\n");
  237. rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
  238. rt_kprintf("| put | | put | put | put | |\n");
  239. /* get block queue */
  240. rt_kprintf("\n====================== rbb block queue get test =====================\n");
  241. req_size = rt_rbb_next_blk_queue_len(rbb) + 5;
  242. size = rt_rbb_blk_queue_get(rbb, req_size, &blk_queue1);
  243. i = j = k = 0;
  244. for (; i < blk3->size; i++)
  245. {
  246. if (rt_rbb_blk_queue_buf(&blk_queue1)[i] != 3) break;
  247. }
  248. for (; j < blk4->size; j++)
  249. {
  250. if (rt_rbb_blk_queue_buf(&blk_queue1)[i + j] != 4) break;
  251. }
  252. for (; k < blk5->size; k++)
  253. {
  254. if (rt_rbb_blk_queue_buf(&blk_queue1)[i + j + k] != 5) break;
  255. }
  256. if (size && size == 42 && rt_rbb_blk_queue_len(&blk_queue1) == 42 && k == blk5->size)
  257. {
  258. rt_kprintf("Block queue (request %d bytes, actual %d) get success.\n", req_size, size);
  259. }
  260. else
  261. {
  262. rt_kprintf("Test error: Block queue (request %d bytes, actual %d) get failed.\n", req_size, size);
  263. goto __exit;
  264. }
  265. rt_kprintf("Ring block buffer current status:\n");
  266. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  267. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  268. rt_kprintf("| | |<----- block queue1 (42 bytes continuous buffer) ----->| |\n");
  269. rt_kprintf("|<--- 5 ---->|< 1 >|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
  270. rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
  271. rt_kprintf("| block6 |empty| block3 | block4 | block5 | fragment |\n");
  272. rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
  273. rt_kprintf("| put | | get | get | get | |\n");
  274. /* free block queue */
  275. rt_kprintf("\n====================== rbb block queue free test =====================\n");
  276. rt_rbb_blk_queue_free(rbb, &blk_queue1);
  277. rt_kprintf("Block queue1 free success.\n");
  278. rt_kprintf("Ring block buffer current status:\n");
  279. rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
  280. rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
  281. rt_kprintf("|<--- 5 ---->|<--------------------------------- 47 ------------------------------------>|\n");
  282. rt_kprintf("+------------+---------------------------------------------------------------------------+\n");
  283. rt_kprintf("| block6 | empty |\n");
  284. rt_kprintf("+------------+---------------------------------------------------------------------------+\n");
  285. rt_kprintf("| put | |\n");
  286. rt_rbb_blk_free(rbb, blk6);
  287. rt_kprintf("\n====================== rbb static test SUCCESS =====================\n");
  288. rt_kprintf("\n====================== rbb dynamic test =====================\n");
  289. thread = rt_thread_create("rbb_put", put_thread, rbb, 1024, 10, 25);
  290. if (thread)
  291. {
  292. rt_thread_startup(thread);
  293. }
  294. thread = rt_thread_create("rbb_get", get_thread, rbb, 1024, 10, 25);
  295. if (thread)
  296. {
  297. rt_thread_startup(thread);
  298. }
  299. __exit :
  300. rt_rbb_destroy(rbb);
  301. }
  302. MSH_CMD_EXPORT(rbb_test, run ring block buffer testcase)