File indexing completed on 2025-05-11 08:24:52
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
0070 typedef enum {
0071 RtemsRatemonReqPeriod_Pre_Id_Valid,
0072 RtemsRatemonReqPeriod_Pre_Id_Invalid,
0073 RtemsRatemonReqPeriod_Pre_Id_NA
0074 } RtemsRatemonReqPeriod_Pre_Id;
0075
0076 typedef enum {
0077 RtemsRatemonReqPeriod_Pre_Caller_OwnerTask,
0078 RtemsRatemonReqPeriod_Pre_Caller_OtherTask,
0079 RtemsRatemonReqPeriod_Pre_Caller_NA
0080 } RtemsRatemonReqPeriod_Pre_Caller;
0081
0082 typedef enum {
0083 RtemsRatemonReqPeriod_Pre_Length_Ticks,
0084 RtemsRatemonReqPeriod_Pre_Length_Status,
0085 RtemsRatemonReqPeriod_Pre_Length_NA
0086 } RtemsRatemonReqPeriod_Pre_Length;
0087
0088 typedef enum {
0089 RtemsRatemonReqPeriod_Pre_State_Inactive,
0090 RtemsRatemonReqPeriod_Pre_State_Active,
0091 RtemsRatemonReqPeriod_Pre_State_Expired,
0092 RtemsRatemonReqPeriod_Pre_State_NA
0093 } RtemsRatemonReqPeriod_Pre_State;
0094
0095 typedef enum {
0096 RtemsRatemonReqPeriod_Pre_Postponed_Zero,
0097 RtemsRatemonReqPeriod_Pre_Postponed_One,
0098 RtemsRatemonReqPeriod_Pre_Postponed_Several,
0099 RtemsRatemonReqPeriod_Pre_Postponed_NA
0100 } RtemsRatemonReqPeriod_Pre_Postponed;
0101
0102 typedef enum {
0103 RtemsRatemonReqPeriod_Pre_InactiveCause_New,
0104 RtemsRatemonReqPeriod_Pre_InactiveCause_Canceled,
0105 RtemsRatemonReqPeriod_Pre_InactiveCause_NA
0106 } RtemsRatemonReqPeriod_Pre_InactiveCause;
0107
0108 typedef enum {
0109 RtemsRatemonReqPeriod_Post_Status_Ok,
0110 RtemsRatemonReqPeriod_Post_Status_InvId,
0111 RtemsRatemonReqPeriod_Post_Status_NotOwn,
0112 RtemsRatemonReqPeriod_Post_Status_NotDef,
0113 RtemsRatemonReqPeriod_Post_Status_TimeOut,
0114 RtemsRatemonReqPeriod_Post_Status_NA
0115 } RtemsRatemonReqPeriod_Post_Status;
0116
0117 typedef enum {
0118 RtemsRatemonReqPeriod_Post_State_Inactive,
0119 RtemsRatemonReqPeriod_Post_State_Active,
0120 RtemsRatemonReqPeriod_Post_State_Expired,
0121 RtemsRatemonReqPeriod_Post_State_Nop,
0122 RtemsRatemonReqPeriod_Post_State_NA
0123 } RtemsRatemonReqPeriod_Post_State;
0124
0125 typedef enum {
0126 RtemsRatemonReqPeriod_Post_Postponed_Zero,
0127 RtemsRatemonReqPeriod_Post_Postponed_OneOrMore,
0128 RtemsRatemonReqPeriod_Post_Postponed_Nop,
0129 RtemsRatemonReqPeriod_Post_Postponed_NA
0130 } RtemsRatemonReqPeriod_Post_Postponed;
0131
0132 typedef enum {
0133 RtemsRatemonReqPeriod_Post_Delay_None,
0134 RtemsRatemonReqPeriod_Post_Delay_TillDeadline,
0135 RtemsRatemonReqPeriod_Post_Delay_NA
0136 } RtemsRatemonReqPeriod_Post_Delay;
0137
0138 typedef enum {
0139 RtemsRatemonReqPeriod_Post_Scheduler_Called,
0140 RtemsRatemonReqPeriod_Post_Scheduler_Nop,
0141 RtemsRatemonReqPeriod_Post_Scheduler_NA
0142 } RtemsRatemonReqPeriod_Post_Scheduler;
0143
0144 typedef struct {
0145 uint32_t Skip : 1;
0146 uint32_t Pre_Id_NA : 1;
0147 uint32_t Pre_Caller_NA : 1;
0148 uint32_t Pre_Length_NA : 1;
0149 uint32_t Pre_State_NA : 1;
0150 uint32_t Pre_Postponed_NA : 1;
0151 uint32_t Pre_InactiveCause_NA : 1;
0152 uint32_t Post_Status : 3;
0153 uint32_t Post_State : 3;
0154 uint32_t Post_Postponed : 2;
0155 uint32_t Post_Delay : 2;
0156 uint32_t Post_Scheduler : 2;
0157 } RtemsRatemonReqPeriod_Entry;
0158
0159
0160
0161
0162 typedef struct {
0163
0164
0165
0166 rtems_id period_id;
0167
0168
0169
0170
0171
0172 rtems_rate_monotonic_period_status period_status;
0173
0174
0175
0176
0177 rtems_id id_param;
0178
0179
0180
0181
0182 rtems_interval length_param;
0183
0184
0185
0186
0187 rtems_status_code status;
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 uint32_t ( *do_action )( void *ctx, void (*todo)( void *ctx_arg ) );
0198
0199
0200
0201
0202
0203
0204 void (*worker_todo)( void *ctx );
0205
0206
0207
0208
0209 rtems_id task_id;
0210
0211
0212
0213
0214
0215 rtems_id worker_id;
0216
0217
0218
0219
0220
0221 rtems_id original_priority;
0222
0223
0224
0225
0226
0227 uint32_t postponed_jobs_count;
0228
0229
0230
0231
0232 rtems_rate_monotonic_period_states previous_state;
0233
0234
0235
0236
0237
0238 uint32_t test_duration;
0239
0240
0241
0242
0243
0244
0245 uint32_t test_duration_till_action;
0246
0247
0248
0249
0250
0251 uint32_t period_calls;
0252
0253
0254
0255
0256
0257 uint32_t action_duration;
0258
0259 struct {
0260
0261
0262
0263
0264 size_t pci[ 6 ];
0265
0266
0267
0268
0269 size_t pcs[ 6 ];
0270
0271
0272
0273
0274 bool in_action_loop;
0275
0276
0277
0278
0279 size_t index;
0280
0281
0282
0283
0284 RtemsRatemonReqPeriod_Entry entry;
0285
0286
0287
0288
0289
0290 bool skip;
0291 } Map;
0292 } RtemsRatemonReqPeriod_Context;
0293
0294 static RtemsRatemonReqPeriod_Context
0295 RtemsRatemonReqPeriod_Instance;
0296
0297 static const char * const RtemsRatemonReqPeriod_PreDesc_Id[] = {
0298 "Valid",
0299 "Invalid",
0300 "NA"
0301 };
0302
0303 static const char * const RtemsRatemonReqPeriod_PreDesc_Caller[] = {
0304 "OwnerTask",
0305 "OtherTask",
0306 "NA"
0307 };
0308
0309 static const char * const RtemsRatemonReqPeriod_PreDesc_Length[] = {
0310 "Ticks",
0311 "Status",
0312 "NA"
0313 };
0314
0315 static const char * const RtemsRatemonReqPeriod_PreDesc_State[] = {
0316 "Inactive",
0317 "Active",
0318 "Expired",
0319 "NA"
0320 };
0321
0322 static const char * const RtemsRatemonReqPeriod_PreDesc_Postponed[] = {
0323 "Zero",
0324 "One",
0325 "Several",
0326 "NA"
0327 };
0328
0329 static const char * const RtemsRatemonReqPeriod_PreDesc_InactiveCause[] = {
0330 "New",
0331 "Canceled",
0332 "NA"
0333 };
0334
0335 static const char * const * const RtemsRatemonReqPeriod_PreDesc[] = {
0336 RtemsRatemonReqPeriod_PreDesc_Id,
0337 RtemsRatemonReqPeriod_PreDesc_Caller,
0338 RtemsRatemonReqPeriod_PreDesc_Length,
0339 RtemsRatemonReqPeriod_PreDesc_State,
0340 RtemsRatemonReqPeriod_PreDesc_Postponed,
0341 RtemsRatemonReqPeriod_PreDesc_InactiveCause,
0342 NULL
0343 };
0344
0345 static const rtems_interval period_length = 5;
0346 static const rtems_task_priority background_task_priority = 100;
0347 static const rtems_task_priority foreground_task_priority = 10;
0348 static const rtems_event_set wake_main_task_event = RTEMS_EVENT_17;
0349
0350 static void TickTheClock(
0351 RtemsRatemonReqPeriod_Context *ctx,
0352 uint32_t ticks
0353 )
0354 {
0355 uint32_t i;
0356 for ( i = 0; i < ticks; ++i ) {
0357 TimecounterTick();
0358 ctx->test_duration++;
0359 }
0360 }
0361
0362 static rtems_status_code CallPeriodFunction(
0363 RtemsRatemonReqPeriod_Context *ctx,
0364 rtems_id id,
0365 rtems_interval length
0366 )
0367 {
0368 rtems_status_code status;
0369 status = rtems_rate_monotonic_period( id, length );
0370 ctx->period_calls++;
0371 return status;
0372 }
0373
0374 static void CreatePeriod( void *ctx_in )
0375 {
0376 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0377 rtems_status_code status;
0378 status = rtems_rate_monotonic_create(
0379 rtems_build_name( 'R', 'M', 'O', 'N' ),
0380 &ctx->period_id
0381 );
0382 T_rsc_success( status );
0383 }
0384
0385 static void DeletePeriod( void *ctx_in )
0386 {
0387 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0388 T_rsc_success( rtems_rate_monotonic_delete( ctx->period_id ) );
0389 }
0390
0391 static void CancelPeriod( void *ctx_in )
0392 {
0393 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0394 T_rsc_success( rtems_rate_monotonic_cancel( ctx->period_id ) );
0395 }
0396
0397 static void CallPeriod( void *ctx_in )
0398 {
0399 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0400 T_rsc_success( CallPeriodFunction( ctx, ctx->period_id, period_length ) );
0401 }
0402
0403 static void CallPeriodTimeout( void *ctx_in )
0404 {
0405 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0406 rtems_status_code status;
0407 status = CallPeriodFunction( ctx, ctx->period_id, period_length );
0408 T_rsc( status, RTEMS_TIMEOUT );
0409 }
0410
0411 static void DoAction( void *ctx_in )
0412 {
0413 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0414 ctx->status = CallPeriodFunction( ctx, ctx->id_param, ctx->length_param );
0415 }
0416
0417 static void WorkerTask( rtems_task_argument argument )
0418 {
0419 RtemsRatemonReqPeriod_Context *ctx =
0420 (RtemsRatemonReqPeriod_Context *) argument;
0421 if ( ctx != NULL ) {
0422 ctx->worker_todo( ctx );
0423 T_rsc_success( rtems_event_send( ctx->task_id, wake_main_task_event ) );
0424 }
0425 T_rsc_success( rtems_task_suspend( RTEMS_SELF ) );
0426 }
0427
0428 static uint32_t OwnerDoWork( void *ctx_in, void (*todo)( void *ctx_arg ) )
0429 {
0430 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0431 uint32_t ticks_to_wait = period_length + 1;
0432 rtems_status_code status;
0433 rtems_event_set event_set;
0434
0435 ctx->worker_todo = todo;
0436 status = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
0437 T_rsc_success( status );
0438
0439 for ( ; ticks_to_wait > 0; --ticks_to_wait ) {
0440
0441 status = rtems_event_receive(
0442 RTEMS_PENDING_EVENTS,
0443 RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
0444 RTEMS_NO_TIMEOUT,
0445 &event_set
0446 );
0447 T_rsc_success( status );
0448
0449 if ( ( event_set & wake_main_task_event ) == wake_main_task_event ) {
0450 break;
0451 }
0452 TickTheClock( ctx, 1 );
0453 }
0454
0455
0456 status = rtems_event_receive(
0457 wake_main_task_event,
0458 RTEMS_DEFAULT_OPTIONS,
0459 RTEMS_NO_TIMEOUT,
0460 &event_set
0461 );
0462 T_rsc_success( status );
0463
0464 return period_length + 1 - ticks_to_wait;
0465 }
0466
0467 static uint32_t OtherDoWork( void *ctx_in, void (*todo)( void *ctx_arg ) )
0468 {
0469 RtemsRatemonReqPeriod_Context *ctx = ctx_in;
0470 todo( ctx );
0471
0472 return 0;
0473 }
0474
0475 static void CreatePostponedJobs(
0476 RtemsRatemonReqPeriod_Context *ctx,
0477 uint32_t jobs_count
0478 )
0479 {
0480 ctx->postponed_jobs_count = jobs_count;
0481 if ( ctx->previous_state == RATE_MONOTONIC_ACTIVE ) {
0482 TickTheClock( ctx, ( jobs_count + 1 ) * period_length );
0483 OwnerDoWork( ctx, CallPeriodTimeout );
0484 } else {
0485
0486 TickTheClock( ctx, jobs_count * period_length );
0487 }
0488 }
0489
0490 static void RtemsRatemonReqPeriod_Pre_Id_Prepare(
0491 RtemsRatemonReqPeriod_Context *ctx,
0492 RtemsRatemonReqPeriod_Pre_Id state
0493 )
0494 {
0495 switch ( state ) {
0496 case RtemsRatemonReqPeriod_Pre_Id_Valid: {
0497
0498
0499
0500 ctx->id_param = ctx->period_id;
0501 break;
0502 }
0503
0504 case RtemsRatemonReqPeriod_Pre_Id_Invalid: {
0505
0506
0507
0508 ctx->id_param = RTEMS_ID_NONE;
0509 break;
0510 }
0511
0512 case RtemsRatemonReqPeriod_Pre_Id_NA:
0513 break;
0514 }
0515 }
0516
0517 static void RtemsRatemonReqPeriod_Pre_Caller_Prepare(
0518 RtemsRatemonReqPeriod_Context *ctx,
0519 RtemsRatemonReqPeriod_Pre_Caller state
0520 )
0521 {
0522 switch ( state ) {
0523 case RtemsRatemonReqPeriod_Pre_Caller_OwnerTask: {
0524
0525
0526
0527
0528 ctx->do_action = OwnerDoWork;
0529 break;
0530 }
0531
0532 case RtemsRatemonReqPeriod_Pre_Caller_OtherTask: {
0533
0534
0535
0536
0537 ctx->do_action = OtherDoWork;
0538 break;
0539 }
0540
0541 case RtemsRatemonReqPeriod_Pre_Caller_NA:
0542 break;
0543 }
0544 }
0545
0546 static void RtemsRatemonReqPeriod_Pre_Length_Prepare(
0547 RtemsRatemonReqPeriod_Context *ctx,
0548 RtemsRatemonReqPeriod_Pre_Length state
0549 )
0550 {
0551 switch ( state ) {
0552 case RtemsRatemonReqPeriod_Pre_Length_Ticks: {
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 ctx->length_param = period_length;
0565 break;
0566 }
0567
0568 case RtemsRatemonReqPeriod_Pre_Length_Status: {
0569
0570
0571
0572 ctx->length_param = RTEMS_PERIOD_STATUS;
0573 break;
0574 }
0575
0576 case RtemsRatemonReqPeriod_Pre_Length_NA:
0577 break;
0578 }
0579 }
0580
0581 static void RtemsRatemonReqPeriod_Pre_State_Prepare(
0582 RtemsRatemonReqPeriod_Context *ctx,
0583 RtemsRatemonReqPeriod_Pre_State state
0584 )
0585 {
0586 switch ( state ) {
0587 case RtemsRatemonReqPeriod_Pre_State_Inactive: {
0588
0589
0590
0591
0592
0593 ctx->previous_state = RATE_MONOTONIC_INACTIVE;
0594 break;
0595 }
0596
0597 case RtemsRatemonReqPeriod_Pre_State_Active: {
0598
0599
0600
0601
0602 OwnerDoWork( ctx, CallPeriod );
0603 ctx->previous_state = RATE_MONOTONIC_ACTIVE;
0604 break;
0605 }
0606
0607 case RtemsRatemonReqPeriod_Pre_State_Expired: {
0608
0609
0610
0611
0612 OwnerDoWork( ctx, CallPeriod );
0613 ctx->previous_state = RATE_MONOTONIC_EXPIRED;
0614 break;
0615 }
0616
0617 case RtemsRatemonReqPeriod_Pre_State_NA:
0618 break;
0619 }
0620 }
0621
0622 static void RtemsRatemonReqPeriod_Pre_Postponed_Prepare(
0623 RtemsRatemonReqPeriod_Context *ctx,
0624 RtemsRatemonReqPeriod_Pre_Postponed state
0625 )
0626 {
0627 switch ( state ) {
0628 case RtemsRatemonReqPeriod_Pre_Postponed_Zero: {
0629
0630
0631
0632 ctx->postponed_jobs_count = 0;
0633 break;
0634 }
0635
0636 case RtemsRatemonReqPeriod_Pre_Postponed_One: {
0637
0638
0639
0640 CreatePostponedJobs( ctx, 1 );
0641 break;
0642 }
0643
0644 case RtemsRatemonReqPeriod_Pre_Postponed_Several: {
0645
0646
0647
0648 CreatePostponedJobs( ctx, 5 );
0649 break;
0650 }
0651
0652 case RtemsRatemonReqPeriod_Pre_Postponed_NA:
0653 break;
0654 }
0655 }
0656
0657 static void RtemsRatemonReqPeriod_Pre_InactiveCause_Prepare(
0658 RtemsRatemonReqPeriod_Context *ctx,
0659 RtemsRatemonReqPeriod_Pre_InactiveCause state
0660 )
0661 {
0662 switch ( state ) {
0663 case RtemsRatemonReqPeriod_Pre_InactiveCause_New: {
0664
0665
0666
0667
0668
0669
0670 ctx->postponed_jobs_count = 0;
0671 break;
0672 }
0673
0674 case RtemsRatemonReqPeriod_Pre_InactiveCause_Canceled: {
0675
0676
0677
0678
0679
0680
0681 if ( ctx->period_calls == 0 ) {
0682 OwnerDoWork( ctx, CallPeriod );
0683 TickTheClock( ctx, ctx->postponed_jobs_count * period_length );
0684 }
0685 OwnerDoWork( ctx, CancelPeriod );
0686 ctx->postponed_jobs_count = 0;
0687 break;
0688 }
0689
0690 case RtemsRatemonReqPeriod_Pre_InactiveCause_NA:
0691 break;
0692 }
0693 }
0694
0695 static void RtemsRatemonReqPeriod_Post_Status_Check(
0696 RtemsRatemonReqPeriod_Context *ctx,
0697 RtemsRatemonReqPeriod_Post_Status state
0698 )
0699 {
0700 switch ( state ) {
0701 case RtemsRatemonReqPeriod_Post_Status_Ok: {
0702
0703
0704
0705
0706 T_rsc_success( ctx->status );
0707 break;
0708 }
0709
0710 case RtemsRatemonReqPeriod_Post_Status_InvId: {
0711
0712
0713
0714
0715 T_rsc( ctx->status, RTEMS_INVALID_ID );
0716 break;
0717 }
0718
0719 case RtemsRatemonReqPeriod_Post_Status_NotOwn: {
0720
0721
0722
0723
0724 T_rsc( ctx->status, RTEMS_NOT_OWNER_OF_RESOURCE );
0725 break;
0726 }
0727
0728 case RtemsRatemonReqPeriod_Post_Status_NotDef: {
0729
0730
0731
0732
0733 T_rsc( ctx->status, RTEMS_NOT_DEFINED );
0734 break;
0735 }
0736
0737 case RtemsRatemonReqPeriod_Post_Status_TimeOut: {
0738
0739
0740
0741
0742 T_rsc( ctx->status, RTEMS_TIMEOUT );
0743 break;
0744 }
0745
0746 case RtemsRatemonReqPeriod_Post_Status_NA:
0747 break;
0748 }
0749 }
0750
0751 static void RtemsRatemonReqPeriod_Post_State_Check(
0752 RtemsRatemonReqPeriod_Context *ctx,
0753 RtemsRatemonReqPeriod_Post_State state
0754 )
0755 {
0756 switch ( state ) {
0757 case RtemsRatemonReqPeriod_Post_State_Inactive: {
0758
0759
0760
0761
0762 T_eq_int( ctx->period_status.state, RATE_MONOTONIC_INACTIVE );
0763 break;
0764 }
0765
0766 case RtemsRatemonReqPeriod_Post_State_Active: {
0767
0768
0769
0770
0771 T_eq_int( ctx->period_status.state, RATE_MONOTONIC_ACTIVE );
0772 break;
0773 }
0774
0775 case RtemsRatemonReqPeriod_Post_State_Expired: {
0776
0777
0778
0779
0780 T_eq_int( ctx->period_status.state, RATE_MONOTONIC_EXPIRED );
0781 break;
0782 }
0783
0784 case RtemsRatemonReqPeriod_Post_State_Nop: {
0785
0786
0787
0788
0789
0790 T_eq_u32( ctx->period_status.state, ctx->previous_state );
0791 break;
0792 }
0793
0794 case RtemsRatemonReqPeriod_Post_State_NA:
0795 break;
0796 }
0797 }
0798
0799 static void RtemsRatemonReqPeriod_Post_Postponed_Check(
0800 RtemsRatemonReqPeriod_Context *ctx,
0801 RtemsRatemonReqPeriod_Post_Postponed state
0802 )
0803 {
0804 switch ( state ) {
0805 case RtemsRatemonReqPeriod_Post_Postponed_Zero: {
0806
0807
0808
0809
0810 T_eq_u32( ctx->period_status.postponed_jobs_count, 0 );
0811 break;
0812 }
0813
0814 case RtemsRatemonReqPeriod_Post_Postponed_OneOrMore: {
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824 T_eq_u32(
0825 ctx->period_status.postponed_jobs_count,
0826 ( ctx->test_duration / period_length + 1 ) - ctx->period_calls
0827 );
0828 break;
0829 }
0830
0831 case RtemsRatemonReqPeriod_Post_Postponed_Nop: {
0832
0833
0834
0835
0836
0837 T_eq_u32(
0838 ctx->period_status.postponed_jobs_count,
0839 ctx->postponed_jobs_count
0840 );
0841 break;
0842 }
0843
0844 case RtemsRatemonReqPeriod_Post_Postponed_NA:
0845 break;
0846 }
0847 }
0848
0849 static void RtemsRatemonReqPeriod_Post_Delay_Check(
0850 RtemsRatemonReqPeriod_Context *ctx,
0851 RtemsRatemonReqPeriod_Post_Delay state
0852 )
0853 {
0854 switch ( state ) {
0855 case RtemsRatemonReqPeriod_Post_Delay_None: {
0856
0857
0858
0859
0860 T_eq_u32( ctx->action_duration, 0 );
0861 break;
0862 }
0863
0864 case RtemsRatemonReqPeriod_Post_Delay_TillDeadline: {
0865
0866
0867
0868
0869 T_eq_u32(
0870 ctx->action_duration,
0871 ( ctx->test_duration_till_action % period_length + 1 ) * period_length -
0872 ctx->test_duration_till_action
0873 );
0874 break;
0875 }
0876
0877 case RtemsRatemonReqPeriod_Post_Delay_NA:
0878 break;
0879 }
0880 }
0881
0882 static void RtemsRatemonReqPeriod_Post_Scheduler_Check(
0883 RtemsRatemonReqPeriod_Context *ctx,
0884 RtemsRatemonReqPeriod_Post_Scheduler state
0885 )
0886 {
0887 switch ( state ) {
0888 case RtemsRatemonReqPeriod_Post_Scheduler_Called: {
0889
0890
0891
0892
0893
0894 break;
0895 }
0896
0897 case RtemsRatemonReqPeriod_Post_Scheduler_Nop: {
0898
0899
0900
0901
0902
0903 break;
0904 }
0905
0906 case RtemsRatemonReqPeriod_Post_Scheduler_NA:
0907 break;
0908 }
0909 }
0910
0911 static void RtemsRatemonReqPeriod_Setup( RtemsRatemonReqPeriod_Context *ctx )
0912 {
0913 rtems_status_code status;
0914 rtems_task_priority priority;
0915 rtems_event_set event_set;
0916 ctx->worker_id = RTEMS_INVALID_ID;
0917
0918 status = rtems_task_ident(
0919 RTEMS_SELF,
0920 RTEMS_SEARCH_ALL_NODES,
0921 &ctx->task_id
0922 );
0923 T_rsc_success( status );
0924
0925 status = rtems_task_set_priority(
0926 RTEMS_SELF,
0927 RTEMS_CURRENT_PRIORITY,
0928 &ctx->original_priority
0929 );
0930 T_rsc_success( status );
0931
0932 status = rtems_task_set_priority(
0933 RTEMS_SELF,
0934 background_task_priority,
0935 &priority
0936 );
0937 T_rsc_success( status );
0938
0939 status = rtems_task_create(
0940 rtems_build_name( 'W', 'O', 'R', 'K' ),
0941 foreground_task_priority,
0942 RTEMS_MINIMUM_STACK_SIZE,
0943 RTEMS_DEFAULT_MODES,
0944 RTEMS_DEFAULT_ATTRIBUTES,
0945 &ctx->worker_id
0946 );
0947 T_rsc_success( status );
0948
0949
0950 status = rtems_event_receive(
0951 RTEMS_ALL_EVENTS,
0952 RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
0953 RTEMS_NO_TIMEOUT,
0954 &event_set
0955 );
0956 T_true( status == RTEMS_SUCCESSFUL || status == RTEMS_UNSATISFIED );
0957
0958 status = rtems_task_start(
0959 ctx->worker_id,
0960 WorkerTask,
0961 (rtems_task_argument) NULL
0962 );
0963 T_rsc_success( status );
0964 }
0965
0966 static void RtemsRatemonReqPeriod_Setup_Wrap( void *arg )
0967 {
0968 RtemsRatemonReqPeriod_Context *ctx;
0969
0970 ctx = arg;
0971 ctx->Map.in_action_loop = false;
0972 RtemsRatemonReqPeriod_Setup( ctx );
0973 }
0974
0975 static void RtemsRatemonReqPeriod_Teardown(
0976 RtemsRatemonReqPeriod_Context *ctx
0977 )
0978 {
0979 rtems_status_code status;
0980 rtems_task_priority priority;
0981
0982 T_rsc_success( rtems_task_delete( ctx->worker_id ) );
0983
0984 status = rtems_task_set_priority(
0985 RTEMS_SELF,
0986 ctx->original_priority,
0987 &priority
0988 );
0989 T_rsc_success( status );
0990 }
0991
0992 static void RtemsRatemonReqPeriod_Teardown_Wrap( void *arg )
0993 {
0994 RtemsRatemonReqPeriod_Context *ctx;
0995
0996 ctx = arg;
0997 ctx->Map.in_action_loop = false;
0998 RtemsRatemonReqPeriod_Teardown( ctx );
0999 }
1000
1001 static void RtemsRatemonReqPeriod_Prepare( RtemsRatemonReqPeriod_Context *ctx )
1002 {
1003 rtems_status_code status;
1004 rtems_rate_monotonic_period_status period_status;
1005 ctx->test_duration = 0;
1006 ctx->period_calls = 0;
1007 OwnerDoWork( ctx, CreatePeriod );
1008
1009
1010
1011
1012
1013
1014 status = rtems_rate_monotonic_get_status(
1015 ctx->period_id,
1016 &period_status
1017 );
1018 T_rsc_success( status );
1019 }
1020
1021 static void RtemsRatemonReqPeriod_Action( RtemsRatemonReqPeriod_Context *ctx )
1022 {
1023 rtems_status_code status;
1024
1025 ctx->test_duration_till_action = ctx->test_duration;
1026 ctx->action_duration = ctx->do_action( ctx, DoAction );
1027
1028 status = rtems_rate_monotonic_get_status(
1029 ctx->period_id,
1030 &ctx->period_status
1031 );
1032 T_rsc_success( status );
1033 }
1034
1035 static void RtemsRatemonReqPeriod_Cleanup( RtemsRatemonReqPeriod_Context *ctx )
1036 {
1037 OwnerDoWork( ctx, DeletePeriod );
1038 }
1039
1040 static const RtemsRatemonReqPeriod_Entry
1041 RtemsRatemonReqPeriod_Entries[] = {
1042 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_InvId,
1043 RtemsRatemonReqPeriod_Post_State_Nop,
1044 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1045 RtemsRatemonReqPeriod_Post_Delay_None,
1046 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1047 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_NotOwn,
1048 RtemsRatemonReqPeriod_Post_State_Nop,
1049 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1050 RtemsRatemonReqPeriod_Post_Delay_None,
1051 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1052 { 1, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_NA,
1053 RtemsRatemonReqPeriod_Post_State_NA,
1054 RtemsRatemonReqPeriod_Post_Postponed_NA,
1055 RtemsRatemonReqPeriod_Post_Delay_NA,
1056 RtemsRatemonReqPeriod_Post_Scheduler_NA },
1057 { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_InvId,
1058 RtemsRatemonReqPeriod_Post_State_Nop,
1059 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1060 RtemsRatemonReqPeriod_Post_Delay_None,
1061 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1062 { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_InvId,
1063 RtemsRatemonReqPeriod_Post_State_Nop,
1064 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1065 RtemsRatemonReqPeriod_Post_Delay_None,
1066 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1067 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_Ok,
1068 RtemsRatemonReqPeriod_Post_State_Nop,
1069 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1070 RtemsRatemonReqPeriod_Post_Delay_None,
1071 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1072 { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_NotOwn,
1073 RtemsRatemonReqPeriod_Post_State_Nop,
1074 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1075 RtemsRatemonReqPeriod_Post_Delay_None,
1076 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1077 { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_NotOwn,
1078 RtemsRatemonReqPeriod_Post_State_Nop,
1079 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1080 RtemsRatemonReqPeriod_Post_Delay_None,
1081 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1082 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
1083 RtemsRatemonReqPeriod_Post_State_Active,
1084 RtemsRatemonReqPeriod_Post_Postponed_Zero,
1085 RtemsRatemonReqPeriod_Post_Delay_None,
1086 RtemsRatemonReqPeriod_Post_Scheduler_Called },
1087 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
1088 RtemsRatemonReqPeriod_Post_State_Active,
1089 RtemsRatemonReqPeriod_Post_Postponed_OneOrMore,
1090 RtemsRatemonReqPeriod_Post_Delay_None,
1091 RtemsRatemonReqPeriod_Post_Scheduler_Called },
1092 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
1093 RtemsRatemonReqPeriod_Post_State_Nop,
1094 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1095 RtemsRatemonReqPeriod_Post_Delay_None,
1096 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1097 { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_Ok,
1098 RtemsRatemonReqPeriod_Post_State_Active,
1099 RtemsRatemonReqPeriod_Post_Postponed_Zero,
1100 RtemsRatemonReqPeriod_Post_Delay_None,
1101 RtemsRatemonReqPeriod_Post_Scheduler_Called },
1102 { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_Ok,
1103 RtemsRatemonReqPeriod_Post_State_Active,
1104 RtemsRatemonReqPeriod_Post_Postponed_Zero,
1105 RtemsRatemonReqPeriod_Post_Delay_None,
1106 RtemsRatemonReqPeriod_Post_Scheduler_Called },
1107 { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_NotDef,
1108 RtemsRatemonReqPeriod_Post_State_Nop,
1109 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1110 RtemsRatemonReqPeriod_Post_Delay_None,
1111 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1112 { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_NotDef,
1113 RtemsRatemonReqPeriod_Post_State_Nop,
1114 RtemsRatemonReqPeriod_Post_Postponed_Nop,
1115 RtemsRatemonReqPeriod_Post_Delay_None,
1116 RtemsRatemonReqPeriod_Post_Scheduler_Nop },
1117 { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_Ok,
1118 RtemsRatemonReqPeriod_Post_State_Active,
1119 RtemsRatemonReqPeriod_Post_Postponed_Zero,
1120 RtemsRatemonReqPeriod_Post_Delay_TillDeadline,
1121 RtemsRatemonReqPeriod_Post_Scheduler_Called }
1122 };
1123
1124 static const uint8_t
1125 RtemsRatemonReqPeriod_Map[] = {
1126 11, 12, 11, 12, 11, 12, 15, 15, 8, 8, 9, 9, 2, 2, 8, 8, 9, 9, 13, 14, 13, 14,
1127 13, 14, 5, 5, 5, 5, 5, 5, 2, 2, 10, 10, 10, 10, 6, 7, 6, 7, 6, 7, 1, 1, 1, 1,
1128 1, 1, 2, 2, 1, 1, 1, 1, 6, 7, 6, 7, 6, 7, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1,
1129 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 4, 3, 4, 3, 4, 0, 0,
1130 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,
1131 0, 0, 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0
1132 };
1133
1134 static size_t RtemsRatemonReqPeriod_Scope( void *arg, char *buf, size_t n )
1135 {
1136 RtemsRatemonReqPeriod_Context *ctx;
1137
1138 ctx = arg;
1139
1140 if ( ctx->Map.in_action_loop ) {
1141 return T_get_scope( RtemsRatemonReqPeriod_PreDesc, buf, n, ctx->Map.pcs );
1142 }
1143
1144 return 0;
1145 }
1146
1147 static T_fixture RtemsRatemonReqPeriod_Fixture = {
1148 .setup = RtemsRatemonReqPeriod_Setup_Wrap,
1149 .stop = NULL,
1150 .teardown = RtemsRatemonReqPeriod_Teardown_Wrap,
1151 .scope = RtemsRatemonReqPeriod_Scope,
1152 .initial_context = &RtemsRatemonReqPeriod_Instance
1153 };
1154
1155 static inline RtemsRatemonReqPeriod_Entry RtemsRatemonReqPeriod_PopEntry(
1156 RtemsRatemonReqPeriod_Context *ctx
1157 )
1158 {
1159 size_t index;
1160
1161 index = ctx->Map.index;
1162 ctx->Map.index = index + 1;
1163 return RtemsRatemonReqPeriod_Entries[
1164 RtemsRatemonReqPeriod_Map[ index ]
1165 ];
1166 }
1167
1168 static void RtemsRatemonReqPeriod_SetPreConditionStates(
1169 RtemsRatemonReqPeriod_Context *ctx
1170 )
1171 {
1172 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
1173 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
1174 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
1175 ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
1176
1177 if ( ctx->Map.entry.Pre_Postponed_NA ) {
1178 ctx->Map.pcs[ 4 ] = RtemsRatemonReqPeriod_Pre_Postponed_NA;
1179 } else {
1180 ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
1181 }
1182
1183 if ( ctx->Map.entry.Pre_InactiveCause_NA ) {
1184 ctx->Map.pcs[ 5 ] = RtemsRatemonReqPeriod_Pre_InactiveCause_NA;
1185 } else {
1186 ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
1187 }
1188 }
1189
1190 static void RtemsRatemonReqPeriod_TestVariant(
1191 RtemsRatemonReqPeriod_Context *ctx
1192 )
1193 {
1194 RtemsRatemonReqPeriod_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1195 RtemsRatemonReqPeriod_Pre_Caller_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1196 RtemsRatemonReqPeriod_Pre_Length_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1197 RtemsRatemonReqPeriod_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1198 RtemsRatemonReqPeriod_Pre_Postponed_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1199 RtemsRatemonReqPeriod_Pre_InactiveCause_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1200 RtemsRatemonReqPeriod_Action( ctx );
1201 RtemsRatemonReqPeriod_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1202 RtemsRatemonReqPeriod_Post_State_Check( ctx, ctx->Map.entry.Post_State );
1203 RtemsRatemonReqPeriod_Post_Postponed_Check(
1204 ctx,
1205 ctx->Map.entry.Post_Postponed
1206 );
1207 RtemsRatemonReqPeriod_Post_Delay_Check( ctx, ctx->Map.entry.Post_Delay );
1208 RtemsRatemonReqPeriod_Post_Scheduler_Check(
1209 ctx,
1210 ctx->Map.entry.Post_Scheduler
1211 );
1212 }
1213
1214
1215
1216
1217 T_TEST_CASE_FIXTURE( RtemsRatemonReqPeriod, &RtemsRatemonReqPeriod_Fixture )
1218 {
1219 RtemsRatemonReqPeriod_Context *ctx;
1220
1221 ctx = T_fixture_context();
1222 ctx->Map.in_action_loop = true;
1223 ctx->Map.index = 0;
1224
1225 for (
1226 ctx->Map.pci[ 0 ] = RtemsRatemonReqPeriod_Pre_Id_Valid;
1227 ctx->Map.pci[ 0 ] < RtemsRatemonReqPeriod_Pre_Id_NA;
1228 ++ctx->Map.pci[ 0 ]
1229 ) {
1230 for (
1231 ctx->Map.pci[ 1 ] = RtemsRatemonReqPeriod_Pre_Caller_OwnerTask;
1232 ctx->Map.pci[ 1 ] < RtemsRatemonReqPeriod_Pre_Caller_NA;
1233 ++ctx->Map.pci[ 1 ]
1234 ) {
1235 for (
1236 ctx->Map.pci[ 2 ] = RtemsRatemonReqPeriod_Pre_Length_Ticks;
1237 ctx->Map.pci[ 2 ] < RtemsRatemonReqPeriod_Pre_Length_NA;
1238 ++ctx->Map.pci[ 2 ]
1239 ) {
1240 for (
1241 ctx->Map.pci[ 3 ] = RtemsRatemonReqPeriod_Pre_State_Inactive;
1242 ctx->Map.pci[ 3 ] < RtemsRatemonReqPeriod_Pre_State_NA;
1243 ++ctx->Map.pci[ 3 ]
1244 ) {
1245 for (
1246 ctx->Map.pci[ 4 ] = RtemsRatemonReqPeriod_Pre_Postponed_Zero;
1247 ctx->Map.pci[ 4 ] < RtemsRatemonReqPeriod_Pre_Postponed_NA;
1248 ++ctx->Map.pci[ 4 ]
1249 ) {
1250 for (
1251 ctx->Map.pci[ 5 ] = RtemsRatemonReqPeriod_Pre_InactiveCause_New;
1252 ctx->Map.pci[ 5 ] < RtemsRatemonReqPeriod_Pre_InactiveCause_NA;
1253 ++ctx->Map.pci[ 5 ]
1254 ) {
1255 ctx->Map.entry = RtemsRatemonReqPeriod_PopEntry( ctx );
1256
1257 if ( ctx->Map.entry.Skip ) {
1258 continue;
1259 }
1260
1261 RtemsRatemonReqPeriod_SetPreConditionStates( ctx );
1262 RtemsRatemonReqPeriod_Prepare( ctx );
1263 RtemsRatemonReqPeriod_TestVariant( ctx );
1264 RtemsRatemonReqPeriod_Cleanup( ctx );
1265 }
1266 }
1267 }
1268 }
1269 }
1270 }
1271 }
1272
1273