xref: /nrf52832-nimble/rt-thread/examples/test/rbb_test.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * File      : rbb_test.c
3  * This file is part of RT-Thread RTOS
4  * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License along
17  *  with this program; if not, write to the Free Software Foundation, Inc.,
18  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Change Logs:
21  * Date           Author       Notes
22  * 2018-08-31     armink       the first version
23  */
24 
25 #include <string.h>
26 #include <rtthread.h>
27 #include <rtdevice.h>
28 #include <stdlib.h>
29 
30 static rt_bool_t put_finish = RT_FALSE;
31 
put_thread(void * param)32 static void put_thread(void *param)
33 {
34     rt_rbb_t rbb = (rt_rbb_t)param;
35     rt_rbb_blk_t block;
36     rt_uint8_t put_count = 0;
37 
38     put_finish = RT_FALSE;
39 
40     while (put_count < 255)
41     {
42         if (put_count == 10)
43         {
44             put_count = 10;
45         }
46         block = rt_rbb_blk_alloc(rbb, rand() % 10 + 1);
47         if (block)
48         {
49             block->buf[0] = put_count++;
50             rt_rbb_blk_put(block);
51         }
52         rt_thread_mdelay(rand() % 10);
53     }
54     rt_kprintf("Put block data finish.\n");
55 
56     put_finish = RT_TRUE;
57 }
58 
get_thread(void * param)59 static void get_thread(void *param)
60 {
61     rt_rbb_t rbb = (rt_rbb_t)param;
62     rt_rbb_blk_t block;
63     rt_uint8_t get_count = 0;
64 
65     while (get_count < 255)
66     {
67         if (get_count == 10)
68         {
69             get_count = 10;
70         }
71         block = rt_rbb_blk_get(rbb);
72         if (block)
73         {
74             if (block->buf[0] != get_count++)
75             {
76                 rt_kprintf("Error: get data (times %d) has an error!\n", get_count);
77             }
78             rt_rbb_blk_free(rbb, block);
79         }
80         else if (put_finish)
81         {
82             break;
83         }
84         rt_thread_mdelay(rand() % 10);
85     }
86     rt_kprintf("Get block data finish.\n");
87     rt_kprintf("\n====================== rbb dynamic test finish =====================\n");
88 }
89 
rbb_test(void)90 void rbb_test(void)
91 {
92     rt_rbb_t rbb;
93     rt_rbb_blk_t blk1, blk2, blk3, blk4, blk5, blk6, _blk1, _blk2;
94     rt_size_t i, j, k, req_size, size;
95     struct rt_rbb_blk_queue blk_queue1;
96     rt_thread_t thread;
97 
98     /* create ring block buffer */
99     rt_kprintf("\n====================== rbb create test =====================\n");
100     rbb = rt_rbb_create(52, 6);
101     if (rbb)
102     {
103         rt_kprintf("6 blocks in 52 bytes ring block buffer object create success.\n");
104     }
105     else
106     {
107         rt_kprintf("Test error: 6 blocks in 52 bytes ring block buffer object create failed.\n");
108     }
109     /* allocate block */
110     rt_kprintf("\n====================== rbb alloc test =====================\n");
111     blk1 = rt_rbb_blk_alloc(rbb, 2);
112     if (blk1 && blk1->size == 2)
113     {
114         memset(blk1->buf, 1, blk1->size);
115         rt_kprintf("Block1 (2 bytes) allocate success.\n");
116     }
117     else
118     {
119         rt_kprintf("Test error: block1 (2 bytes) allocate failed.\n");
120         goto __exit;
121     }
122     blk2 = rt_rbb_blk_alloc(rbb, 4);
123     if (blk2 && blk2->size == 4)
124     {
125         memset(blk2->buf, 2, blk2->size);
126         rt_kprintf("Block2 (4 bytes) allocate success.\n");
127     }
128     else
129     {
130         rt_kprintf("Test error: block2 (4 bytes) allocate failed.\n");
131         goto __exit;
132     }
133     blk3 = rt_rbb_blk_alloc(rbb, 8);
134     if (blk3 && blk3->size == 8)
135     {
136         memset(blk3->buf, 3, blk3->size);
137         rt_kprintf("Block3 (8 bytes) allocate success.\n");
138     }
139     else
140     {
141         rt_kprintf("Test error: block3 (8 bytes) allocate failed.\n");
142         goto __exit;
143     }
144     blk4 = rt_rbb_blk_alloc(rbb, 16);
145     if (blk4 && blk4->size == 16)
146     {
147         memset(blk4->buf, 4, blk4->size);
148         rt_kprintf("Block4 (16 bytes) allocate success.\n");
149     }
150     else
151     {
152         rt_kprintf("Test error: block4 (16 bytes) allocate failed.\n");
153         goto __exit;
154     }
155     blk5 = rt_rbb_blk_alloc(rbb, 32);
156     if (blk5 && blk5->size == 32)
157     {
158         memset(blk5->buf, 5, blk5->size);
159         rt_kprintf("Block5 (32 bytes) allocate success.\n");
160     }
161     else
162     {
163         rt_kprintf("Block5 (32 bytes) allocate failed.\n");
164     }
165     blk5 = rt_rbb_blk_alloc(rbb, 18);
166     if (blk5 && blk5->size == 18)
167     {
168         memset(blk5->buf, 5, blk5->size);
169         rt_kprintf("Block5 (18 bytes) allocate success.\n");
170     }
171     else
172     {
173         rt_kprintf("Test error: block5 (18 bytes) allocate failed.\n");
174         goto __exit;
175     }
176     rt_kprintf("Ring block buffer current status:\n");
177     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
178     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
179     rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
180     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
181     rt_kprintf("| blcok1 | block2  |    block3    |       block4        |       block5     |    empty    |\n");
182     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
183     rt_kprintf("| inited | inited  |    inited    |       inited        |       inited     |             |\n");
184 
185     /* put block */
186     rt_kprintf("\n====================== rbb put test =====================\n");
187     rt_rbb_blk_put(blk1);
188     rt_rbb_blk_put(blk2);
189     rt_rbb_blk_put(blk3);
190     rt_rbb_blk_put(blk4);
191     rt_rbb_blk_put(blk5);
192     rt_kprintf("Block1 to block5 put success.\n");
193     rt_kprintf("Ring block buffer current status:\n");
194     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
195     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
196     rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
197     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
198     rt_kprintf("| blcok1 | block2  |    block3    |       block4        |       block5     |    empty    |\n");
199     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
200     rt_kprintf("|  put   |  put    |     put      |        put          |        put       |             |\n");
201 
202     /* get block */
203     rt_kprintf("\n====================== rbb get test =====================\n");
204     _blk1 = rt_rbb_blk_get(rbb);
205     _blk2 = rt_rbb_blk_get(rbb);
206     for (i = 0; i < _blk1->size; i++)
207     {
208         if (_blk1->buf[i] != 1) break;
209     }
210     for (j = 0; j < _blk2->size; j++)
211     {
212         if (_blk2->buf[j] != 2) break;
213     }
214     if (blk1 == _blk1 && blk2 == _blk2 && i == _blk1->size && j == _blk2->size)
215     {
216         rt_kprintf("Block1 and block2 get success.\n");
217     }
218     else
219     {
220         rt_kprintf("Test error: block1 and block2 get failed.\n");
221         goto __exit;
222     }
223     rt_kprintf("Ring block buffer current status:\n");
224     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
225     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
226     rt_kprintf("|<- 2 -->|<-- 4 -->|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
227     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
228     rt_kprintf("| blcok1 | block2  |    block3    |       block4        |       block5     |    empty    |\n");
229     rt_kprintf("+--------+---------+--------------+---------------------+------------------+-------------+\n");
230     rt_kprintf("|  get   |   get   |     put      |        put          |        put       |             |\n");
231 
232     /* free block */
233     rt_kprintf("\n====================== rbb free test =====================\n");
234     rt_rbb_blk_free(rbb, blk2);
235     rt_kprintf("Block2 free success.\n");
236     rt_rbb_blk_free(rbb, blk1);
237     rt_kprintf("Block1 free success.\n");
238     rt_kprintf("Ring block buffer current status:\n");
239     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
240     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
241     rt_kprintf("|<------- 6 ------>|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
242     rt_kprintf("+------------------+--------------+---------------------+------------------+-------------+\n");
243     rt_kprintf("|      empty2      |    block3    |       block4        |       block5     |    empty1   |\n");
244     rt_kprintf("+------------------+--------------+---------------------+------------------+-------------+\n");
245     rt_kprintf("|                  |     put      |        put          |        put       |             |\n");
246 
247     blk6 = rt_rbb_blk_alloc(rbb, 5);
248     if (blk6)
249     {
250         rt_kprintf("Block6 (5 bytes) allocate success.\n");
251     }
252     else
253     {
254         rt_kprintf("Test error: block6 (5 bytes) allocate failed.\n");
255         goto __exit;
256     }
257 
258     rt_rbb_blk_put(blk6);
259     rt_kprintf("Block6 put success.\n");
260     rt_kprintf("Ring block buffer current status:\n");
261     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
262     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
263     rt_kprintf("|<--- 5 ---->|< 1 >|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
264     rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
265     rt_kprintf("|   block6   |empty|    block3    |       block4        |       block5     |   fragment  |\n");
266     rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
267     rt_kprintf("|     put    |     |     put      |        put          |        put       |             |\n");
268 
269     /* get block queue */
270     rt_kprintf("\n====================== rbb block queue get test =====================\n");
271     req_size = rt_rbb_next_blk_queue_len(rbb) + 5;
272     size = rt_rbb_blk_queue_get(rbb, req_size, &blk_queue1);
273     i = j = k = 0;
274     for (; i < blk3->size; i++)
275     {
276         if (rt_rbb_blk_queue_buf(&blk_queue1)[i] != 3) break;
277     }
278     for (; j < blk4->size; j++)
279     {
280         if (rt_rbb_blk_queue_buf(&blk_queue1)[i + j] != 4) break;
281     }
282     for (; k < blk5->size; k++)
283     {
284         if (rt_rbb_blk_queue_buf(&blk_queue1)[i + j + k] != 5) break;
285     }
286     if (size && size == 42 && rt_rbb_blk_queue_len(&blk_queue1) == 42 && k == blk5->size)
287     {
288         rt_kprintf("Block queue (request %d bytes, actual %d) get success.\n", req_size, size);
289     }
290     else
291     {
292         rt_kprintf("Test error: Block queue (request %d bytes, actual %d) get failed.\n", req_size, size);
293         goto __exit;
294     }
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("|            |     |<----- block queue1 (42 bytes continuous buffer) ----->|             |\n");
299     rt_kprintf("|<--- 5 ---->|< 1 >|<---- 8 ----->|<------- 16 -------->|<------ 18 ------>|<---- 4 ---->|\n");
300     rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
301     rt_kprintf("|   block6   |empty|    block3    |       block4        |       block5     |   fragment  |\n");
302     rt_kprintf("+------------+-----+--------------+---------------------+------------------+-------------+\n");
303     rt_kprintf("|     put    |     |     get      |        get          |        get       |             |\n");
304 
305     /* free block queue */
306     rt_kprintf("\n====================== rbb block queue free test =====================\n");
307     rt_rbb_blk_queue_free(rbb, &blk_queue1);
308     rt_kprintf("Block queue1 free success.\n");
309     rt_kprintf("Ring block buffer current status:\n");
310     rt_kprintf("next block queue length: %d\n", rt_rbb_next_blk_queue_len(rbb));
311     rt_kprintf("block list length: %d\n", rt_slist_len(&rbb->blk_list));
312     rt_kprintf("|<--- 5 ---->|<--------------------------------- 47 ------------------------------------>|\n");
313     rt_kprintf("+------------+---------------------------------------------------------------------------+\n");
314     rt_kprintf("|   block6   |                                 empty                                     |\n");
315     rt_kprintf("+------------+---------------------------------------------------------------------------+\n");
316     rt_kprintf("|     put    |                                                                           |\n");
317     rt_rbb_blk_free(rbb, blk6);
318 
319     rt_kprintf("\n====================== rbb static test SUCCESS =====================\n");
320 
321     rt_kprintf("\n====================== rbb dynamic test =====================\n");
322 
323     thread = rt_thread_create("rbb_put", put_thread, rbb, 1024, 10, 25);
324     if (thread)
325     {
326         rt_thread_startup(thread);
327     }
328 
329     thread = rt_thread_create("rbb_get", get_thread, rbb, 1024, 10, 25);
330     if (thread)
331     {
332         rt_thread_startup(thread);
333     }
334 
335 __exit :
336 
337     rt_rbb_destroy(rbb);
338 }
339 
340 MSH_CMD_EXPORT(rbb_test, run ring block buffer testcase)
341 
342