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