Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:53

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsTimerReqFireAfter
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
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  * @defgroup RtemsTimerReqFireAfter spec:/rtems/timer/req/fire-after
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsTimerReqFireAfter_Pre_Ticks_Valid,
0071   RtemsTimerReqFireAfter_Pre_Ticks_Is0,
0072   RtemsTimerReqFireAfter_Pre_Ticks_NA
0073 } RtemsTimerReqFireAfter_Pre_Ticks;
0074 
0075 typedef enum {
0076   RtemsTimerReqFireAfter_Pre_Routine_Valid,
0077   RtemsTimerReqFireAfter_Pre_Routine_Null,
0078   RtemsTimerReqFireAfter_Pre_Routine_NA
0079 } RtemsTimerReqFireAfter_Pre_Routine;
0080 
0081 typedef enum {
0082   RtemsTimerReqFireAfter_Pre_Id_Valid,
0083   RtemsTimerReqFireAfter_Pre_Id_Invalid,
0084   RtemsTimerReqFireAfter_Pre_Id_NA
0085 } RtemsTimerReqFireAfter_Pre_Id;
0086 
0087 typedef enum {
0088   RtemsTimerReqFireAfter_Pre_Context_None,
0089   RtemsTimerReqFireAfter_Pre_Context_Interrupt,
0090   RtemsTimerReqFireAfter_Pre_Context_Server,
0091   RtemsTimerReqFireAfter_Pre_Context_NA
0092 } RtemsTimerReqFireAfter_Pre_Context;
0093 
0094 typedef enum {
0095   RtemsTimerReqFireAfter_Pre_Clock_None,
0096   RtemsTimerReqFireAfter_Pre_Clock_Ticks,
0097   RtemsTimerReqFireAfter_Pre_Clock_Realtime,
0098   RtemsTimerReqFireAfter_Pre_Clock_NA
0099 } RtemsTimerReqFireAfter_Pre_Clock;
0100 
0101 typedef enum {
0102   RtemsTimerReqFireAfter_Pre_State_Inactive,
0103   RtemsTimerReqFireAfter_Pre_State_Scheduled,
0104   RtemsTimerReqFireAfter_Pre_State_Pending,
0105   RtemsTimerReqFireAfter_Pre_State_NA
0106 } RtemsTimerReqFireAfter_Pre_State;
0107 
0108 typedef enum {
0109   RtemsTimerReqFireAfter_Post_Status_Ok,
0110   RtemsTimerReqFireAfter_Post_Status_InvId,
0111   RtemsTimerReqFireAfter_Post_Status_InvAddr,
0112   RtemsTimerReqFireAfter_Post_Status_InvNum,
0113   RtemsTimerReqFireAfter_Post_Status_NA
0114 } RtemsTimerReqFireAfter_Post_Status;
0115 
0116 typedef enum {
0117   RtemsTimerReqFireAfter_Post_Context_None,
0118   RtemsTimerReqFireAfter_Post_Context_Interrupt,
0119   RtemsTimerReqFireAfter_Post_Context_Server,
0120   RtemsTimerReqFireAfter_Post_Context_Nop,
0121   RtemsTimerReqFireAfter_Post_Context_NA
0122 } RtemsTimerReqFireAfter_Post_Context;
0123 
0124 typedef enum {
0125   RtemsTimerReqFireAfter_Post_Clock_None,
0126   RtemsTimerReqFireAfter_Post_Clock_Ticks,
0127   RtemsTimerReqFireAfter_Post_Clock_Realtime,
0128   RtemsTimerReqFireAfter_Post_Clock_Nop,
0129   RtemsTimerReqFireAfter_Post_Clock_NA
0130 } RtemsTimerReqFireAfter_Post_Clock;
0131 
0132 typedef enum {
0133   RtemsTimerReqFireAfter_Post_State_Scheduled,
0134   RtemsTimerReqFireAfter_Post_State_Nop,
0135   RtemsTimerReqFireAfter_Post_State_NA
0136 } RtemsTimerReqFireAfter_Post_State;
0137 
0138 typedef enum {
0139   RtemsTimerReqFireAfter_Post_Interval_Param,
0140   RtemsTimerReqFireAfter_Post_Interval_Nop,
0141   RtemsTimerReqFireAfter_Post_Interval_NA
0142 } RtemsTimerReqFireAfter_Post_Interval;
0143 
0144 typedef enum {
0145   RtemsTimerReqFireAfter_Post_Routine_Param,
0146   RtemsTimerReqFireAfter_Post_Routine_Nop,
0147   RtemsTimerReqFireAfter_Post_Routine_NA
0148 } RtemsTimerReqFireAfter_Post_Routine;
0149 
0150 typedef enum {
0151   RtemsTimerReqFireAfter_Post_UserData_Param,
0152   RtemsTimerReqFireAfter_Post_UserData_Nop,
0153   RtemsTimerReqFireAfter_Post_UserData_NA
0154 } RtemsTimerReqFireAfter_Post_UserData;
0155 
0156 typedef struct {
0157   uint32_t Skip : 1;
0158   uint32_t Pre_Ticks_NA : 1;
0159   uint32_t Pre_Routine_NA : 1;
0160   uint32_t Pre_Id_NA : 1;
0161   uint32_t Pre_Context_NA : 1;
0162   uint32_t Pre_Clock_NA : 1;
0163   uint32_t Pre_State_NA : 1;
0164   uint32_t Post_Status : 3;
0165   uint32_t Post_Context : 3;
0166   uint32_t Post_Clock : 3;
0167   uint32_t Post_State : 2;
0168   uint32_t Post_Interval : 2;
0169   uint32_t Post_Routine : 2;
0170   uint32_t Post_UserData : 2;
0171 } RtemsTimerReqFireAfter_Entry;
0172 
0173 typedef enum {
0174   PRE_NONE      = 0,
0175   PRE_INTERRUPT = 1,
0176   PRE_SERVER    = 2
0177 } PreConditionContext;
0178 
0179 typedef enum {
0180   SCHEDULE_NONE  = 0,
0181   SCHEDULE_SOON  = 1,
0182   SCHEDULE_LATER = 2,
0183   SCHEDULE_MAX   = 5
0184 } Scheduling_Ticks;
0185 
0186 /**
0187  * @brief Test context for spec:/rtems/timer/req/fire-after test case.
0188  */
0189 typedef struct {
0190   /**
0191    * @brief This member contains a valid id of a timer.
0192    */
0193   rtems_id timer_id;
0194 
0195   /**
0196    * @brief This member specifies the ``id`` parameter for the action.
0197    */
0198   rtems_id id_param;
0199 
0200   /**
0201    * @brief This member specifies the ``ticks`` parameter for the action.
0202    */
0203   rtems_interval ticks_param;
0204 
0205   /**
0206    * @brief This member specifies the ``routine`` parameter for the action.
0207    */
0208   rtems_timer_service_routine_entry routine_param;
0209 
0210   /**
0211    * @brief This member contains the returned status code of the action.
0212    */
0213   rtems_status_code status;
0214 
0215   /**
0216    * @brief This member contains a counter for invocations of the Timer Service
0217    *   Routine.
0218    */
0219   int invocations;
0220 
0221   /**
0222    * @brief Function TriggerTimer() is used to figure out how many ticks (see
0223    *   tick) are needed till the Timer Service Routine gets executed. This
0224    *   member contains the number of ticks needed to fire the Timer Service
0225    *   Routine.
0226    */
0227   Scheduling_Ticks ticks_till_fire;
0228 
0229   /**
0230    * @brief This member contains the user data given to the Timer Service
0231    *   Routine when called.
0232    */
0233   void *routine_user_data;
0234 
0235   /**
0236    * @brief This member specifies which pre-condition context (none, interrupt
0237    *   context, server context) must be created before the
0238    *   rtems_timer_fire_after() action gets executed.
0239    */
0240   PreConditionContext pre_cond_contex;
0241 
0242   /**
0243    * @brief This member stores internal clock and context settings of the timer
0244    *   before the execution of the test action.
0245    */
0246   Timer_Classes pre_class;
0247 
0248   /**
0249    * @brief This member stores the state of the timer before the execution of
0250    *   the test action.
0251    */
0252   Timer_States pre_state;
0253 
0254   /**
0255    * @brief This member stores the state of the timer after the execution of
0256    *   the test action.
0257    */
0258   Timer_States post_state;
0259 
0260   /**
0261    * @brief This member stores the scheduling data of the timer before the
0262    *   execution of the test action.
0263    */
0264   Timer_Scheduling_Data pre_scheduling_data;
0265 
0266   /**
0267    * @brief This member stores the scheduling data of the timer after the
0268    *   execution of the test action.
0269    */
0270   Timer_Scheduling_Data post_scheduling_data;
0271 
0272   struct {
0273     /**
0274      * @brief This member defines the pre-condition states for the next action.
0275      */
0276     size_t pcs[ 6 ];
0277 
0278     /**
0279      * @brief If this member is true, then the test action loop is executed.
0280      */
0281     bool in_action_loop;
0282 
0283     /**
0284      * @brief This member contains the next transition map index.
0285      */
0286     size_t index;
0287 
0288     /**
0289      * @brief This member contains the current transition map entry.
0290      */
0291     RtemsTimerReqFireAfter_Entry entry;
0292 
0293     /**
0294      * @brief If this member is true, then the current transition variant
0295      *   should be skipped.
0296      */
0297     bool skip;
0298   } Map;
0299 } RtemsTimerReqFireAfter_Context;
0300 
0301 static RtemsTimerReqFireAfter_Context
0302   RtemsTimerReqFireAfter_Instance;
0303 
0304 static const char * const RtemsTimerReqFireAfter_PreDesc_Ticks[] = {
0305   "Valid",
0306   "Is0",
0307   "NA"
0308 };
0309 
0310 static const char * const RtemsTimerReqFireAfter_PreDesc_Routine[] = {
0311   "Valid",
0312   "Null",
0313   "NA"
0314 };
0315 
0316 static const char * const RtemsTimerReqFireAfter_PreDesc_Id[] = {
0317   "Valid",
0318   "Invalid",
0319   "NA"
0320 };
0321 
0322 static const char * const RtemsTimerReqFireAfter_PreDesc_Context[] = {
0323   "None",
0324   "Interrupt",
0325   "Server",
0326   "NA"
0327 };
0328 
0329 static const char * const RtemsTimerReqFireAfter_PreDesc_Clock[] = {
0330   "None",
0331   "Ticks",
0332   "Realtime",
0333   "NA"
0334 };
0335 
0336 static const char * const RtemsTimerReqFireAfter_PreDesc_State[] = {
0337   "Inactive",
0338   "Scheduled",
0339   "Pending",
0340   "NA"
0341 };
0342 
0343 static const char * const * const RtemsTimerReqFireAfter_PreDesc[] = {
0344   RtemsTimerReqFireAfter_PreDesc_Ticks,
0345   RtemsTimerReqFireAfter_PreDesc_Routine,
0346   RtemsTimerReqFireAfter_PreDesc_Id,
0347   RtemsTimerReqFireAfter_PreDesc_Context,
0348   RtemsTimerReqFireAfter_PreDesc_Clock,
0349   RtemsTimerReqFireAfter_PreDesc_State,
0350   NULL
0351 };
0352 
0353 static const rtems_time_of_day tod_now      = { 2000, 1, 1, 0, 0, 0, 0 };
0354 static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
0355 static const rtems_time_of_day tod_fire     = { 2000, 1, 2, 0, 0, 0, 0 };
0356 
0357 static Scheduling_Ticks TriggerTimer( const RtemsTimerReqFireAfter_Context *ctx )
0358 {
0359   int ticks_fired = SCHEDULE_NONE;
0360   int invocations_old = ctx->invocations;
0361 
0362   /* Fire the timer service routine for ticks and realtime clock */
0363   int i;
0364   for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
0365     ClockTick();
0366     if ( ctx->invocations > invocations_old ) {
0367       ticks_fired = i;
0368       break;
0369     }
0370   }
0371 
0372   T_rsc_success( rtems_clock_set( &tod_fire ) );
0373 
0374   return ticks_fired;
0375 }
0376 
0377 static void TimerServiceRoutine(
0378   rtems_id timer_id,
0379   void *user_data
0380 )
0381 {
0382   RtemsTimerReqFireAfter_Context *ctx = user_data;
0383   ++( ctx->invocations );
0384   ctx->routine_user_data = user_data;
0385 }
0386 
0387 static void RtemsTimerReqFireAfter_Pre_Ticks_Prepare(
0388   RtemsTimerReqFireAfter_Context  *ctx,
0389   RtemsTimerReqFireAfter_Pre_Ticks state
0390 )
0391 {
0392   switch ( state ) {
0393     case RtemsTimerReqFireAfter_Pre_Ticks_Valid: {
0394       /*
0395        * While the ``ticks`` parameter is a positive (greater 0) number.
0396        */
0397       ctx->ticks_param = SCHEDULE_LATER;
0398       break;
0399     }
0400 
0401     case RtemsTimerReqFireAfter_Pre_Ticks_Is0: {
0402       /*
0403        * While the ``ticks`` parameter is 0.
0404        */
0405       ctx->ticks_param = 0;
0406       break;
0407     }
0408 
0409     case RtemsTimerReqFireAfter_Pre_Ticks_NA:
0410       break;
0411   }
0412 }
0413 
0414 static void RtemsTimerReqFireAfter_Pre_Routine_Prepare(
0415   RtemsTimerReqFireAfter_Context    *ctx,
0416   RtemsTimerReqFireAfter_Pre_Routine state
0417 )
0418 {
0419   switch ( state ) {
0420     case RtemsTimerReqFireAfter_Pre_Routine_Valid: {
0421       /*
0422        * While the ``routine`` parameter references an object of type
0423        * rtems_timer_service_routine_entry.
0424        */
0425       ctx->routine_param = TimerServiceRoutine;
0426       break;
0427     }
0428 
0429     case RtemsTimerReqFireAfter_Pre_Routine_Null: {
0430       /*
0431        * While the ``routine`` parameter is NULL..
0432        */
0433       ctx->routine_param = NULL;
0434       break;
0435     }
0436 
0437     case RtemsTimerReqFireAfter_Pre_Routine_NA:
0438       break;
0439   }
0440 }
0441 
0442 static void RtemsTimerReqFireAfter_Pre_Id_Prepare(
0443   RtemsTimerReqFireAfter_Context *ctx,
0444   RtemsTimerReqFireAfter_Pre_Id   state
0445 )
0446 {
0447   switch ( state ) {
0448     case RtemsTimerReqFireAfter_Pre_Id_Valid: {
0449       /*
0450        * While the ``id`` parameter is valid.
0451        */
0452       ctx->id_param = ctx->timer_id;
0453       break;
0454     }
0455 
0456     case RtemsTimerReqFireAfter_Pre_Id_Invalid: {
0457       /*
0458        * While the ``id`` parameter is invalid.
0459        */
0460       ctx->id_param = RTEMS_ID_NONE;
0461       break;
0462     }
0463 
0464     case RtemsTimerReqFireAfter_Pre_Id_NA:
0465       break;
0466   }
0467 }
0468 
0469 static void RtemsTimerReqFireAfter_Pre_Context_Prepare(
0470   RtemsTimerReqFireAfter_Context    *ctx,
0471   RtemsTimerReqFireAfter_Pre_Context state
0472 )
0473 {
0474   switch ( state ) {
0475     case RtemsTimerReqFireAfter_Pre_Context_None: {
0476       /*
0477        * While the Timer Service Routine has never been scheduled since
0478        * creation of the timer. See also none.
0479        */
0480       ctx->pre_cond_contex = PRE_NONE;
0481       break;
0482     }
0483 
0484     case RtemsTimerReqFireAfter_Pre_Context_Interrupt: {
0485       /*
0486        * While the timer is in interrupt context.
0487        */
0488       ctx->pre_cond_contex = PRE_INTERRUPT;
0489       break;
0490     }
0491 
0492     case RtemsTimerReqFireAfter_Pre_Context_Server: {
0493       /*
0494        * While the timer is in server context.
0495        */
0496       ctx->pre_cond_contex = PRE_SERVER;
0497       break;
0498     }
0499 
0500     case RtemsTimerReqFireAfter_Pre_Context_NA:
0501       break;
0502   }
0503 }
0504 
0505 static void RtemsTimerReqFireAfter_Pre_Clock_Prepare(
0506   RtemsTimerReqFireAfter_Context  *ctx,
0507   RtemsTimerReqFireAfter_Pre_Clock state
0508 )
0509 {
0510   switch ( state ) {
0511     case RtemsTimerReqFireAfter_Pre_Clock_None: {
0512       /*
0513        * While the timer has never been scheduled since creation of the timer.
0514        */
0515       T_eq_int( ctx->pre_cond_contex, PRE_NONE );
0516       break;
0517     }
0518 
0519     case RtemsTimerReqFireAfter_Pre_Clock_Ticks: {
0520       /*
0521        * While the clock used to determine when the timer will fire is the
0522        * ticks based clock.
0523        */
0524       rtems_status_code status;
0525 
0526       if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0527         status = rtems_timer_fire_after(
0528           ctx->timer_id,
0529           SCHEDULE_SOON,
0530           TimerServiceRoutine,
0531           ctx
0532         );
0533       } else {
0534         status = rtems_timer_server_fire_after(
0535           ctx->timer_id,
0536           SCHEDULE_SOON,
0537           TimerServiceRoutine,
0538           ctx
0539         );
0540       }
0541       T_rsc_success( status );
0542       break;
0543     }
0544 
0545     case RtemsTimerReqFireAfter_Pre_Clock_Realtime: {
0546       /*
0547        * While the clock used to determine when the timer will fire is the
0548        * realtime clock.
0549        */
0550       rtems_status_code status;
0551 
0552       if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0553         status = rtems_timer_fire_when(
0554           ctx->timer_id,
0555           &tod_schedule,
0556           TimerServiceRoutine,
0557           ctx
0558         );
0559       } else {
0560         status = rtems_timer_server_fire_when(
0561           ctx->timer_id,
0562           &tod_schedule,
0563           TimerServiceRoutine,
0564           ctx
0565         );
0566       }
0567       T_rsc_success( status );
0568       break;
0569     }
0570 
0571     case RtemsTimerReqFireAfter_Pre_Clock_NA:
0572       break;
0573   }
0574 }
0575 
0576 static void RtemsTimerReqFireAfter_Pre_State_Prepare(
0577   RtemsTimerReqFireAfter_Context  *ctx,
0578   RtemsTimerReqFireAfter_Pre_State state
0579 )
0580 {
0581   switch ( state ) {
0582     case RtemsTimerReqFireAfter_Pre_State_Inactive: {
0583       /*
0584        * While the timer is in inactive state.
0585        */
0586       TriggerTimer( ctx );
0587       T_eq_int(
0588         ctx->invocations,
0589         ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
0590       );
0591       ctx->invocations = 0;
0592       ctx->pre_state = TIMER_INACTIVE;
0593       break;
0594     }
0595 
0596     case RtemsTimerReqFireAfter_Pre_State_Scheduled: {
0597       /*
0598        * While the timer is in scheduled state.
0599        */
0600       /* The timer was already scheduled in the "Clock" pre-conditions. */
0601       ctx->pre_state = TIMER_SCHEDULED;
0602       break;
0603     }
0604 
0605     case RtemsTimerReqFireAfter_Pre_State_Pending: {
0606       /*
0607        * While the timer is in pending state.
0608        */
0609       T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
0610       TriggerTimer( ctx );
0611       T_eq_int( ctx->invocations, 0 );
0612       ctx->pre_state = TIMER_PENDING;
0613       break;
0614     }
0615 
0616     case RtemsTimerReqFireAfter_Pre_State_NA:
0617       break;
0618   }
0619 }
0620 
0621 static void RtemsTimerReqFireAfter_Post_Status_Check(
0622   RtemsTimerReqFireAfter_Context    *ctx,
0623   RtemsTimerReqFireAfter_Post_Status state
0624 )
0625 {
0626   switch ( state ) {
0627     case RtemsTimerReqFireAfter_Post_Status_Ok: {
0628       /*
0629        * The return status of rtems_timer_fire_after() shall be
0630        * RTEMS_SUCCESSFUL.
0631        */
0632       T_rsc_success( ctx->status );
0633       break;
0634     }
0635 
0636     case RtemsTimerReqFireAfter_Post_Status_InvId: {
0637       /*
0638        * The return status of rtems_timer_fire_after() shall be
0639        * RTEMS_INVALID_ID.
0640        */
0641       T_rsc( ctx->status, RTEMS_INVALID_ID );
0642       break;
0643     }
0644 
0645     case RtemsTimerReqFireAfter_Post_Status_InvAddr: {
0646       /*
0647        * The return status of rtems_timer_fire_after() shall be
0648        * RTEMS_INVALID_ADDRESS.
0649        */
0650       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0651       break;
0652     }
0653 
0654     case RtemsTimerReqFireAfter_Post_Status_InvNum: {
0655       /*
0656        * The return status of rtems_timer_fire_after() shall be
0657        * RTEMS_INVALID_NUMBER.
0658        */
0659       T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
0660       break;
0661     }
0662 
0663     case RtemsTimerReqFireAfter_Post_Status_NA:
0664       break;
0665   }
0666 }
0667 
0668 static void RtemsTimerReqFireAfter_Post_Context_Check(
0669   RtemsTimerReqFireAfter_Context     *ctx,
0670   RtemsTimerReqFireAfter_Post_Context state
0671 )
0672 {
0673   Timer_Classes class;
0674   class = GetTimerClass( ctx->timer_id );
0675 
0676   switch ( state ) {
0677     case RtemsTimerReqFireAfter_Post_Context_None: {
0678       /*
0679        * The timer shall have never been scheduled. See also none.
0680        */
0681       T_eq_int( class, TIMER_DORMANT );
0682       break;
0683     }
0684 
0685     case RtemsTimerReqFireAfter_Post_Context_Interrupt: {
0686       /*
0687        * The timer shall be in interrupt context.
0688        */
0689       T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
0690       break;
0691     }
0692 
0693     case RtemsTimerReqFireAfter_Post_Context_Server: {
0694       /*
0695        * The timer shall be in server context.
0696        */
0697       T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
0698       break;
0699     }
0700 
0701     case RtemsTimerReqFireAfter_Post_Context_Nop: {
0702       /*
0703        * Objects referenced by the parameters in the past call to
0704        * rtems_timer_fire_after() shall not be accessed by the
0705        * rtems_timer_fire_after() call. See also Nop.
0706        */
0707       T_eq_int( class, ctx->pre_class );
0708       break;
0709     }
0710 
0711     case RtemsTimerReqFireAfter_Post_Context_NA:
0712       break;
0713   }
0714 }
0715 
0716 static void RtemsTimerReqFireAfter_Post_Clock_Check(
0717   RtemsTimerReqFireAfter_Context   *ctx,
0718   RtemsTimerReqFireAfter_Post_Clock state
0719 )
0720 {
0721   Timer_Classes class;
0722   class = GetTimerClass( ctx->timer_id );
0723 
0724   switch ( state ) {
0725     case RtemsTimerReqFireAfter_Post_Clock_None: {
0726       /*
0727        * The timer shall have never been scheduled.
0728        */
0729       T_eq_int( class, TIMER_DORMANT );
0730       break;
0731     }
0732 
0733     case RtemsTimerReqFireAfter_Post_Clock_Ticks: {
0734       /*
0735        * The timer shall use the ticks based clock.
0736        */
0737       T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
0738       break;
0739     }
0740 
0741     case RtemsTimerReqFireAfter_Post_Clock_Realtime: {
0742       /*
0743        * The timer shall use the realtime clock.
0744        */
0745       T_eq_int(
0746         class & TIMER_CLASS_BIT_TIME_OF_DAY,
0747         TIMER_CLASS_BIT_TIME_OF_DAY
0748       );
0749       break;
0750     }
0751 
0752     case RtemsTimerReqFireAfter_Post_Clock_Nop: {
0753       /*
0754        * Objects referenced by the parameters in the past call to
0755        * rtems_timer_fire_after() shall not be accessed by the
0756        * rtems_timer_fire_after() call.
0757        */
0758       T_eq_int( class, ctx->pre_class );
0759       break;
0760     }
0761 
0762     case RtemsTimerReqFireAfter_Post_Clock_NA:
0763       break;
0764   }
0765 }
0766 
0767 static void RtemsTimerReqFireAfter_Post_State_Check(
0768   RtemsTimerReqFireAfter_Context   *ctx,
0769   RtemsTimerReqFireAfter_Post_State state
0770 )
0771 {
0772   switch ( state ) {
0773     case RtemsTimerReqFireAfter_Post_State_Scheduled: {
0774       /*
0775        * The timer shall be in scheduled state.
0776        */
0777       ctx->ticks_till_fire = TriggerTimer( ctx );
0778       T_eq_int( ctx->invocations, 1 );
0779       break;
0780     }
0781 
0782     case RtemsTimerReqFireAfter_Post_State_Nop: {
0783       /*
0784        * Objects referenced by the parameters in the past call to
0785        * rtems_timer_fire_after() shall not be accessed by the
0786        * rtems_timer_fire_after() call.
0787        */
0788       T_eq_int( ctx->post_state, ctx->pre_state );
0789       break;
0790     }
0791 
0792     case RtemsTimerReqFireAfter_Post_State_NA:
0793       break;
0794   }
0795 }
0796 
0797 static void RtemsTimerReqFireAfter_Post_Interval_Check(
0798   RtemsTimerReqFireAfter_Context      *ctx,
0799   RtemsTimerReqFireAfter_Post_Interval state
0800 )
0801 {
0802   switch ( state ) {
0803     case RtemsTimerReqFireAfter_Post_Interval_Param: {
0804       /*
0805        * The Timer Service Routine shall be invoked the number of ticks (see
0806        * tick), which are provided by the ``ticks`` parameter in the past call
0807        * to rtems_timer_fire_after(), after a point in time during the
0808        * execution of the rtems_timer_fire_after() call.
0809        */
0810       T_eq_int( ctx->ticks_till_fire, ctx->ticks_param );
0811       break;
0812     }
0813 
0814     case RtemsTimerReqFireAfter_Post_Interval_Nop: {
0815       /*
0816        * If and when the Timer Service Routine will be invoked shall not be
0817        * changed by the past call to rtems_timer_fire_after().
0818        */
0819       /*
0820        * Whether the timer is scheduled has already been tested by the
0821        * "Nop" "State" post-condition above.
0822        */
0823       T_eq_u32(
0824         ctx->post_scheduling_data.interval,
0825         ctx->pre_scheduling_data.interval
0826       );
0827       break;
0828     }
0829 
0830     case RtemsTimerReqFireAfter_Post_Interval_NA:
0831       break;
0832   }
0833 }
0834 
0835 static void RtemsTimerReqFireAfter_Post_Routine_Check(
0836   RtemsTimerReqFireAfter_Context     *ctx,
0837   RtemsTimerReqFireAfter_Post_Routine state
0838 )
0839 {
0840   switch ( state ) {
0841     case RtemsTimerReqFireAfter_Post_Routine_Param: {
0842       /*
0843        * The function reference used to invoke the Timer Service Routine when
0844        * the timer will fire shall be the one provided by the ``routine``
0845        * parameter in the past call to rtems_timer_fire_after().
0846        */
0847       T_eq_int( ctx->invocations, 1 );
0848       break;
0849     }
0850 
0851     case RtemsTimerReqFireAfter_Post_Routine_Nop: {
0852       /*
0853        * The function reference used for any invocation of the Timer Service
0854        * Routine shall not be changed by the past call to
0855        * rtems_timer_fire_after().
0856        */
0857       T_eq_ptr(
0858         ctx->post_scheduling_data.routine,
0859         ctx->pre_scheduling_data.routine
0860       );
0861       break;
0862     }
0863 
0864     case RtemsTimerReqFireAfter_Post_Routine_NA:
0865       break;
0866   }
0867 }
0868 
0869 static void RtemsTimerReqFireAfter_Post_UserData_Check(
0870   RtemsTimerReqFireAfter_Context      *ctx,
0871   RtemsTimerReqFireAfter_Post_UserData state
0872 )
0873 {
0874   switch ( state ) {
0875     case RtemsTimerReqFireAfter_Post_UserData_Param: {
0876       /*
0877        * The user data argument for invoking the Timer Service Routine when the
0878        * timer will fire shall be the one provided by the ``user_data``
0879        * parameter in the past call to rtems_timer_fire_after().
0880        */
0881       T_eq_ptr( ctx->routine_user_data, ctx );
0882       break;
0883     }
0884 
0885     case RtemsTimerReqFireAfter_Post_UserData_Nop: {
0886       /*
0887        * The user data argument used for any invocation of the Timer Service
0888        * Routine shall not be changed by the past call to
0889        * rtems_timer_fire_after().
0890        */
0891       T_eq_ptr(
0892         ctx->post_scheduling_data.user_data,
0893         ctx->pre_scheduling_data.user_data
0894       );
0895       break;
0896     }
0897 
0898     case RtemsTimerReqFireAfter_Post_UserData_NA:
0899       break;
0900   }
0901 }
0902 
0903 static void RtemsTimerReqFireAfter_Setup( RtemsTimerReqFireAfter_Context *ctx )
0904 {
0905   rtems_status_code status;
0906   status = rtems_timer_initiate_server(
0907     RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
0908     RTEMS_MINIMUM_STACK_SIZE,
0909     RTEMS_DEFAULT_ATTRIBUTES
0910   );
0911   T_rsc_success( status );
0912 }
0913 
0914 static void RtemsTimerReqFireAfter_Setup_Wrap( void *arg )
0915 {
0916   RtemsTimerReqFireAfter_Context *ctx;
0917 
0918   ctx = arg;
0919   ctx->Map.in_action_loop = false;
0920   RtemsTimerReqFireAfter_Setup( ctx );
0921 }
0922 
0923 /**
0924  * @brief Make sure the timer server is not running and the realtime clock is
0925  *   not set after this test.
0926  */
0927 static void RtemsTimerReqFireAfter_Teardown(
0928   RtemsTimerReqFireAfter_Context *ctx
0929 )
0930 {
0931   DeleteTimerServer();
0932   UnsetClock();
0933 }
0934 
0935 static void RtemsTimerReqFireAfter_Teardown_Wrap( void *arg )
0936 {
0937   RtemsTimerReqFireAfter_Context *ctx;
0938 
0939   ctx = arg;
0940   ctx->Map.in_action_loop = false;
0941   RtemsTimerReqFireAfter_Teardown( ctx );
0942 }
0943 
0944 static void RtemsTimerReqFireAfter_Prepare(
0945   RtemsTimerReqFireAfter_Context *ctx
0946 )
0947 {
0948   rtems_status_code status;
0949   status = rtems_timer_create(
0950     rtems_build_name( 'T', 'I', 'M', 'E' ),
0951     &ctx->timer_id
0952   );
0953   T_rsc_success( status );
0954 
0955   ctx->invocations               = 0;
0956   ctx->ticks_till_fire           = SCHEDULE_NONE;
0957   ctx->routine_user_data         = NULL;
0958   T_rsc_success( rtems_clock_set( &tod_now ) );
0959 }
0960 
0961 static void RtemsTimerReqFireAfter_Action(
0962   RtemsTimerReqFireAfter_Context *ctx
0963 )
0964 {
0965   GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
0966   ctx->pre_class = GetTimerClass( ctx->timer_id );
0967   ctx->status = rtems_timer_fire_after(
0968     ctx->id_param,
0969     ctx->ticks_param,
0970     ctx->routine_param,
0971     ctx
0972   );
0973   ctx->post_state = GetTimerState( ctx->timer_id );
0974   GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
0975   /* Ignoring return status: the timer server task may be suspended or not. */
0976   rtems_task_resume( GetTimerServerTaskId() );
0977 }
0978 
0979 static void RtemsTimerReqFireAfter_Cleanup(
0980   RtemsTimerReqFireAfter_Context *ctx
0981 )
0982 {
0983   T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
0984 }
0985 
0986 static const RtemsTimerReqFireAfter_Entry
0987 RtemsTimerReqFireAfter_Entries[] = {
0988   { 1, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_NA,
0989     RtemsTimerReqFireAfter_Post_Context_NA,
0990     RtemsTimerReqFireAfter_Post_Clock_NA, RtemsTimerReqFireAfter_Post_State_NA,
0991     RtemsTimerReqFireAfter_Post_Interval_NA,
0992     RtemsTimerReqFireAfter_Post_Routine_NA,
0993     RtemsTimerReqFireAfter_Post_UserData_NA },
0994   { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvNum,
0995     RtemsTimerReqFireAfter_Post_Context_Nop,
0996     RtemsTimerReqFireAfter_Post_Clock_Nop,
0997     RtemsTimerReqFireAfter_Post_State_Nop,
0998     RtemsTimerReqFireAfter_Post_Interval_Nop,
0999     RtemsTimerReqFireAfter_Post_Routine_Nop,
1000     RtemsTimerReqFireAfter_Post_UserData_Nop },
1001   { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvAddr,
1002     RtemsTimerReqFireAfter_Post_Context_Nop,
1003     RtemsTimerReqFireAfter_Post_Clock_Nop,
1004     RtemsTimerReqFireAfter_Post_State_Nop,
1005     RtemsTimerReqFireAfter_Post_Interval_Nop,
1006     RtemsTimerReqFireAfter_Post_Routine_Nop,
1007     RtemsTimerReqFireAfter_Post_UserData_Nop },
1008   { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_Ok,
1009     RtemsTimerReqFireAfter_Post_Context_Interrupt,
1010     RtemsTimerReqFireAfter_Post_Clock_Ticks,
1011     RtemsTimerReqFireAfter_Post_State_Scheduled,
1012     RtemsTimerReqFireAfter_Post_Interval_Param,
1013     RtemsTimerReqFireAfter_Post_Routine_Param,
1014     RtemsTimerReqFireAfter_Post_UserData_Param },
1015   { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvId,
1016     RtemsTimerReqFireAfter_Post_Context_Nop,
1017     RtemsTimerReqFireAfter_Post_Clock_Nop,
1018     RtemsTimerReqFireAfter_Post_State_Nop,
1019     RtemsTimerReqFireAfter_Post_Interval_Nop,
1020     RtemsTimerReqFireAfter_Post_Routine_Nop,
1021     RtemsTimerReqFireAfter_Post_UserData_Nop }
1022 };
1023 
1024 static const uint8_t
1025 RtemsTimerReqFireAfter_Map[] = {
1026   3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 3,
1027   3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4,
1028   4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2, 2,
1029   2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2,
1030   2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1,
1031   1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
1032   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, 0,
1033   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,
1034   0, 0, 1, 1, 1, 1, 1, 1
1035 };
1036 
1037 static size_t RtemsTimerReqFireAfter_Scope( void *arg, char *buf, size_t n )
1038 {
1039   RtemsTimerReqFireAfter_Context *ctx;
1040 
1041   ctx = arg;
1042 
1043   if ( ctx->Map.in_action_loop ) {
1044     return T_get_scope( RtemsTimerReqFireAfter_PreDesc, buf, n, ctx->Map.pcs );
1045   }
1046 
1047   return 0;
1048 }
1049 
1050 static T_fixture RtemsTimerReqFireAfter_Fixture = {
1051   .setup = RtemsTimerReqFireAfter_Setup_Wrap,
1052   .stop = NULL,
1053   .teardown = RtemsTimerReqFireAfter_Teardown_Wrap,
1054   .scope = RtemsTimerReqFireAfter_Scope,
1055   .initial_context = &RtemsTimerReqFireAfter_Instance
1056 };
1057 
1058 static inline RtemsTimerReqFireAfter_Entry RtemsTimerReqFireAfter_PopEntry(
1059   RtemsTimerReqFireAfter_Context *ctx
1060 )
1061 {
1062   size_t index;
1063 
1064   index = ctx->Map.index;
1065   ctx->Map.index = index + 1;
1066   return RtemsTimerReqFireAfter_Entries[
1067     RtemsTimerReqFireAfter_Map[ index ]
1068   ];
1069 }
1070 
1071 static void RtemsTimerReqFireAfter_TestVariant(
1072   RtemsTimerReqFireAfter_Context *ctx
1073 )
1074 {
1075   RtemsTimerReqFireAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1076   RtemsTimerReqFireAfter_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1077   RtemsTimerReqFireAfter_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1078   RtemsTimerReqFireAfter_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1079   RtemsTimerReqFireAfter_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1080   RtemsTimerReqFireAfter_Pre_State_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1081   RtemsTimerReqFireAfter_Action( ctx );
1082   RtemsTimerReqFireAfter_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1083   RtemsTimerReqFireAfter_Post_Context_Check(
1084     ctx,
1085     ctx->Map.entry.Post_Context
1086   );
1087   RtemsTimerReqFireAfter_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
1088   RtemsTimerReqFireAfter_Post_State_Check( ctx, ctx->Map.entry.Post_State );
1089   RtemsTimerReqFireAfter_Post_Interval_Check(
1090     ctx,
1091     ctx->Map.entry.Post_Interval
1092   );
1093   RtemsTimerReqFireAfter_Post_Routine_Check(
1094     ctx,
1095     ctx->Map.entry.Post_Routine
1096   );
1097   RtemsTimerReqFireAfter_Post_UserData_Check(
1098     ctx,
1099     ctx->Map.entry.Post_UserData
1100   );
1101 }
1102 
1103 /**
1104  * @fn void T_case_body_RtemsTimerReqFireAfter( void )
1105  */
1106 T_TEST_CASE_FIXTURE( RtemsTimerReqFireAfter, &RtemsTimerReqFireAfter_Fixture )
1107 {
1108   RtemsTimerReqFireAfter_Context *ctx;
1109 
1110   ctx = T_fixture_context();
1111   ctx->Map.in_action_loop = true;
1112   ctx->Map.index = 0;
1113 
1114   for (
1115     ctx->Map.pcs[ 0 ] = RtemsTimerReqFireAfter_Pre_Ticks_Valid;
1116     ctx->Map.pcs[ 0 ] < RtemsTimerReqFireAfter_Pre_Ticks_NA;
1117     ++ctx->Map.pcs[ 0 ]
1118   ) {
1119     for (
1120       ctx->Map.pcs[ 1 ] = RtemsTimerReqFireAfter_Pre_Routine_Valid;
1121       ctx->Map.pcs[ 1 ] < RtemsTimerReqFireAfter_Pre_Routine_NA;
1122       ++ctx->Map.pcs[ 1 ]
1123     ) {
1124       for (
1125         ctx->Map.pcs[ 2 ] = RtemsTimerReqFireAfter_Pre_Id_Valid;
1126         ctx->Map.pcs[ 2 ] < RtemsTimerReqFireAfter_Pre_Id_NA;
1127         ++ctx->Map.pcs[ 2 ]
1128       ) {
1129         for (
1130           ctx->Map.pcs[ 3 ] = RtemsTimerReqFireAfter_Pre_Context_None;
1131           ctx->Map.pcs[ 3 ] < RtemsTimerReqFireAfter_Pre_Context_NA;
1132           ++ctx->Map.pcs[ 3 ]
1133         ) {
1134           for (
1135             ctx->Map.pcs[ 4 ] = RtemsTimerReqFireAfter_Pre_Clock_None;
1136             ctx->Map.pcs[ 4 ] < RtemsTimerReqFireAfter_Pre_Clock_NA;
1137             ++ctx->Map.pcs[ 4 ]
1138           ) {
1139             for (
1140               ctx->Map.pcs[ 5 ] = RtemsTimerReqFireAfter_Pre_State_Inactive;
1141               ctx->Map.pcs[ 5 ] < RtemsTimerReqFireAfter_Pre_State_NA;
1142               ++ctx->Map.pcs[ 5 ]
1143             ) {
1144               ctx->Map.entry = RtemsTimerReqFireAfter_PopEntry( ctx );
1145 
1146               if ( ctx->Map.entry.Skip ) {
1147                 continue;
1148               }
1149 
1150               RtemsTimerReqFireAfter_Prepare( ctx );
1151               RtemsTimerReqFireAfter_TestVariant( ctx );
1152               RtemsTimerReqFireAfter_Cleanup( ctx );
1153             }
1154           }
1155         }
1156       }
1157     }
1158   }
1159 }
1160 
1161 /** @} */