File indexing completed on 2025-05-11 08:24:53
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
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include <rtems.h>
0056
0057 #include "tx-support.h"
0058
0059 #include <rtems/test.h>
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 typedef enum {
0070 RtemsTimerReqFireWhen_Pre_RtClock_Set,
0071 RtemsTimerReqFireWhen_Pre_RtClock_Unset,
0072 RtemsTimerReqFireWhen_Pre_RtClock_NA
0073 } RtemsTimerReqFireWhen_Pre_RtClock;
0074
0075 typedef enum {
0076 RtemsTimerReqFireWhen_Pre_Routine_Valid,
0077 RtemsTimerReqFireWhen_Pre_Routine_Null,
0078 RtemsTimerReqFireWhen_Pre_Routine_NA
0079 } RtemsTimerReqFireWhen_Pre_Routine;
0080
0081 typedef enum {
0082 RtemsTimerReqFireWhen_Pre_WallTime_Valid,
0083 RtemsTimerReqFireWhen_Pre_WallTime_Invalid,
0084 RtemsTimerReqFireWhen_Pre_WallTime_Past,
0085 RtemsTimerReqFireWhen_Pre_WallTime_Null,
0086 RtemsTimerReqFireWhen_Pre_WallTime_NA
0087 } RtemsTimerReqFireWhen_Pre_WallTime;
0088
0089 typedef enum {
0090 RtemsTimerReqFireWhen_Pre_Id_Valid,
0091 RtemsTimerReqFireWhen_Pre_Id_Invalid,
0092 RtemsTimerReqFireWhen_Pre_Id_NA
0093 } RtemsTimerReqFireWhen_Pre_Id;
0094
0095 typedef enum {
0096 RtemsTimerReqFireWhen_Pre_Context_None,
0097 RtemsTimerReqFireWhen_Pre_Context_Interrupt,
0098 RtemsTimerReqFireWhen_Pre_Context_Server,
0099 RtemsTimerReqFireWhen_Pre_Context_NA
0100 } RtemsTimerReqFireWhen_Pre_Context;
0101
0102 typedef enum {
0103 RtemsTimerReqFireWhen_Pre_Clock_None,
0104 RtemsTimerReqFireWhen_Pre_Clock_Ticks,
0105 RtemsTimerReqFireWhen_Pre_Clock_Realtime,
0106 RtemsTimerReqFireWhen_Pre_Clock_NA
0107 } RtemsTimerReqFireWhen_Pre_Clock;
0108
0109 typedef enum {
0110 RtemsTimerReqFireWhen_Pre_State_Inactive,
0111 RtemsTimerReqFireWhen_Pre_State_Scheduled,
0112 RtemsTimerReqFireWhen_Pre_State_Pending,
0113 RtemsTimerReqFireWhen_Pre_State_NA
0114 } RtemsTimerReqFireWhen_Pre_State;
0115
0116 typedef enum {
0117 RtemsTimerReqFireWhen_Post_Status_Ok,
0118 RtemsTimerReqFireWhen_Post_Status_NotDef,
0119 RtemsTimerReqFireWhen_Post_Status_InvId,
0120 RtemsTimerReqFireWhen_Post_Status_InvAddr,
0121 RtemsTimerReqFireWhen_Post_Status_InvClock,
0122 RtemsTimerReqFireWhen_Post_Status_NA
0123 } RtemsTimerReqFireWhen_Post_Status;
0124
0125 typedef enum {
0126 RtemsTimerReqFireWhen_Post_Context_None,
0127 RtemsTimerReqFireWhen_Post_Context_Interrupt,
0128 RtemsTimerReqFireWhen_Post_Context_Server,
0129 RtemsTimerReqFireWhen_Post_Context_Nop,
0130 RtemsTimerReqFireWhen_Post_Context_NA
0131 } RtemsTimerReqFireWhen_Post_Context;
0132
0133 typedef enum {
0134 RtemsTimerReqFireWhen_Post_Clock_None,
0135 RtemsTimerReqFireWhen_Post_Clock_Ticks,
0136 RtemsTimerReqFireWhen_Post_Clock_Realtime,
0137 RtemsTimerReqFireWhen_Post_Clock_Nop,
0138 RtemsTimerReqFireWhen_Post_Clock_NA
0139 } RtemsTimerReqFireWhen_Post_Clock;
0140
0141 typedef enum {
0142 RtemsTimerReqFireWhen_Post_State_Scheduled,
0143 RtemsTimerReqFireWhen_Post_State_Nop,
0144 RtemsTimerReqFireWhen_Post_State_NA
0145 } RtemsTimerReqFireWhen_Post_State;
0146
0147 typedef enum {
0148 RtemsTimerReqFireWhen_Post_WallTime_Param,
0149 RtemsTimerReqFireWhen_Post_WallTime_Nop,
0150 RtemsTimerReqFireWhen_Post_WallTime_NA
0151 } RtemsTimerReqFireWhen_Post_WallTime;
0152
0153 typedef enum {
0154 RtemsTimerReqFireWhen_Post_Routine_Param,
0155 RtemsTimerReqFireWhen_Post_Routine_Nop,
0156 RtemsTimerReqFireWhen_Post_Routine_NA
0157 } RtemsTimerReqFireWhen_Post_Routine;
0158
0159 typedef enum {
0160 RtemsTimerReqFireWhen_Post_UserData_Param,
0161 RtemsTimerReqFireWhen_Post_UserData_Nop,
0162 RtemsTimerReqFireWhen_Post_UserData_NA
0163 } RtemsTimerReqFireWhen_Post_UserData;
0164
0165 typedef struct {
0166 uint32_t Skip : 1;
0167 uint32_t Pre_RtClock_NA : 1;
0168 uint32_t Pre_Routine_NA : 1;
0169 uint32_t Pre_WallTime_NA : 1;
0170 uint32_t Pre_Id_NA : 1;
0171 uint32_t Pre_Context_NA : 1;
0172 uint32_t Pre_Clock_NA : 1;
0173 uint32_t Pre_State_NA : 1;
0174 uint32_t Post_Status : 3;
0175 uint32_t Post_Context : 3;
0176 uint32_t Post_Clock : 3;
0177 uint32_t Post_State : 2;
0178 uint32_t Post_WallTime : 2;
0179 uint32_t Post_Routine : 2;
0180 uint32_t Post_UserData : 2;
0181 } RtemsTimerReqFireWhen_Entry;
0182
0183 typedef enum {
0184 PRE_NONE = 0,
0185 PRE_INTERRUPT = 1,
0186 PRE_SERVER = 2
0187 } PreConditionContext;
0188
0189 typedef enum {
0190 SCHEDULE_NONE = 0,
0191 SCHEDULE_SOON = 1,
0192 SCHEDULE_MAX = 5
0193 } Scheduling_Ticks;
0194
0195
0196
0197
0198 typedef struct {
0199
0200
0201
0202 rtems_id timer_id;
0203
0204
0205
0206
0207 rtems_id id_param;
0208
0209
0210
0211
0212 const rtems_time_of_day *wall_time_param;
0213
0214
0215
0216
0217 rtems_timer_service_routine_entry routine_param;
0218
0219
0220
0221
0222 rtems_status_code status;
0223
0224
0225
0226
0227
0228 int invocations;
0229
0230
0231
0232
0233
0234
0235 rtems_time_of_day tod_till_fire;
0236
0237
0238
0239
0240
0241 void *routine_user_data;
0242
0243
0244
0245
0246
0247
0248 PreConditionContext pre_cond_contex;
0249
0250
0251
0252
0253
0254
0255 const rtems_time_of_day *pre_cond_tod;
0256
0257
0258
0259
0260
0261 Timer_Classes pre_class;
0262
0263
0264
0265
0266
0267 Timer_States pre_state;
0268
0269
0270
0271
0272
0273 Timer_States post_state;
0274
0275
0276
0277
0278
0279 Timer_Scheduling_Data pre_scheduling_data;
0280
0281
0282
0283
0284
0285 Timer_Scheduling_Data post_scheduling_data;
0286
0287 struct {
0288
0289
0290
0291 size_t pcs[ 7 ];
0292
0293
0294
0295
0296 bool in_action_loop;
0297
0298
0299
0300
0301 size_t index;
0302
0303
0304
0305
0306 RtemsTimerReqFireWhen_Entry entry;
0307
0308
0309
0310
0311
0312 bool skip;
0313 } Map;
0314 } RtemsTimerReqFireWhen_Context;
0315
0316 static RtemsTimerReqFireWhen_Context
0317 RtemsTimerReqFireWhen_Instance;
0318
0319 static const char * const RtemsTimerReqFireWhen_PreDesc_RtClock[] = {
0320 "Set",
0321 "Unset",
0322 "NA"
0323 };
0324
0325 static const char * const RtemsTimerReqFireWhen_PreDesc_Routine[] = {
0326 "Valid",
0327 "Null",
0328 "NA"
0329 };
0330
0331 static const char * const RtemsTimerReqFireWhen_PreDesc_WallTime[] = {
0332 "Valid",
0333 "Invalid",
0334 "Past",
0335 "Null",
0336 "NA"
0337 };
0338
0339 static const char * const RtemsTimerReqFireWhen_PreDesc_Id[] = {
0340 "Valid",
0341 "Invalid",
0342 "NA"
0343 };
0344
0345 static const char * const RtemsTimerReqFireWhen_PreDesc_Context[] = {
0346 "None",
0347 "Interrupt",
0348 "Server",
0349 "NA"
0350 };
0351
0352 static const char * const RtemsTimerReqFireWhen_PreDesc_Clock[] = {
0353 "None",
0354 "Ticks",
0355 "Realtime",
0356 "NA"
0357 };
0358
0359 static const char * const RtemsTimerReqFireWhen_PreDesc_State[] = {
0360 "Inactive",
0361 "Scheduled",
0362 "Pending",
0363 "NA"
0364 };
0365
0366 static const char * const * const RtemsTimerReqFireWhen_PreDesc[] = {
0367 RtemsTimerReqFireWhen_PreDesc_RtClock,
0368 RtemsTimerReqFireWhen_PreDesc_Routine,
0369 RtemsTimerReqFireWhen_PreDesc_WallTime,
0370 RtemsTimerReqFireWhen_PreDesc_Id,
0371 RtemsTimerReqFireWhen_PreDesc_Context,
0372 RtemsTimerReqFireWhen_PreDesc_Clock,
0373 RtemsTimerReqFireWhen_PreDesc_State,
0374 NULL
0375 };
0376
0377 static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
0378 static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 5, 0, 0, 0 };
0379 static const rtems_time_of_day tod_invalid = { 1985, 1, 1, 0, 0, 0, 0 };
0380
0381
0382
0383
0384 static const rtems_time_of_day tod_past = { 2000, 1, 1, 0, 0, 0, 50 };
0385
0386 static void TriggerTimer(
0387 const RtemsTimerReqFireWhen_Context *ctx,
0388 rtems_time_of_day *tod_fire
0389 )
0390 {
0391 rtems_time_of_day tod = tod_now;
0392 int invocations_old = ctx->invocations;
0393 int i;
0394
0395
0396 for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
0397 ClockTick();
0398 }
0399
0400 for ( i = 1; i < 24; ++i ) {
0401 tod.hour = i;
0402 T_rsc_success( rtems_clock_set( &tod ) );
0403 if ( tod_fire != NULL && ctx->invocations > invocations_old ) {
0404 *tod_fire = tod;
0405 break;
0406 }
0407 }
0408 }
0409
0410 static void TimerServiceRoutine(
0411 rtems_id timer_id,
0412 void *user_data
0413 )
0414 {
0415 RtemsTimerReqFireWhen_Context *ctx = user_data;
0416 ++( ctx->invocations );
0417 ctx->routine_user_data = user_data;
0418 }
0419
0420 static void RtemsTimerReqFireWhen_Pre_RtClock_Prepare(
0421 RtemsTimerReqFireWhen_Context *ctx,
0422 RtemsTimerReqFireWhen_Pre_RtClock state
0423 )
0424 {
0425 switch ( state ) {
0426 case RtemsTimerReqFireWhen_Pre_RtClock_Set: {
0427
0428
0429
0430 ctx->pre_cond_tod = &tod_now;
0431 break;
0432 }
0433
0434 case RtemsTimerReqFireWhen_Pre_RtClock_Unset: {
0435
0436
0437
0438 ctx->pre_cond_tod = NULL;
0439 break;
0440 }
0441
0442 case RtemsTimerReqFireWhen_Pre_RtClock_NA:
0443 break;
0444 }
0445 }
0446
0447 static void RtemsTimerReqFireWhen_Pre_Routine_Prepare(
0448 RtemsTimerReqFireWhen_Context *ctx,
0449 RtemsTimerReqFireWhen_Pre_Routine state
0450 )
0451 {
0452 switch ( state ) {
0453 case RtemsTimerReqFireWhen_Pre_Routine_Valid: {
0454
0455
0456
0457
0458 ctx->routine_param = TimerServiceRoutine;
0459 break;
0460 }
0461
0462 case RtemsTimerReqFireWhen_Pre_Routine_Null: {
0463
0464
0465
0466 ctx->routine_param = NULL;
0467 break;
0468 }
0469
0470 case RtemsTimerReqFireWhen_Pre_Routine_NA:
0471 break;
0472 }
0473 }
0474
0475 static void RtemsTimerReqFireWhen_Pre_WallTime_Prepare(
0476 RtemsTimerReqFireWhen_Context *ctx,
0477 RtemsTimerReqFireWhen_Pre_WallTime state
0478 )
0479 {
0480 switch ( state ) {
0481 case RtemsTimerReqFireWhen_Pre_WallTime_Valid: {
0482
0483
0484
0485
0486
0487 ctx->wall_time_param = &tod_schedule;
0488 break;
0489 }
0490
0491 case RtemsTimerReqFireWhen_Pre_WallTime_Invalid: {
0492
0493
0494
0495 ctx->wall_time_param = &tod_invalid;
0496 break;
0497 }
0498
0499 case RtemsTimerReqFireWhen_Pre_WallTime_Past: {
0500
0501
0502
0503
0504
0505 ctx->wall_time_param = &tod_past;
0506 break;
0507 }
0508
0509 case RtemsTimerReqFireWhen_Pre_WallTime_Null: {
0510
0511
0512
0513 ctx->wall_time_param = NULL;
0514 break;
0515 }
0516
0517 case RtemsTimerReqFireWhen_Pre_WallTime_NA:
0518 break;
0519 }
0520 }
0521
0522 static void RtemsTimerReqFireWhen_Pre_Id_Prepare(
0523 RtemsTimerReqFireWhen_Context *ctx,
0524 RtemsTimerReqFireWhen_Pre_Id state
0525 )
0526 {
0527 switch ( state ) {
0528 case RtemsTimerReqFireWhen_Pre_Id_Valid: {
0529
0530
0531
0532 ctx->id_param = ctx->timer_id;
0533 break;
0534 }
0535
0536 case RtemsTimerReqFireWhen_Pre_Id_Invalid: {
0537
0538
0539
0540 ctx->id_param = RTEMS_ID_NONE;
0541 break;
0542 }
0543
0544 case RtemsTimerReqFireWhen_Pre_Id_NA:
0545 break;
0546 }
0547 }
0548
0549 static void RtemsTimerReqFireWhen_Pre_Context_Prepare(
0550 RtemsTimerReqFireWhen_Context *ctx,
0551 RtemsTimerReqFireWhen_Pre_Context state
0552 )
0553 {
0554 switch ( state ) {
0555 case RtemsTimerReqFireWhen_Pre_Context_None: {
0556
0557
0558
0559
0560 ctx->pre_cond_contex = PRE_NONE;
0561 break;
0562 }
0563
0564 case RtemsTimerReqFireWhen_Pre_Context_Interrupt: {
0565
0566
0567
0568 ctx->pre_cond_contex = PRE_INTERRUPT;
0569 break;
0570 }
0571
0572 case RtemsTimerReqFireWhen_Pre_Context_Server: {
0573
0574
0575
0576 ctx->pre_cond_contex = PRE_SERVER;
0577 break;
0578 }
0579
0580 case RtemsTimerReqFireWhen_Pre_Context_NA:
0581 break;
0582 }
0583 }
0584
0585 static void RtemsTimerReqFireWhen_Pre_Clock_Prepare(
0586 RtemsTimerReqFireWhen_Context *ctx,
0587 RtemsTimerReqFireWhen_Pre_Clock state
0588 )
0589 {
0590 switch ( state ) {
0591 case RtemsTimerReqFireWhen_Pre_Clock_None: {
0592
0593
0594
0595 T_eq_int( ctx->pre_cond_contex, PRE_NONE );
0596 break;
0597 }
0598
0599 case RtemsTimerReqFireWhen_Pre_Clock_Ticks: {
0600
0601
0602
0603
0604 rtems_status_code status;
0605
0606 if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0607 status = rtems_timer_fire_after(
0608 ctx->timer_id,
0609 SCHEDULE_SOON,
0610 TimerServiceRoutine,
0611 ctx
0612 );
0613 } else {
0614 status = rtems_timer_server_fire_after(
0615 ctx->timer_id,
0616 SCHEDULE_SOON,
0617 TimerServiceRoutine,
0618 ctx
0619 );
0620 }
0621 T_rsc_success( status );
0622 break;
0623 }
0624
0625 case RtemsTimerReqFireWhen_Pre_Clock_Realtime: {
0626
0627
0628
0629
0630 rtems_status_code status;
0631 T_rsc_success( rtems_clock_set( &tod_now ) );
0632
0633 if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0634 status = rtems_timer_fire_when(
0635 ctx->timer_id,
0636 &tod_schedule,
0637 TimerServiceRoutine,
0638 ctx
0639 );
0640 } else {
0641 status = rtems_timer_server_fire_when(
0642 ctx->timer_id,
0643 &tod_schedule,
0644 TimerServiceRoutine,
0645 ctx
0646 );
0647 }
0648 T_rsc_success( status );
0649 break;
0650 }
0651
0652 case RtemsTimerReqFireWhen_Pre_Clock_NA:
0653 break;
0654 }
0655 }
0656
0657 static void RtemsTimerReqFireWhen_Pre_State_Prepare(
0658 RtemsTimerReqFireWhen_Context *ctx,
0659 RtemsTimerReqFireWhen_Pre_State state
0660 )
0661 {
0662 switch ( state ) {
0663 case RtemsTimerReqFireWhen_Pre_State_Inactive: {
0664
0665
0666
0667 TriggerTimer( ctx, NULL );
0668 T_eq_int(
0669 ctx->invocations,
0670 ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
0671 );
0672 ctx->invocations = 0;
0673 ctx->pre_state = TIMER_INACTIVE;
0674 break;
0675 }
0676
0677 case RtemsTimerReqFireWhen_Pre_State_Scheduled: {
0678
0679
0680
0681
0682 ctx->pre_state = TIMER_SCHEDULED;
0683 break;
0684 }
0685
0686 case RtemsTimerReqFireWhen_Pre_State_Pending: {
0687
0688
0689
0690 T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
0691 TriggerTimer( ctx, NULL );
0692 T_eq_int( ctx->invocations, 0 );
0693 ctx->pre_state = TIMER_PENDING;
0694 break;
0695 }
0696
0697 case RtemsTimerReqFireWhen_Pre_State_NA:
0698 break;
0699 }
0700 }
0701
0702 static void RtemsTimerReqFireWhen_Post_Status_Check(
0703 RtemsTimerReqFireWhen_Context *ctx,
0704 RtemsTimerReqFireWhen_Post_Status state
0705 )
0706 {
0707 switch ( state ) {
0708 case RtemsTimerReqFireWhen_Post_Status_Ok: {
0709
0710
0711
0712
0713 T_rsc_success( ctx->status );
0714 break;
0715 }
0716
0717 case RtemsTimerReqFireWhen_Post_Status_NotDef: {
0718
0719
0720
0721
0722 T_rsc( ctx->status, RTEMS_NOT_DEFINED );
0723 break;
0724 }
0725
0726 case RtemsTimerReqFireWhen_Post_Status_InvId: {
0727
0728
0729
0730
0731 T_rsc( ctx->status, RTEMS_INVALID_ID );
0732 break;
0733 }
0734
0735 case RtemsTimerReqFireWhen_Post_Status_InvAddr: {
0736
0737
0738
0739
0740 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0741 break;
0742 }
0743
0744 case RtemsTimerReqFireWhen_Post_Status_InvClock: {
0745
0746
0747
0748
0749 T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
0750 break;
0751 }
0752
0753 case RtemsTimerReqFireWhen_Post_Status_NA:
0754 break;
0755 }
0756 }
0757
0758 static void RtemsTimerReqFireWhen_Post_Context_Check(
0759 RtemsTimerReqFireWhen_Context *ctx,
0760 RtemsTimerReqFireWhen_Post_Context state
0761 )
0762 {
0763 Timer_Classes class;
0764 class = GetTimerClass( ctx->timer_id );
0765
0766 switch ( state ) {
0767 case RtemsTimerReqFireWhen_Post_Context_None: {
0768
0769
0770
0771 T_eq_int( class, TIMER_DORMANT );
0772 break;
0773 }
0774
0775 case RtemsTimerReqFireWhen_Post_Context_Interrupt: {
0776
0777
0778
0779 T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
0780 break;
0781 }
0782
0783 case RtemsTimerReqFireWhen_Post_Context_Server: {
0784
0785
0786
0787 T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
0788 break;
0789 }
0790
0791 case RtemsTimerReqFireWhen_Post_Context_Nop: {
0792
0793
0794
0795
0796
0797 T_eq_int( class, ctx->pre_class );
0798 break;
0799 }
0800
0801 case RtemsTimerReqFireWhen_Post_Context_NA:
0802 break;
0803 }
0804 }
0805
0806 static void RtemsTimerReqFireWhen_Post_Clock_Check(
0807 RtemsTimerReqFireWhen_Context *ctx,
0808 RtemsTimerReqFireWhen_Post_Clock state
0809 )
0810 {
0811 Timer_Classes class;
0812 class = GetTimerClass( ctx->timer_id );
0813
0814 switch ( state ) {
0815 case RtemsTimerReqFireWhen_Post_Clock_None: {
0816
0817
0818
0819 T_eq_int( class, TIMER_DORMANT );
0820 break;
0821 }
0822
0823 case RtemsTimerReqFireWhen_Post_Clock_Ticks: {
0824
0825
0826
0827 T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
0828 break;
0829 }
0830
0831 case RtemsTimerReqFireWhen_Post_Clock_Realtime: {
0832
0833
0834
0835 T_eq_int(
0836 class & TIMER_CLASS_BIT_TIME_OF_DAY,
0837 TIMER_CLASS_BIT_TIME_OF_DAY
0838 );
0839 break;
0840 }
0841
0842 case RtemsTimerReqFireWhen_Post_Clock_Nop: {
0843
0844
0845
0846
0847
0848 T_eq_int( class, ctx->pre_class );
0849 break;
0850 }
0851
0852 case RtemsTimerReqFireWhen_Post_Clock_NA:
0853 break;
0854 }
0855 }
0856
0857 static void RtemsTimerReqFireWhen_Post_State_Check(
0858 RtemsTimerReqFireWhen_Context *ctx,
0859 RtemsTimerReqFireWhen_Post_State state
0860 )
0861 {
0862 switch ( state ) {
0863 case RtemsTimerReqFireWhen_Post_State_Scheduled: {
0864
0865
0866
0867 TriggerTimer( ctx, &ctx->tod_till_fire );
0868 T_eq_int( ctx->invocations, 1 );
0869 break;
0870 }
0871
0872 case RtemsTimerReqFireWhen_Post_State_Nop: {
0873
0874
0875
0876
0877
0878 T_eq_int( ctx->post_state, ctx->pre_state );
0879 break;
0880 }
0881
0882 case RtemsTimerReqFireWhen_Post_State_NA:
0883 break;
0884 }
0885 }
0886
0887 static void RtemsTimerReqFireWhen_Post_WallTime_Check(
0888 RtemsTimerReqFireWhen_Context *ctx,
0889 RtemsTimerReqFireWhen_Post_WallTime state
0890 )
0891 {
0892 switch ( state ) {
0893 case RtemsTimerReqFireWhen_Post_WallTime_Param: {
0894
0895
0896
0897
0898
0899 T_eq_mem(
0900 &ctx->tod_till_fire,
0901 ctx->wall_time_param,
0902 sizeof( ctx->tod_till_fire )
0903 );
0904 break;
0905 }
0906
0907 case RtemsTimerReqFireWhen_Post_WallTime_Nop: {
0908
0909
0910
0911
0912
0913
0914
0915
0916 T_eq_u32(
0917 ctx->post_scheduling_data.interval,
0918 ctx->pre_scheduling_data.interval
0919 );
0920 break;
0921 }
0922
0923 case RtemsTimerReqFireWhen_Post_WallTime_NA:
0924 break;
0925 }
0926 }
0927
0928 static void RtemsTimerReqFireWhen_Post_Routine_Check(
0929 RtemsTimerReqFireWhen_Context *ctx,
0930 RtemsTimerReqFireWhen_Post_Routine state
0931 )
0932 {
0933 switch ( state ) {
0934 case RtemsTimerReqFireWhen_Post_Routine_Param: {
0935
0936
0937
0938
0939
0940 T_eq_int( ctx->invocations, 1 );
0941 break;
0942 }
0943
0944 case RtemsTimerReqFireWhen_Post_Routine_Nop: {
0945
0946
0947
0948
0949
0950 T_eq_ptr(
0951 ctx->post_scheduling_data.routine,
0952 ctx->pre_scheduling_data.routine
0953 );
0954 break;
0955 }
0956
0957 case RtemsTimerReqFireWhen_Post_Routine_NA:
0958 break;
0959 }
0960 }
0961
0962 static void RtemsTimerReqFireWhen_Post_UserData_Check(
0963 RtemsTimerReqFireWhen_Context *ctx,
0964 RtemsTimerReqFireWhen_Post_UserData state
0965 )
0966 {
0967 switch ( state ) {
0968 case RtemsTimerReqFireWhen_Post_UserData_Param: {
0969
0970
0971
0972
0973
0974 T_eq_ptr( ctx->routine_user_data, ctx );
0975 break;
0976 }
0977
0978 case RtemsTimerReqFireWhen_Post_UserData_Nop: {
0979
0980
0981
0982
0983
0984 T_eq_ptr(
0985 ctx->post_scheduling_data.user_data,
0986 ctx->pre_scheduling_data.user_data
0987 );
0988 break;
0989 }
0990
0991 case RtemsTimerReqFireWhen_Post_UserData_NA:
0992 break;
0993 }
0994 }
0995
0996 static void RtemsTimerReqFireWhen_Setup( RtemsTimerReqFireWhen_Context *ctx )
0997 {
0998 rtems_status_code status;
0999 status = rtems_timer_initiate_server(
1000 RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
1001 RTEMS_MINIMUM_STACK_SIZE,
1002 RTEMS_DEFAULT_ATTRIBUTES
1003 );
1004 T_rsc_success( status );
1005 }
1006
1007 static void RtemsTimerReqFireWhen_Setup_Wrap( void *arg )
1008 {
1009 RtemsTimerReqFireWhen_Context *ctx;
1010
1011 ctx = arg;
1012 ctx->Map.in_action_loop = false;
1013 RtemsTimerReqFireWhen_Setup( ctx );
1014 }
1015
1016
1017
1018
1019
1020 static void RtemsTimerReqFireWhen_Teardown(
1021 RtemsTimerReqFireWhen_Context *ctx
1022 )
1023 {
1024 DeleteTimerServer();
1025 UnsetClock();
1026 }
1027
1028 static void RtemsTimerReqFireWhen_Teardown_Wrap( void *arg )
1029 {
1030 RtemsTimerReqFireWhen_Context *ctx;
1031
1032 ctx = arg;
1033 ctx->Map.in_action_loop = false;
1034 RtemsTimerReqFireWhen_Teardown( ctx );
1035 }
1036
1037 static void RtemsTimerReqFireWhen_Prepare( RtemsTimerReqFireWhen_Context *ctx )
1038 {
1039 rtems_status_code status;
1040 status = rtems_timer_create(
1041 rtems_build_name( 'T', 'I', 'M', 'E' ),
1042 &ctx->timer_id
1043 );
1044 T_rsc_success( status );
1045
1046 ctx->invocations = 0;
1047 ctx->routine_user_data = NULL;
1048 }
1049
1050 static void RtemsTimerReqFireWhen_Action( RtemsTimerReqFireWhen_Context *ctx )
1051 {
1052 GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
1053 ctx->pre_class = GetTimerClass( ctx->timer_id );
1054 if ( ctx->pre_cond_tod == NULL ) {
1055 UnsetClock();
1056 } else {
1057 T_rsc_success( rtems_clock_set( ctx->pre_cond_tod ) );
1058 }
1059 ctx->status = rtems_timer_fire_when(
1060 ctx->id_param,
1061 ctx->wall_time_param,
1062 ctx->routine_param,
1063 ctx
1064 );
1065 ctx->post_state = GetTimerState( ctx->timer_id );
1066 GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
1067
1068 rtems_task_resume( GetTimerServerTaskId() );
1069 }
1070
1071 static void RtemsTimerReqFireWhen_Cleanup( RtemsTimerReqFireWhen_Context *ctx )
1072 {
1073 T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
1074 }
1075
1076 static const RtemsTimerReqFireWhen_Entry
1077 RtemsTimerReqFireWhen_Entries[] = {
1078 { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NA,
1079 RtemsTimerReqFireWhen_Post_Context_NA, RtemsTimerReqFireWhen_Post_Clock_NA,
1080 RtemsTimerReqFireWhen_Post_State_NA,
1081 RtemsTimerReqFireWhen_Post_WallTime_NA,
1082 RtemsTimerReqFireWhen_Post_Routine_NA,
1083 RtemsTimerReqFireWhen_Post_UserData_NA },
1084 { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvAddr,
1085 RtemsTimerReqFireWhen_Post_Context_Nop,
1086 RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
1087 RtemsTimerReqFireWhen_Post_WallTime_Nop,
1088 RtemsTimerReqFireWhen_Post_Routine_Nop,
1089 RtemsTimerReqFireWhen_Post_UserData_Nop },
1090 { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NotDef,
1091 RtemsTimerReqFireWhen_Post_Context_Nop,
1092 RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
1093 RtemsTimerReqFireWhen_Post_WallTime_Nop,
1094 RtemsTimerReqFireWhen_Post_Routine_Nop,
1095 RtemsTimerReqFireWhen_Post_UserData_Nop },
1096 { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NA,
1097 RtemsTimerReqFireWhen_Post_Context_NA, RtemsTimerReqFireWhen_Post_Clock_NA,
1098 RtemsTimerReqFireWhen_Post_State_NA,
1099 RtemsTimerReqFireWhen_Post_WallTime_NA,
1100 RtemsTimerReqFireWhen_Post_Routine_NA,
1101 RtemsTimerReqFireWhen_Post_UserData_NA },
1102 { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvClock,
1103 RtemsTimerReqFireWhen_Post_Context_Nop,
1104 RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
1105 RtemsTimerReqFireWhen_Post_WallTime_Nop,
1106 RtemsTimerReqFireWhen_Post_Routine_Nop,
1107 RtemsTimerReqFireWhen_Post_UserData_Nop },
1108 { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_Ok,
1109 RtemsTimerReqFireWhen_Post_Context_Interrupt,
1110 RtemsTimerReqFireWhen_Post_Clock_Realtime,
1111 RtemsTimerReqFireWhen_Post_State_Scheduled,
1112 RtemsTimerReqFireWhen_Post_WallTime_Param,
1113 RtemsTimerReqFireWhen_Post_Routine_Param,
1114 RtemsTimerReqFireWhen_Post_UserData_Param },
1115 { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvId,
1116 RtemsTimerReqFireWhen_Post_Context_Nop,
1117 RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
1118 RtemsTimerReqFireWhen_Post_WallTime_Nop,
1119 RtemsTimerReqFireWhen_Post_Routine_Nop,
1120 RtemsTimerReqFireWhen_Post_UserData_Nop }
1121 };
1122
1123 static const uint8_t
1124 RtemsTimerReqFireWhen_Map[] = {
1125 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5,
1126 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6, 6,
1127 6, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4,
1128 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4,
1129 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4,
1130 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0,
1131 4, 4, 4, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0,
1132 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
1133 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
1134 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1,
1135 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
1136 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
1137 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1138 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1139 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1140 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1141 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1142 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0,
1143 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
1144 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0,
1145 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0,
1146 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0,
1147 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0,
1148 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0,
1149 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0,
1150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2,
1151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3,
1152 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3,
1153 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3,
1154 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2,
1155 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2,
1156 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2,
1157 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0,
1158 2, 2, 2, 3, 3, 3
1159 };
1160
1161 static size_t RtemsTimerReqFireWhen_Scope( void *arg, char *buf, size_t n )
1162 {
1163 RtemsTimerReqFireWhen_Context *ctx;
1164
1165 ctx = arg;
1166
1167 if ( ctx->Map.in_action_loop ) {
1168 return T_get_scope( RtemsTimerReqFireWhen_PreDesc, buf, n, ctx->Map.pcs );
1169 }
1170
1171 return 0;
1172 }
1173
1174 static T_fixture RtemsTimerReqFireWhen_Fixture = {
1175 .setup = RtemsTimerReqFireWhen_Setup_Wrap,
1176 .stop = NULL,
1177 .teardown = RtemsTimerReqFireWhen_Teardown_Wrap,
1178 .scope = RtemsTimerReqFireWhen_Scope,
1179 .initial_context = &RtemsTimerReqFireWhen_Instance
1180 };
1181
1182 static inline RtemsTimerReqFireWhen_Entry RtemsTimerReqFireWhen_PopEntry(
1183 RtemsTimerReqFireWhen_Context *ctx
1184 )
1185 {
1186 size_t index;
1187
1188 index = ctx->Map.index;
1189 ctx->Map.index = index + 1;
1190 return RtemsTimerReqFireWhen_Entries[
1191 RtemsTimerReqFireWhen_Map[ index ]
1192 ];
1193 }
1194
1195 static void RtemsTimerReqFireWhen_TestVariant(
1196 RtemsTimerReqFireWhen_Context *ctx
1197 )
1198 {
1199 RtemsTimerReqFireWhen_Pre_RtClock_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1200 RtemsTimerReqFireWhen_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1201 RtemsTimerReqFireWhen_Pre_WallTime_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1202 RtemsTimerReqFireWhen_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1203 RtemsTimerReqFireWhen_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1204 RtemsTimerReqFireWhen_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1205 RtemsTimerReqFireWhen_Pre_State_Prepare( ctx, ctx->Map.pcs[ 6 ] );
1206 RtemsTimerReqFireWhen_Action( ctx );
1207 RtemsTimerReqFireWhen_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1208 RtemsTimerReqFireWhen_Post_Context_Check( ctx, ctx->Map.entry.Post_Context );
1209 RtemsTimerReqFireWhen_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
1210 RtemsTimerReqFireWhen_Post_State_Check( ctx, ctx->Map.entry.Post_State );
1211 RtemsTimerReqFireWhen_Post_WallTime_Check(
1212 ctx,
1213 ctx->Map.entry.Post_WallTime
1214 );
1215 RtemsTimerReqFireWhen_Post_Routine_Check( ctx, ctx->Map.entry.Post_Routine );
1216 RtemsTimerReqFireWhen_Post_UserData_Check(
1217 ctx,
1218 ctx->Map.entry.Post_UserData
1219 );
1220 }
1221
1222
1223
1224
1225 T_TEST_CASE_FIXTURE( RtemsTimerReqFireWhen, &RtemsTimerReqFireWhen_Fixture )
1226 {
1227 RtemsTimerReqFireWhen_Context *ctx;
1228
1229 ctx = T_fixture_context();
1230 ctx->Map.in_action_loop = true;
1231 ctx->Map.index = 0;
1232
1233 for (
1234 ctx->Map.pcs[ 0 ] = RtemsTimerReqFireWhen_Pre_RtClock_Set;
1235 ctx->Map.pcs[ 0 ] < RtemsTimerReqFireWhen_Pre_RtClock_NA;
1236 ++ctx->Map.pcs[ 0 ]
1237 ) {
1238 for (
1239 ctx->Map.pcs[ 1 ] = RtemsTimerReqFireWhen_Pre_Routine_Valid;
1240 ctx->Map.pcs[ 1 ] < RtemsTimerReqFireWhen_Pre_Routine_NA;
1241 ++ctx->Map.pcs[ 1 ]
1242 ) {
1243 for (
1244 ctx->Map.pcs[ 2 ] = RtemsTimerReqFireWhen_Pre_WallTime_Valid;
1245 ctx->Map.pcs[ 2 ] < RtemsTimerReqFireWhen_Pre_WallTime_NA;
1246 ++ctx->Map.pcs[ 2 ]
1247 ) {
1248 for (
1249 ctx->Map.pcs[ 3 ] = RtemsTimerReqFireWhen_Pre_Id_Valid;
1250 ctx->Map.pcs[ 3 ] < RtemsTimerReqFireWhen_Pre_Id_NA;
1251 ++ctx->Map.pcs[ 3 ]
1252 ) {
1253 for (
1254 ctx->Map.pcs[ 4 ] = RtemsTimerReqFireWhen_Pre_Context_None;
1255 ctx->Map.pcs[ 4 ] < RtemsTimerReqFireWhen_Pre_Context_NA;
1256 ++ctx->Map.pcs[ 4 ]
1257 ) {
1258 for (
1259 ctx->Map.pcs[ 5 ] = RtemsTimerReqFireWhen_Pre_Clock_None;
1260 ctx->Map.pcs[ 5 ] < RtemsTimerReqFireWhen_Pre_Clock_NA;
1261 ++ctx->Map.pcs[ 5 ]
1262 ) {
1263 for (
1264 ctx->Map.pcs[ 6 ] = RtemsTimerReqFireWhen_Pre_State_Inactive;
1265 ctx->Map.pcs[ 6 ] < RtemsTimerReqFireWhen_Pre_State_NA;
1266 ++ctx->Map.pcs[ 6 ]
1267 ) {
1268 ctx->Map.entry = RtemsTimerReqFireWhen_PopEntry( ctx );
1269
1270 if ( ctx->Map.entry.Skip ) {
1271 continue;
1272 }
1273
1274 RtemsTimerReqFireWhen_Prepare( ctx );
1275 RtemsTimerReqFireWhen_TestVariant( ctx );
1276 RtemsTimerReqFireWhen_Cleanup( ctx );
1277 }
1278 }
1279 }
1280 }
1281 }
1282 }
1283 }
1284 }
1285
1286