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 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 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 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