File indexing completed on 2025-05-11 08:24:46
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 <tmacros.h>
0041
0042 const char rtems_test_name[] = "SP 68";
0043
0044
0045 rtems_task Init(rtems_task_argument argument);
0046
0047 #define TIMER_COUNT 6
0048
0049 #define OBTAIN 0
0050 #define RELEASE 1
0051 #define INTERRUPT 2
0052 #define DELAYED 3
0053 #define SERVER_TRIGGERED 4
0054 #define INTERRUPT_TRIGGERED 5
0055
0056 #define T0 0
0057 #define T1 1
0058 #define T2 2
0059 #define T3 3
0060 #define T4 4
0061 #define T5 5
0062 #define T6 6
0063
0064 static volatile bool obtain_try;
0065 static volatile bool obtain_done;
0066 static volatile bool release_happened;
0067 static volatile bool interrupt_happened;
0068 static volatile bool delayed_happened;
0069 static volatile bool server_triggered_happened;
0070 static volatile bool interrupt_triggered_happened;
0071
0072 static rtems_id timer [TIMER_COUNT];
0073
0074 static rtems_id semaphore;
0075 static rtems_id mutex;
0076 static rtems_id message_queue;
0077 static rtems_id region;
0078 static rtems_id barrier;
0079
0080 static void *region_item;
0081
0082 static rtems_interval start;
0083
0084 static rtems_id timer_server_id;
0085
0086 static volatile enum resource_type {
0087 SEMAPHORE = 0,
0088 MUTEX,
0089 MESSAGE_QUEUE,
0090 REGION,
0091 EVENT,
0092 BARRIER,
0093 TASK_WAKE_AFTER
0094 } resource_type;
0095
0096 static const char *const resource_type_desc [] = {
0097 "SEMAPHORE",
0098 "MUTEX",
0099 "MESSAGE QUEUE",
0100 "REGION",
0101 "EVENT",
0102 "BARRIER",
0103 "TASK WAKE AFTER"
0104 };
0105
0106 static void assert_time(rtems_interval expected)
0107 {
0108 rtems_test_assert((rtems_clock_get_ticks_since_boot() - start) == expected);
0109 }
0110
0111 static void obtain_callback(rtems_id timer_id, void *arg)
0112 {
0113 rtems_status_code sc = RTEMS_SUCCESSFUL;
0114 char buf [1];
0115 size_t size = sizeof(buf);
0116 void *new_region_item = NULL;
0117 rtems_event_set events = 0;
0118
0119 assert_time(T1);
0120
0121 rtems_test_assert(
0122 !release_happened
0123 && !interrupt_happened
0124 && !delayed_happened
0125 && !interrupt_triggered_happened
0126 && !server_triggered_happened
0127 );
0128
0129 obtain_try = true;
0130
0131 switch (resource_type) {
0132 case SEMAPHORE:
0133 sc = rtems_semaphore_obtain(semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0134 break;
0135 case MUTEX:
0136 sc = rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0137 break;
0138 case MESSAGE_QUEUE:
0139 sc = rtems_message_queue_receive(
0140 message_queue, buf, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0141 break;
0142 case REGION:
0143 sc = rtems_region_get_segment(
0144 region, 1, RTEMS_WAIT, RTEMS_NO_TIMEOUT, &new_region_item);
0145 break;
0146 case EVENT:
0147 timer_server_id = rtems_task_self();
0148 sc = rtems_event_receive(
0149 RTEMS_EVENT_0, RTEMS_EVENT_ALL | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
0150 break;
0151 case BARRIER:
0152 sc = rtems_barrier_wait(barrier, RTEMS_NO_TIMEOUT);
0153 break;
0154 case TASK_WAKE_AFTER:
0155 sc = rtems_task_wake_after(T4 - T1);
0156 break;
0157 default:
0158 rtems_test_assert(false);
0159 break;
0160 }
0161 directive_failed(sc, "obtain");
0162
0163 obtain_done = true;
0164 }
0165
0166 static void release_callback(rtems_id timer_id, void *arg)
0167 {
0168 rtems_status_code sc = RTEMS_SUCCESSFUL;
0169 char buf [1] = { 0 };
0170 size_t size = sizeof(buf);
0171 uint32_t released = 0;
0172
0173 assert_time(T4);
0174
0175 rtems_test_assert(
0176 obtain_try
0177 && interrupt_happened
0178 && !delayed_happened
0179 && !interrupt_triggered_happened
0180 && !server_triggered_happened
0181 );
0182
0183 switch (resource_type) {
0184 case SEMAPHORE:
0185 sc = rtems_semaphore_release(semaphore);
0186 break;
0187 case MUTEX:
0188 sc = rtems_semaphore_release(mutex);
0189 break;
0190 case MESSAGE_QUEUE:
0191 sc = rtems_message_queue_send(message_queue, buf, size);
0192 break;
0193 case EVENT:
0194 sc = rtems_event_send(timer_server_id, RTEMS_EVENT_0);
0195 break;
0196 case BARRIER:
0197 sc = rtems_barrier_release(barrier, &released);
0198 break;
0199 case TASK_WAKE_AFTER:
0200 sc = RTEMS_SUCCESSFUL;
0201 break;
0202 default:
0203 rtems_test_assert(false);
0204 break;
0205 }
0206 directive_failed_with_level(sc, "release", 1);
0207
0208 release_happened = true;
0209 }
0210
0211 static void interrupt_triggered_callback(rtems_id timer_id, void *arg)
0212 {
0213
0214
0215
0216
0217 assert_time(T4);
0218
0219 rtems_test_assert(
0220 obtain_done
0221 && release_happened
0222 && interrupt_happened
0223 && !server_triggered_happened
0224 );
0225
0226 interrupt_triggered_happened = true;
0227 }
0228
0229 static void interrupt_callback(rtems_id timer_id, void *arg)
0230 {
0231 rtems_status_code sc = RTEMS_SUCCESSFUL;
0232
0233 assert_time(T2);
0234
0235 rtems_test_assert(
0236 obtain_try
0237 && !obtain_done
0238 && !release_happened
0239 && !delayed_happened
0240 && !interrupt_triggered_happened
0241 && !server_triggered_happened
0242 );
0243
0244 sc = rtems_timer_server_fire_after(
0245 timer [INTERRUPT_TRIGGERED],
0246 T3 - T2,
0247 interrupt_triggered_callback,
0248 NULL
0249 );
0250 directive_failed_with_level(sc, "rtems_timer_server_fire_after", -1);
0251
0252 interrupt_happened = true;
0253 }
0254
0255 static void server_triggered_callback(rtems_id timer_id, void *arg)
0256 {
0257 assert_time(T5);
0258
0259 rtems_test_assert(
0260 obtain_done
0261 && release_happened
0262 && interrupt_happened
0263 && delayed_happened
0264 && interrupt_triggered_happened
0265 );
0266
0267 server_triggered_happened = true;
0268 }
0269
0270 static void delayed_callback(rtems_id timer_id, void *arg)
0271 {
0272 rtems_status_code sc = RTEMS_SUCCESSFUL;
0273
0274 assert_time(T4);
0275
0276 rtems_test_assert(
0277 obtain_done
0278 && release_happened
0279 && interrupt_happened
0280 && !server_triggered_happened
0281 );
0282
0283 sc = rtems_timer_server_fire_after(
0284 timer [SERVER_TRIGGERED],
0285 T5 - T4,
0286 server_triggered_callback,
0287 NULL
0288 );
0289 directive_failed(sc, "rtems_timer_server_fire_after");
0290
0291 delayed_happened = true;
0292 }
0293
0294 static void test_reset(void)
0295 {
0296 rtems_status_code sc = RTEMS_SUCCESSFUL;
0297
0298 obtain_try = false;
0299 obtain_done = false;
0300 release_happened = false;
0301 interrupt_happened = false;
0302 delayed_happened = false;
0303 interrupt_triggered_happened = false;
0304 server_triggered_happened = false;
0305
0306
0307 sc = rtems_task_wake_after(1);
0308 directive_failed(sc, "rtems_task_wake_after");
0309
0310 start = rtems_clock_get_ticks_since_boot();
0311 }
0312
0313 static void test_case(enum resource_type rt)
0314 {
0315 rtems_status_code sc = RTEMS_SUCCESSFUL;
0316
0317 printf("test case: %s\n", resource_type_desc [rt]);
0318
0319 resource_type = rt;
0320
0321 test_reset();
0322
0323 sc = rtems_timer_server_fire_after(
0324 timer [OBTAIN],
0325 T1 - T0,
0326 obtain_callback,
0327 NULL
0328 );
0329 directive_failed(sc, "rtems_timer_server_fire_after");
0330
0331 sc = rtems_timer_fire_after(
0332 timer [INTERRUPT],
0333 T2 - T0,
0334 interrupt_callback,
0335 NULL
0336 );
0337 directive_failed(sc, "rtems_timer_fire_after");
0338
0339 sc = rtems_timer_server_fire_after(
0340 timer [DELAYED],
0341 T3 - T0,
0342 delayed_callback,
0343 NULL
0344 );
0345 directive_failed(sc, "rtems_timer_server_fire_after");
0346
0347 if (resource_type != REGION) {
0348 sc = rtems_timer_fire_after(
0349 timer [RELEASE],
0350 T4 - T0,
0351 release_callback,
0352 NULL
0353 );
0354 directive_failed(sc, "rtems_timer_fire_after");
0355
0356 assert_time(T0);
0357
0358 sc = rtems_task_wake_after(T6 - T0);
0359 directive_failed(sc, "task_wake_after");
0360 } else {
0361 sc = rtems_task_wake_after(T4 - T0);
0362 directive_failed(sc, "task_wake_after");
0363
0364 assert_time(T4);
0365
0366 rtems_test_assert(
0367 obtain_try
0368 && interrupt_happened
0369 && !delayed_happened
0370 && !interrupt_triggered_happened
0371 && !server_triggered_happened
0372 );
0373
0374 sc = rtems_region_return_segment(region, region_item);
0375 directive_failed(sc, "rtems_region_return_segment");
0376
0377 release_happened = true;
0378
0379 sc = rtems_task_wake_after(T6 - T4);
0380 directive_failed(sc, "task_wake_after");
0381 }
0382
0383 assert_time(T6);
0384
0385 rtems_test_assert(
0386 obtain_done
0387 && interrupt_happened
0388 && release_happened
0389 && delayed_happened
0390 && interrupt_triggered_happened
0391 && server_triggered_happened
0392 );
0393 }
0394
0395 rtems_task Init(rtems_task_argument argument)
0396 {
0397 rtems_status_code sc = RTEMS_SUCCESSFUL;
0398 char region_area [256];
0399 enum resource_type rt = SEMAPHORE;
0400 void *new_region_item = NULL;
0401 size_t i = 0;
0402
0403 TEST_BEGIN();
0404
0405 for (i = 0; i < TIMER_COUNT; ++i) {
0406 sc = rtems_timer_create(
0407 rtems_build_name('T', 'I', 'M', '0' + i),
0408 &timer [i]
0409 );
0410 directive_failed(sc, "rtems_timer_create");
0411 }
0412
0413 sc = rtems_timer_initiate_server(
0414 RTEMS_MINIMUM_PRIORITY,
0415 RTEMS_MINIMUM_STACK_SIZE,
0416 RTEMS_DEFAULT_ATTRIBUTES
0417 );
0418 directive_failed(sc, "rtems_timer_initiate_server");
0419
0420 sc = rtems_semaphore_create(
0421 rtems_build_name('S', 'E', 'M', 'A'),
0422 0,
0423 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE,
0424 0,
0425 &semaphore
0426 );
0427 directive_failed(sc, "rtems_semaphore_create");
0428
0429 sc = rtems_semaphore_create(
0430 rtems_build_name('M', 'U', 'T', 'X'),
0431 0,
0432 RTEMS_LOCAL | RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE,
0433 0,
0434 &mutex
0435 );
0436 directive_failed(sc, "rtems_semaphore_create");
0437
0438 sc = rtems_message_queue_create(
0439 rtems_build_name('M', 'S', 'G', 'Q'),
0440 1,
0441 1,
0442 RTEMS_LOCAL | RTEMS_FIFO,
0443 &message_queue
0444 );
0445 directive_failed(sc, "rtems_message_queue_create");
0446
0447 sc = rtems_region_create(
0448 rtems_build_name('R', 'E', 'G', 'I'),
0449 region_area,
0450 sizeof(region_area),
0451 1,
0452 RTEMS_LOCAL | RTEMS_FIFO,
0453 ®ion
0454 );
0455 directive_failed(sc, "rtems_region_create");
0456
0457 do {
0458 region_item = new_region_item;
0459 sc = rtems_region_get_segment(
0460 region, 1, RTEMS_NO_WAIT, 0, &new_region_item);
0461 } while (sc == RTEMS_SUCCESSFUL);
0462
0463 sc = rtems_barrier_create(
0464 rtems_build_name('B', 'A', 'R', 'R'),
0465 RTEMS_LOCAL | RTEMS_FIFO,
0466 2,
0467 &barrier
0468 );
0469 directive_failed(sc, "rtems_barrier_create");
0470
0471 while (rt <= TASK_WAKE_AFTER) {
0472 test_case(rt);
0473 ++rt;
0474 }
0475
0476 TEST_END();
0477
0478 rtems_test_exit(0);
0479 }
0480
0481 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0482 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0483
0484 #define CONFIGURE_MAXIMUM_TASKS 2
0485 #define CONFIGURE_MAXIMUM_TIMERS TIMER_COUNT
0486 #define CONFIGURE_MAXIMUM_SEMAPHORES 2
0487 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 1
0488 #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
0489 CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1)
0490 #define CONFIGURE_MAXIMUM_REGIONS 1
0491 #define CONFIGURE_MAXIMUM_BARRIERS 1
0492
0493 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0494
0495 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0496
0497 #define CONFIGURE_INIT
0498
0499 #include <rtems/confdefs.h>