File indexing completed on 2025-05-11 08:24:32
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 #ifndef BDBUF_TESTS_H
0032 #define BDBUF_TESTS_H
0033
0034 #include <inttypes.h>
0035 #include <stdio.h>
0036 #include <string.h>
0037 #include <errno.h>
0038 #include <rtems/bspIo.h>
0039 #include <rtems/bdbuf.h>
0040
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif
0044
0045 extern void run_bdbuf_tests(void);
0046
0047 extern void bdbuf_test1_1_main(void);
0048 extern void bdbuf_test1_2_main(void);
0049 extern void bdbuf_test1_3_main(void);
0050 extern void bdbuf_test1_4_main(void);
0051 extern void bdbuf_test1_5_main(void);
0052
0053 extern void bdbuf_test2_1_main(void);
0054 extern void bdbuf_test2_2_main(void);
0055 extern void bdbuf_test2_3_main(void);
0056 extern void bdbuf_test2_4_main(void);
0057 extern void bdbuf_test2_5_main(void);
0058
0059 extern void bdbuf_test3_1_main(void);
0060 extern void bdbuf_test3_2_main(void);
0061 extern void bdbuf_test3_3_main(void);
0062
0063 extern void bdbuf_test4_1_main(void);
0064 extern void bdbuf_test4_2_main(void);
0065 extern void bdbuf_test4_3_main(void);
0066
0067 extern rtems_status_code test_disk_initialize(void);
0068
0069 #define ARRAY_NUM(a_) (sizeof(a_) / sizeof(a_[0]))
0070
0071
0072
0073
0074 #define TEST_DISK_BLOCK_SIZE 512
0075 #define TEST_DISK_BLOCK_NUM 1024
0076 #define TEST_DISK_NAME "/dev/testdisk"
0077
0078
0079 enum bdbuf_test_msg_type {
0080
0081 BDBUF_TEST_MSG_TYPE_DRIVER_REQ,
0082
0083
0084
0085
0086 BDBUF_TEST_MSG_TYPE_DRIVER_REPLY,
0087 };
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 typedef struct bdbuf_test_msg {
0098
0099 enum bdbuf_test_msg_type type;
0100
0101 union {
0102 struct driver_req {
0103 const rtems_disk_device *dd;
0104 uint32_t req;
0105 void *argp;
0106 } driver_req;
0107 struct driver_reply {
0108 int ret_val;
0109 int ret_errno;
0110 rtems_status_code res_status;
0111 int res_errno;
0112 } driver_reply;
0113 } val;
0114 } bdbuf_test_msg;
0115
0116
0117 typedef enum bdbuf_rest_thread_prio {
0118 BDBUF_TEST_THREAD_PRIO_NORMAL = 3,
0119 BDBUF_TEST_THREAD_PRIO_LOW = 7,
0120 BDBUF_TEST_THREAD_PRIO_HIGH = 5,
0121 } bdbuf_rest_thread_prio;
0122
0123
0124 typedef struct test_ctx {
0125
0126
0127
0128
0129 Objects_Id test_qid;
0130
0131
0132
0133
0134
0135
0136 Objects_Id test_drv_qid;
0137
0138
0139 const char *test_name;
0140
0141
0142
0143
0144
0145
0146
0147 rtems_id test_sync_main[3];
0148
0149
0150
0151
0152
0153 rtems_id test_end_main;
0154
0155
0156
0157
0158
0159
0160
0161 rtems_id test_sync[3];
0162
0163
0164 Objects_Id test_task[3];
0165 } test_ctx;
0166
0167 extern test_ctx g_test_ctx;
0168
0169
0170 extern rtems_disk_device *test_dd;
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 extern rtems_status_code bdbuf_test_create_drv_rx_queue(Objects_Id *id);
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190 extern rtems_status_code bdbuf_test_create_drv_tx_queue(Objects_Id *id);
0191
0192
0193
0194
0195
0196
0197
0198
0199 extern rtems_status_code bdbuf_test_start_thread(unsigned int idx,
0200 rtems_task_entry func);
0201
0202
0203
0204
0205 extern rtems_status_code bdbuf_test_end(void);
0206
0207
0208 extern bool good_test_result;
0209
0210 #define BDBUF_TEST_BLOCK_TIMEOUT (2 * rtems_clock_get_ticks_per_second())
0211
0212 #define SET_THREAD_PRIORITY(t_num_, prio_) \
0213 do { \
0214 rtems_task_priority old_prio; \
0215 rtems_status_code rc_; \
0216 \
0217 rc_ = rtems_task_set_priority( \
0218 g_test_ctx.test_task[(t_num_) - 1], \
0219 BDBUF_TEST_THREAD_PRIO_ ## prio_, &old_prio); \
0220 if (rc_ != RTEMS_SUCCESSFUL) \
0221 { \
0222 printk("Failed to change priority of test thread #" \
0223 #t_num_ " in test %s\n", g_test_ctx.test_name); \
0224 return; \
0225 } \
0226 } while (0)
0227
0228
0229
0230
0231
0232
0233
0234
0235 #define START_THREAD(t_num_, func_) \
0236 do { \
0237 if (bdbuf_test_start_thread((t_num_) - 1, func_) != \
0238 RTEMS_SUCCESSFUL) \
0239 { \
0240 return; \
0241 } \
0242 printk("Thread #" #t_num_ " started\n"); \
0243 } while (0)
0244
0245
0246
0247
0248
0249
0250 #define WAIT_DRV_MSG(msg_) \
0251 do { \
0252 rtems_status_code rc_; \
0253 size_t msg_size_ = sizeof(*(msg_)); \
0254 \
0255 rc_ = rtems_message_queue_receive(g_test_ctx.test_qid, \
0256 (msg_), &msg_size_, \
0257 RTEMS_WAIT, \
0258 RTEMS_NO_TIMEOUT); \
0259 if (rc_ != RTEMS_SUCCESSFUL || \
0260 msg_size_ != sizeof(*(msg_))) \
0261 { \
0262 printk("Error at %s:%d\n", __FILE__, __LINE__); \
0263 return; \
0264 } \
0265 if ((msg_)->type != BDBUF_TEST_MSG_TYPE_DRIVER_REQ) \
0266 { \
0267 printk("Unexpected message received: %d\n", \
0268 (msg_)->type); \
0269 return; \
0270 } \
0271 } while (0)
0272
0273 #define WAIT_DRV_MSG_WR(msg_) \
0274 do { \
0275 WAIT_DRV_MSG(msg_); \
0276 if ((msg_)->val.driver_req.req != RTEMS_BLKIO_REQUEST || \
0277 (msg_)->val.driver_req.dd != test_dd || \
0278 ((rtems_blkdev_request *) \
0279 ((msg_)->val.driver_req.argp))->req != \
0280 RTEMS_BLKDEV_REQ_WRITE) \
0281 { \
0282 printk("Unexpected message received by disk driver: " \
0283 "req - 0x%" PRIx32 " (0x%lx), dev - %p (%p)\n", \
0284 (msg_)->val.driver_req.req, RTEMS_BLKIO_REQUEST, \
0285 (msg_)->val.driver_req.dd, test_dd); \
0286 return; \
0287 } \
0288 } while (0)
0289
0290 #define CHECK_NO_DRV_MSG() \
0291 do { \
0292 rtems_status_code rc_; \
0293 bdbuf_test_msg msg_; \
0294 size_t msg_size_ = sizeof(msg_); \
0295 \
0296 rc_ = rtems_message_queue_receive(g_test_ctx.test_qid, \
0297 (&msg_), &msg_size_, \
0298 RTEMS_WAIT, \
0299 BDBUF_TEST_BLOCK_TIMEOUT); \
0300 if (rc_ != RTEMS_TIMEOUT) \
0301 { \
0302 printk("Error at %s:%d\n", __FILE__, __LINE__); \
0303 return; \
0304 } \
0305 } while (0)
0306
0307 extern bdbuf_test_msg test_drv_msg;
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 #define SEND_DRV_MSG(ret_val_, ret_errno_, res_status_, res_errno_) \
0327 do { \
0328 rtems_status_code rc_; \
0329 \
0330 memset(&test_drv_msg, 0, sizeof(test_drv_msg)); \
0331 test_drv_msg.type = BDBUF_TEST_MSG_TYPE_DRIVER_REPLY; \
0332 test_drv_msg.val.driver_reply.ret_val = (ret_val_); \
0333 test_drv_msg.val.driver_reply.ret_errno = (ret_errno_); \
0334 test_drv_msg.val.driver_reply.res_status = (res_status_); \
0335 test_drv_msg.val.driver_reply.res_errno = (res_errno_); \
0336 \
0337 rc_ = rtems_message_queue_send(g_test_ctx.test_drv_qid, \
0338 &test_drv_msg, \
0339 sizeof(test_drv_msg)); \
0340 if (rc_ != RTEMS_SUCCESSFUL) \
0341 { \
0342 printk("Error while sending a message to " \
0343 "disk driver: %u\n", rc_); \
0344 return; \
0345 } \
0346 } while (0)
0347
0348
0349
0350
0351
0352
0353
0354
0355 #define WAIT_THREAD_SYNC(t_num_) \
0356 do { \
0357 rtems_status_code rc_; \
0358 \
0359 rc_ = rtems_semaphore_obtain( \
0360 g_test_ctx.test_sync_main[(t_num_) - 1], \
0361 RTEMS_WAIT, RTEMS_NO_TIMEOUT); \
0362 if (rc_ != RTEMS_SUCCESSFUL) \
0363 { \
0364 printk("Failed to get sync with a thread: %d\n", rc_); \
0365 return; \
0366 } \
0367 } while (0)
0368
0369
0370
0371
0372
0373
0374 #define CHECK_THREAD_BLOCKED(t_num_) \
0375 do { \
0376 rtems_status_code rc_; \
0377 \
0378 rc_ = rtems_semaphore_obtain( \
0379 g_test_ctx.test_sync_main[(t_num_) - 1], \
0380 RTEMS_WAIT, BDBUF_TEST_BLOCK_TIMEOUT); \
0381 if (rc_ != RTEMS_TIMEOUT) \
0382 { \
0383 printk("Thread %d is not blocked at%s:%d\n", \
0384 t_num_, __FILE__, __LINE__); \
0385 return; \
0386 } \
0387 } while (0)
0388
0389
0390
0391
0392
0393
0394
0395 #define CONTINUE_THREAD(t_num_) \
0396 do { \
0397 rtems_status_code rc_; \
0398 \
0399 rc_ = rtems_semaphore_release( \
0400 g_test_ctx.test_sync[(t_num_) - 1]); \
0401 if (rc_ != RTEMS_SUCCESSFUL) \
0402 { \
0403 printk("Failed to give control to thread #" \
0404 #t_num_ ": %d\n", rc_); \
0405 return; \
0406 } \
0407 } while (0)
0408
0409
0410
0411
0412
0413
0414 #define CONTINUE_MAIN(t_num_) \
0415 do { \
0416 rtems_status_code rc_; \
0417 \
0418 rc_ = rtems_semaphore_release( \
0419 g_test_ctx.test_sync_main[(t_num_) - 1]); \
0420 if (rc_ != RTEMS_SUCCESSFUL) \
0421 { \
0422 printk("Failed to give control to " \
0423 "main task: %d", rc_); \
0424 return; \
0425 } \
0426 rc_ = rtems_semaphore_obtain( \
0427 g_test_ctx.test_sync[(t_num_) - 1], \
0428 RTEMS_WAIT, RTEMS_NO_TIMEOUT); \
0429 if (rc_ != RTEMS_SUCCESSFUL) \
0430 { \
0431 printk("Failed to block on thread #" \
0432 #t_num_ ": %d\n", rc_); \
0433 return; \
0434 } \
0435 } while (0)
0436
0437 #define WAIT_MAIN_SYNC(t_num_) \
0438 do { \
0439 rtems_status_code rc_; \
0440 \
0441 rc_ = rtems_semaphore_obtain( \
0442 g_test_ctx.test_sync[(t_num_) - 1], \
0443 RTEMS_WAIT, RTEMS_NO_TIMEOUT); \
0444 if (rc_ != RTEMS_SUCCESSFUL) \
0445 { \
0446 printk("Failed to block on thread #" \
0447 #t_num_ ": %d\n", rc_); \
0448 return; \
0449 } \
0450 } while (0)
0451
0452
0453 #define TEST_START(test_name_) \
0454 do { \
0455 good_test_result = true; \
0456 g_test_ctx.test_name = test_name_; \
0457 printk("%s - STARTED\n", \
0458 g_test_ctx.test_name); \
0459 } while (0)
0460
0461 #define TEST_CHECK_RESULT(step_) \
0462 do { \
0463 if (!good_test_result) \
0464 { \
0465 printk("TEST FAILED (Step %s)\n", \
0466 step_); \
0467 rtems_task_exit(); \
0468 } \
0469 else \
0470 { \
0471 printk("%s: Step %s - OK\n", \
0472 g_test_ctx.test_name, step_); \
0473 } \
0474 } while (0)
0475
0476 #define TEST_STOP() \
0477 do { \
0478 bdbuf_test_end(); \
0479 \
0480 if (good_test_result) \
0481 printk("TEST PASSED\n"); \
0482 else \
0483 printk("TEST FAILED (END)"); \
0484 } while (0)
0485
0486 #define THREAD_END() \
0487 do { \
0488 rtems_status_code rc_; \
0489 \
0490 rc_ = rtems_semaphore_release(g_test_ctx.test_end_main);\
0491 if (rc_ != RTEMS_SUCCESSFUL) \
0492 { \
0493 printk("Failed to give control to " \
0494 "main task: %d", rc_); \
0495 return; \
0496 } \
0497 rtems_task_exit(); \
0498 } while (0)
0499
0500 #define TEST_FAILED() \
0501 do { \
0502 good_test_result = false; \
0503 } while (0)
0504
0505 #define SLEEP() \
0506 rtems_task_wake_after(BDBUF_TEST_BLOCK_TIMEOUT)
0507
0508
0509 extern rtems_status_code
0510 bdbuf_test_start_aux_task(rtems_name name,
0511 rtems_task_entry entry_point,
0512 rtems_task_argument arg,
0513 Objects_Id *id);
0514 #ifdef __cplusplus
0515 }
0516 #endif
0517
0518 #endif