File indexing completed on 2025-05-11 08:24:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039
0040 #include <sys/stat.h>
0041 #include <errno.h>
0042 #include <fcntl.h>
0043 #include <stdarg.h>
0044
0045 #include <rtems.h>
0046 #include <rtems/bspIo.h>
0047 #include <rtems/bdbuf.h>
0048 #include <rtems/blkdev.h>
0049
0050 #include <tmacros.h>
0051
0052 const char rtems_test_name[] = "BLOCK 5";
0053
0054
0055 static rtems_task Init(rtems_task_argument argument);
0056
0057 #define ASSERT_SC(sc) rtems_test_assert((sc) == RTEMS_SUCCESSFUL)
0058
0059 #define PRIORITY_INIT 1
0060
0061 #define PRIORITY_HIGH 2
0062
0063 #define PRIORITY_LOW_ALT 3
0064
0065 #define PRIORITY_SWAPOUT 4
0066
0067 #define PRIORITY_LOW 5
0068
0069 #define PRIORITY_RESUME 6
0070
0071 #define BLOCK_SIZE_A 1
0072
0073 #define BLOCK_COUNT_A 2
0074
0075 #define BLOCK_SIZE_B 2
0076
0077 #define BLOCK_COUNT_B 1
0078
0079
0080 static unsigned output_level = 0;
0081
0082 static rtems_disk_device *dd_a;
0083
0084 static rtems_disk_device *dd_b;
0085
0086 static rtems_id task_id_init;
0087
0088 static rtems_id task_id_low;
0089
0090 static rtems_id task_id_high;
0091
0092 static rtems_id task_id_resume;
0093
0094 static volatile bool finish_low;
0095
0096 static volatile bool finish_high;
0097
0098 static volatile enum resume_style {
0099 RESUME_IMMEDIATE,
0100 RESUME_FINISH
0101 } resume;
0102
0103 static volatile enum trig_style {
0104 SUSP = 0,
0105 CONT
0106 } trig;
0107
0108 static volatile enum get_type {
0109 GET = 0,
0110 READ
0111 } trig_get, low_get, high_get;
0112
0113 static volatile enum blk_kind {
0114 BLK_A0 = 0,
0115 BLK_A1,
0116 BLK_B0
0117 } trig_blk, low_blk, high_blk;
0118
0119 static volatile enum rel_type {
0120 REL = 0,
0121 REL_MOD,
0122 SYNC
0123 } trig_rel, low_rel, high_rel;
0124
0125 static const char trig_style_desc [] = {
0126 'S',
0127 'C'
0128 };
0129
0130 static const char get_type_desc [] = {
0131 'G',
0132 'R'
0133 };
0134
0135 static const char *blk_kind_desc [] = {
0136 "A0",
0137 "A1",
0138 "B0"
0139 };
0140
0141 static const char rel_type_desc [] = {
0142 'R',
0143 'M',
0144 'S'
0145 };
0146
0147 static void print(unsigned level, const char *fmt, ...)
0148 {
0149 if (level <= output_level) {
0150 va_list ap;
0151
0152 va_start(ap, fmt);
0153 vprintk(fmt, ap);
0154 va_end(ap);
0155 }
0156 }
0157
0158 static void set_task_prio(rtems_id task, rtems_task_priority prio)
0159 {
0160 rtems_status_code sc = RTEMS_SUCCESSFUL;
0161 rtems_task_priority cur = 0;
0162
0163 sc = rtems_task_set_priority(task, prio, &cur);
0164 ASSERT_SC(sc);
0165 }
0166
0167 static rtems_bdbuf_buffer *get(enum get_type type, enum blk_kind kind)
0168 {
0169 rtems_status_code sc = RTEMS_SUCCESSFUL;
0170 rtems_bdbuf_buffer *bd = NULL;
0171 rtems_blkdev_bnum blk_index = 0;
0172 rtems_status_code (*get_bd)(
0173 rtems_disk_device *,
0174 rtems_blkdev_bnum,
0175 rtems_bdbuf_buffer **
0176 ) = NULL;
0177 rtems_disk_device *dd = NULL;
0178 size_t bds_per_group = 0;
0179
0180 switch (kind) {
0181 case BLK_A0:
0182 dd = dd_a;
0183 blk_index = 0;
0184 bds_per_group = 2;
0185 break;
0186 case BLK_A1:
0187 dd = dd_a;
0188 blk_index = 1;
0189 bds_per_group = 2;
0190 break;
0191 case BLK_B0:
0192 dd = dd_b;
0193 blk_index = 0;
0194 bds_per_group = 1;
0195 break;
0196 default:
0197 rtems_test_assert(false);
0198 break;
0199 }
0200
0201 switch (type) {
0202 case GET:
0203 get_bd = rtems_bdbuf_get;
0204 break;
0205 case READ:
0206 get_bd = rtems_bdbuf_read;
0207 break;
0208 default:
0209 rtems_test_assert(false);
0210 break;
0211 }
0212
0213 sc = (*get_bd)(dd, blk_index, &bd);
0214 rtems_test_assert(
0215 sc == RTEMS_SUCCESSFUL
0216 && bd->dd == dd
0217 && bd->block == blk_index
0218 && bd->group->bds_per_group == bds_per_group
0219 );
0220
0221 return bd;
0222 }
0223
0224 static void rel(rtems_bdbuf_buffer *bd, enum rel_type type)
0225 {
0226 rtems_status_code sc = RTEMS_SUCCESSFUL;
0227 rtems_status_code (*rel_bd)(rtems_bdbuf_buffer *) = NULL;
0228
0229 switch (type) {
0230 case REL:
0231 rel_bd = rtems_bdbuf_release;
0232 break;
0233 case REL_MOD:
0234 rel_bd = rtems_bdbuf_release_modified;
0235 break;
0236 case SYNC:
0237 rel_bd = rtems_bdbuf_sync;
0238 break;
0239 default:
0240 rtems_test_assert(false);
0241 break;
0242 }
0243
0244 sc = (*rel_bd)(bd);
0245 ASSERT_SC(sc);
0246 }
0247
0248 static void task_low(rtems_task_argument arg)
0249 {
0250 rtems_status_code sc = RTEMS_SUCCESSFUL;
0251
0252 while (true) {
0253 print(2, "LG\n");
0254 rtems_bdbuf_buffer *bd = get(low_get, low_blk);
0255
0256 print(2, "LR\n");
0257 rel(bd, low_rel);
0258
0259 finish_low = true;
0260
0261 sc = rtems_task_suspend(RTEMS_SELF);
0262 ASSERT_SC(sc);
0263 }
0264 }
0265
0266 static void task_high(rtems_task_argument arg)
0267 {
0268 rtems_status_code sc = RTEMS_SUCCESSFUL;
0269
0270 while (true) {
0271 print(2, "HG\n");
0272 rtems_bdbuf_buffer *bd = get(high_get, high_blk);
0273
0274 print(2, "HR\n");
0275 rel(bd, high_rel);
0276
0277 finish_high = true;
0278
0279 sc = rtems_task_suspend(RTEMS_SELF);
0280 ASSERT_SC(sc);
0281 }
0282 }
0283
0284 static void task_resume(rtems_task_argument arg)
0285 {
0286 while (true) {
0287 bool do_resume = false;
0288
0289 switch (resume) {
0290 case RESUME_IMMEDIATE:
0291 print(2, "RI\n");
0292 do_resume = true;
0293 break;
0294 case RESUME_FINISH:
0295 print(2, "RF\n");
0296 do_resume = finish_low && finish_high;
0297 break;
0298 default:
0299 rtems_test_assert(false);
0300 break;
0301 }
0302
0303 if (do_resume) {
0304 rtems_task_resume(task_id_init);
0305 }
0306 }
0307 }
0308
0309 static void execute_test(unsigned i)
0310 {
0311 rtems_status_code sc = RTEMS_SUCCESSFUL;
0312 rtems_bdbuf_buffer *bd = NULL;
0313 bool suspend = false;
0314
0315 print(
0316 1,
0317 "[%05u]T(%c,%c,%s,%c)L(%c,%s,%c)H(%c,%s,%c)\n",
0318 i,
0319 trig_style_desc [trig],
0320 get_type_desc [trig_get],
0321 blk_kind_desc [trig_blk],
0322 rel_type_desc [trig_rel],
0323 get_type_desc [low_get],
0324 blk_kind_desc [low_blk],
0325 rel_type_desc [low_rel],
0326 get_type_desc [high_get],
0327 blk_kind_desc [high_blk],
0328 rel_type_desc [high_rel]
0329 );
0330
0331 set_task_prio(task_id_low, PRIORITY_LOW);
0332
0333 finish_low = false;
0334 finish_high = false;
0335
0336 sc = rtems_task_resume(task_id_low);
0337 ASSERT_SC(sc);
0338
0339 sc = rtems_task_resume(task_id_high);
0340 ASSERT_SC(sc);
0341
0342 sc = rtems_bdbuf_get(dd_b, 0, &bd);
0343 rtems_test_assert(sc == RTEMS_SUCCESSFUL && bd->dd == dd_b && bd->block == 0);
0344
0345 sc = rtems_bdbuf_release(bd);
0346 ASSERT_SC(sc);
0347
0348 switch (trig) {
0349 case SUSP:
0350 suspend = true;
0351 break;
0352 case CONT:
0353 suspend = false;
0354 break;
0355 default:
0356 rtems_test_assert(false);
0357 break;
0358 }
0359
0360 print(2, "TG\n");
0361 bd = get(trig_get, trig_blk);
0362
0363 if (suspend) {
0364 print(2, "S\n");
0365 resume = RESUME_IMMEDIATE;
0366 sc = rtems_task_suspend(RTEMS_SELF);
0367 ASSERT_SC(sc);
0368 }
0369 resume = RESUME_FINISH;
0370
0371 print(2, "TR\n");
0372 rel(bd, trig_rel);
0373
0374 sc = rtems_task_suspend(RTEMS_SELF);
0375 ASSERT_SC(sc);
0376
0377 print(2, "F\n");
0378
0379 sc = rtems_bdbuf_syncdev(dd_a);
0380 ASSERT_SC(sc);
0381
0382 sc = rtems_bdbuf_syncdev(dd_b);
0383 ASSERT_SC(sc);
0384 }
0385
0386 static int disk_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
0387 {
0388 if (req == RTEMS_BLKIO_REQUEST) {
0389 rtems_blkdev_request *r = argp;
0390
0391 set_task_prio(task_id_low, PRIORITY_LOW_ALT);
0392
0393 switch (r->req) {
0394 case RTEMS_BLKDEV_REQ_READ:
0395 case RTEMS_BLKDEV_REQ_WRITE:
0396 rtems_blkdev_request_done(r, RTEMS_SUCCESSFUL);
0397 return 0;
0398 default:
0399 errno = EINVAL;
0400 return -1;
0401 }
0402 } else {
0403 return rtems_blkdev_ioctl(dd, req, argp);
0404 }
0405 }
0406
0407 static void disk_register(
0408 const char *dev,
0409 uint32_t block_size,
0410 rtems_blkdev_bnum block_count,
0411 rtems_disk_device **dd_ptr
0412 )
0413 {
0414 rtems_status_code sc;
0415 int rv;
0416 int fd;
0417
0418 sc = rtems_blkdev_create(
0419 dev,
0420 block_size,
0421 block_count,
0422 disk_ioctl,
0423 NULL
0424 );
0425 ASSERT_SC(sc);
0426
0427 fd = open(dev, O_RDWR);
0428 rtems_test_assert(fd >= 0);
0429
0430 rv = rtems_disk_fd_get_disk_device(fd, dd_ptr);
0431 rtems_test_assert(rv == 0);
0432
0433 rv = close(fd);
0434 rtems_test_assert(rv == 0);
0435 }
0436
0437 static rtems_task Init(rtems_task_argument argument)
0438 {
0439 rtems_status_code sc = RTEMS_SUCCESSFUL;
0440 unsigned i = 0;
0441
0442 TEST_BEGIN();
0443
0444 task_id_init = rtems_task_self();
0445
0446 disk_register("dd_b", BLOCK_SIZE_A, BLOCK_COUNT_A, &dd_a);
0447
0448 disk_register("dd_a", BLOCK_SIZE_B, BLOCK_COUNT_B, &dd_b);
0449
0450 sc = rtems_task_create(
0451 rtems_build_name(' ', 'L', 'O', 'W'),
0452 PRIORITY_LOW,
0453 0,
0454 RTEMS_DEFAULT_MODES,
0455 RTEMS_DEFAULT_ATTRIBUTES,
0456 &task_id_low
0457 );
0458 ASSERT_SC(sc);
0459
0460 sc = rtems_task_start(task_id_low, task_low, 0);
0461 ASSERT_SC(sc);
0462
0463 sc = rtems_task_create(
0464 rtems_build_name('H', 'I', 'G', 'H'),
0465 PRIORITY_HIGH,
0466 0,
0467 RTEMS_DEFAULT_MODES,
0468 RTEMS_DEFAULT_ATTRIBUTES,
0469 &task_id_high
0470 );
0471 ASSERT_SC(sc);
0472
0473 sc = rtems_task_start(task_id_high, task_high, 0);
0474 ASSERT_SC(sc);
0475
0476 sc = rtems_task_create(
0477 rtems_build_name('R', 'E', 'S', 'U'),
0478 PRIORITY_RESUME,
0479 0,
0480 RTEMS_DEFAULT_MODES,
0481 RTEMS_DEFAULT_ATTRIBUTES,
0482 &task_id_resume
0483 );
0484 ASSERT_SC(sc);
0485
0486 sc = rtems_task_start(task_id_resume, task_resume, 0);
0487 ASSERT_SC(sc);
0488
0489 sc = rtems_task_suspend(task_id_low);
0490 ASSERT_SC(sc);
0491
0492 sc = rtems_task_suspend(task_id_high);
0493 ASSERT_SC(sc);
0494
0495 for (trig = SUSP; trig <= CONT; ++trig) {
0496 for (trig_get = GET; trig_get <= READ; ++trig_get) {
0497 for (low_get = GET; low_get <= READ; ++low_get) {
0498 for (high_get = GET; high_get <= READ; ++high_get) {
0499 for (trig_blk = BLK_A0; trig_blk <= BLK_B0; ++trig_blk) {
0500 for (low_blk = BLK_A0; low_blk <= BLK_B0; ++low_blk) {
0501 for (high_blk = BLK_A0; high_blk <= BLK_B0; ++high_blk) {
0502 for (trig_rel = REL; trig_rel <= SYNC; ++trig_rel) {
0503 for (low_rel = REL; low_rel <= SYNC; ++low_rel) {
0504 for (high_rel = REL; high_rel <= SYNC; ++high_rel) {
0505 execute_test(i);
0506 ++i;
0507 }
0508 }
0509 }
0510 }
0511 }
0512 }
0513 }
0514 }
0515 }
0516 }
0517
0518 TEST_END();
0519
0520 exit(0);
0521 }
0522
0523 #define CONFIGURE_INIT
0524
0525 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0526 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0527 #define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
0528
0529 #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
0530
0531 #define CONFIGURE_MAXIMUM_TASKS 4
0532
0533 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0534
0535 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0536
0537 #define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_INIT
0538 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
0539 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0540
0541 #define CONFIGURE_SWAPOUT_TASK_PRIORITY PRIORITY_SWAPOUT
0542
0543 #define CONFIGURE_BDBUF_BUFFER_MIN_SIZE BLOCK_SIZE_A
0544 #define CONFIGURE_BDBUF_BUFFER_MAX_SIZE BLOCK_SIZE_B
0545 #define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE BLOCK_SIZE_B
0546
0547 #include <rtems/confdefs.h>