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 RtemsTimerReqReset
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 RtemsTimerReqReset spec:/rtems/timer/req/reset
0063  *
0064  * @ingroup TestsuitesValidationNoClock0
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsTimerReqReset_Pre_Id_Valid,
0071   RtemsTimerReqReset_Pre_Id_Invalid,
0072   RtemsTimerReqReset_Pre_Id_NA
0073 } RtemsTimerReqReset_Pre_Id;
0074 
0075 typedef enum {
0076   RtemsTimerReqReset_Pre_Context_None,
0077   RtemsTimerReqReset_Pre_Context_Interrupt,
0078   RtemsTimerReqReset_Pre_Context_Server,
0079   RtemsTimerReqReset_Pre_Context_NA
0080 } RtemsTimerReqReset_Pre_Context;
0081 
0082 typedef enum {
0083   RtemsTimerReqReset_Pre_Clock_None,
0084   RtemsTimerReqReset_Pre_Clock_Ticks,
0085   RtemsTimerReqReset_Pre_Clock_Realtime,
0086   RtemsTimerReqReset_Pre_Clock_NA
0087 } RtemsTimerReqReset_Pre_Clock;
0088 
0089 typedef enum {
0090   RtemsTimerReqReset_Pre_State_Inactive,
0091   RtemsTimerReqReset_Pre_State_Scheduled,
0092   RtemsTimerReqReset_Pre_State_Pending,
0093   RtemsTimerReqReset_Pre_State_NA
0094 } RtemsTimerReqReset_Pre_State;
0095 
0096 typedef enum {
0097   RtemsTimerReqReset_Post_Status_Ok,
0098   RtemsTimerReqReset_Post_Status_InvId,
0099   RtemsTimerReqReset_Post_Status_NotDef,
0100   RtemsTimerReqReset_Post_Status_NA
0101 } RtemsTimerReqReset_Post_Status;
0102 
0103 typedef enum {
0104   RtemsTimerReqReset_Post_Context_None,
0105   RtemsTimerReqReset_Post_Context_Interrupt,
0106   RtemsTimerReqReset_Post_Context_Server,
0107   RtemsTimerReqReset_Post_Context_Nop,
0108   RtemsTimerReqReset_Post_Context_NA
0109 } RtemsTimerReqReset_Post_Context;
0110 
0111 typedef enum {
0112   RtemsTimerReqReset_Post_Clock_None,
0113   RtemsTimerReqReset_Post_Clock_Ticks,
0114   RtemsTimerReqReset_Post_Clock_Realtime,
0115   RtemsTimerReqReset_Post_Clock_Nop,
0116   RtemsTimerReqReset_Post_Clock_NA
0117 } RtemsTimerReqReset_Post_Clock;
0118 
0119 typedef enum {
0120   RtemsTimerReqReset_Post_State_Scheduled,
0121   RtemsTimerReqReset_Post_State_Nop,
0122   RtemsTimerReqReset_Post_State_NA
0123 } RtemsTimerReqReset_Post_State;
0124 
0125 typedef enum {
0126   RtemsTimerReqReset_Post_Interval_Last,
0127   RtemsTimerReqReset_Post_Interval_Nop,
0128   RtemsTimerReqReset_Post_Interval_NA
0129 } RtemsTimerReqReset_Post_Interval;
0130 
0131 typedef enum {
0132   RtemsTimerReqReset_Post_Routine_Last,
0133   RtemsTimerReqReset_Post_Routine_Nop,
0134   RtemsTimerReqReset_Post_Routine_NA
0135 } RtemsTimerReqReset_Post_Routine;
0136 
0137 typedef enum {
0138   RtemsTimerReqReset_Post_UserData_Last,
0139   RtemsTimerReqReset_Post_UserData_Nop,
0140   RtemsTimerReqReset_Post_UserData_NA
0141 } RtemsTimerReqReset_Post_UserData;
0142 
0143 typedef struct {
0144   uint32_t Skip : 1;
0145   uint32_t Pre_Id_NA : 1;
0146   uint32_t Pre_Context_NA : 1;
0147   uint32_t Pre_Clock_NA : 1;
0148   uint32_t Pre_State_NA : 1;
0149   uint32_t Post_Status : 2;
0150   uint32_t Post_Context : 3;
0151   uint32_t Post_Clock : 3;
0152   uint32_t Post_State : 2;
0153   uint32_t Post_Interval : 2;
0154   uint32_t Post_Routine : 2;
0155   uint32_t Post_UserData : 2;
0156 } RtemsTimerReqReset_Entry;
0157 
0158 typedef enum {
0159   PRE_NONE      = 0,
0160   PRE_INTERRUPT = 1,
0161   PRE_SERVER    = 2
0162 } PreConditionContext;
0163 
0164 typedef enum {
0165   SCHEDULE_NONE  = 0,
0166   SCHEDULE_SOON  = 1,
0167   SCHEDULE_LATER = 2,
0168   SCHEDULE_MAX   = 5
0169 } Scheduling_Ticks;
0170 
0171 /**
0172  * @brief Test context for spec:/rtems/timer/req/reset test case.
0173  */
0174 typedef struct {
0175   /**
0176    * @brief This member contains a valid id of a timer.
0177    */
0178   rtems_id timer_id;
0179 
0180   /**
0181    * @brief This member specifies the ``id`` parameter for the action.
0182    */
0183   rtems_id id_param;
0184 
0185   /**
0186    * @brief This member contains the returned status code of the action.
0187    */
0188   rtems_status_code status;
0189 
0190   /**
0191    * @brief This member contains the user data for Timer Service Routine "A".
0192    */
0193   void *data_a;
0194 
0195   /**
0196    * @brief This member contains the user data for Timer Service Routine "B".
0197    */
0198   void *data_b;
0199 
0200   /**
0201    * @brief This member contains the counter for invocations of Timer Service
0202    *   Routine "A".
0203    */
0204   int invocations_a;
0205 
0206   /**
0207    * @brief This member contains the counter for invocations of Timer Service
0208    *   Routine "B".
0209    */
0210   int invocations_b;
0211 
0212   /**
0213    * @brief This member contains the number of ticks needed to fire the Timer
0214    *   Service Routine.
0215    */
0216   Scheduling_Ticks ticks_till_fire;
0217 
0218   /**
0219    * @brief This member identifier the user data given to the Timer Service
0220    *   Routine when called. It either the address of member data_a or data_b.
0221    */
0222   void **routine_user_data;
0223 
0224   /**
0225    * @brief This member contains a reference to the user data to be used in the
0226    *   next call to the Timer Service Routine.
0227    */
0228   void **scheduled_user_data;
0229 
0230   /**
0231    * @brief This member contains 1 if the Timer Service Routine "A" has been
0232    *   scheduled otherwise 0.
0233    */
0234   int scheduled_invocations_a;
0235 
0236   /**
0237    * @brief This member contains 1 if the Timer Service Routine "B" has been
0238    *   scheduled otherwise 0.
0239    */
0240   int scheduled_invocations_b;
0241 
0242   /**
0243    * @brief This member specifies the number of ticks till the scheduled Timer
0244    *   Service Routine should fire.
0245    */
0246   Scheduling_Ticks scheduled_ticks_till_fire;
0247 
0248   /**
0249    * @brief This member specifies which pre-condition context (none, interrupt
0250    *   context, server context) must be created before the rtems_timer_reset()
0251    *   action gets executed.
0252    */
0253   PreConditionContext pre_cond_contex;
0254 
0255   /**
0256    * @brief This member stores internal clock and context settings of the timer
0257    *   before the execution of the test action.
0258    */
0259   Timer_Classes pre_class;
0260 
0261   /**
0262    * @brief This member stores the state of the timer before the execution of
0263    *   the test action.
0264    */
0265   Timer_States pre_state;
0266 
0267   /**
0268    * @brief This member stores the state of the timer after the execution of
0269    *   the test action.
0270    */
0271   Timer_States post_state;
0272 
0273   /**
0274    * @brief This member stores the scheduling data of the timer before the
0275    *   execution of the test action.
0276    */
0277   Timer_Scheduling_Data pre_scheduling_data;
0278 
0279   /**
0280    * @brief This member stores the scheduling data of the timer after the
0281    *   execution of the test action.
0282    */
0283   Timer_Scheduling_Data post_scheduling_data;
0284 
0285   struct {
0286     /**
0287      * @brief This member defines the pre-condition states for the next action.
0288      */
0289     size_t pcs[ 4 ];
0290 
0291     /**
0292      * @brief If this member is true, then the test action loop is executed.
0293      */
0294     bool in_action_loop;
0295 
0296     /**
0297      * @brief This member contains the next transition map index.
0298      */
0299     size_t index;
0300 
0301     /**
0302      * @brief This member contains the current transition map entry.
0303      */
0304     RtemsTimerReqReset_Entry entry;
0305 
0306     /**
0307      * @brief If this member is true, then the current transition variant
0308      *   should be skipped.
0309      */
0310     bool skip;
0311   } Map;
0312 } RtemsTimerReqReset_Context;
0313 
0314 static RtemsTimerReqReset_Context
0315   RtemsTimerReqReset_Instance;
0316 
0317 static const char * const RtemsTimerReqReset_PreDesc_Id[] = {
0318   "Valid",
0319   "Invalid",
0320   "NA"
0321 };
0322 
0323 static const char * const RtemsTimerReqReset_PreDesc_Context[] = {
0324   "None",
0325   "Interrupt",
0326   "Server",
0327   "NA"
0328 };
0329 
0330 static const char * const RtemsTimerReqReset_PreDesc_Clock[] = {
0331   "None",
0332   "Ticks",
0333   "Realtime",
0334   "NA"
0335 };
0336 
0337 static const char * const RtemsTimerReqReset_PreDesc_State[] = {
0338   "Inactive",
0339   "Scheduled",
0340   "Pending",
0341   "NA"
0342 };
0343 
0344 static const char * const * const RtemsTimerReqReset_PreDesc[] = {
0345   RtemsTimerReqReset_PreDesc_Id,
0346   RtemsTimerReqReset_PreDesc_Context,
0347   RtemsTimerReqReset_PreDesc_Clock,
0348   RtemsTimerReqReset_PreDesc_State,
0349   NULL
0350 };
0351 
0352 static const rtems_time_of_day tod_now      = { 2000, 1, 1, 0, 0, 0, 0 };
0353 static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
0354 static const rtems_time_of_day tod_fire     = { 2000, 1, 2, 0, 0, 0, 0 };
0355 
0356 static Scheduling_Ticks TriggerTimer( const RtemsTimerReqReset_Context *ctx )
0357 {
0358   int ticks_fired = SCHEDULE_NONE;
0359   int invocations_old = ctx->invocations_a + ctx->invocations_b;
0360 
0361   /* Fire the timer service routine for ticks and realtime clock */
0362   int i;
0363   for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
0364     ClockTick();
0365     if ( ctx->invocations_a + ctx->invocations_b > invocations_old ) {
0366       ticks_fired = i;
0367       break;
0368     }
0369   }
0370 
0371   T_rsc_success( rtems_clock_set( &tod_fire ) );
0372 
0373   return ticks_fired;
0374 }
0375 
0376 static void TimerServiceRoutineA(
0377   rtems_id timer_id,
0378   void *user_data
0379 )
0380 {
0381   RtemsTimerReqReset_Context *ctx =
0382     *(RtemsTimerReqReset_Context **) user_data;
0383   ++( ctx->invocations_a );
0384   ctx->routine_user_data = user_data;
0385 }
0386 
0387 static void TimerServiceRoutineB(
0388   rtems_id timer_id,
0389   void *user_data
0390 )
0391 {
0392   RtemsTimerReqReset_Context *ctx =
0393     *(RtemsTimerReqReset_Context **) user_data;
0394   ++( ctx->invocations_b );
0395   ctx->routine_user_data = user_data;
0396 }
0397 
0398 static void RtemsTimerReqReset_Pre_Id_Prepare(
0399   RtemsTimerReqReset_Context *ctx,
0400   RtemsTimerReqReset_Pre_Id   state
0401 )
0402 {
0403   switch ( state ) {
0404     case RtemsTimerReqReset_Pre_Id_Valid: {
0405       /*
0406        * While the ``id`` parameter is valid.
0407        */
0408       ctx->id_param = ctx->timer_id;
0409       break;
0410     }
0411 
0412     case RtemsTimerReqReset_Pre_Id_Invalid: {
0413       /*
0414        * While the ``id`` parameter is invalid.
0415        */
0416       ctx->id_param = RTEMS_ID_NONE;
0417       break;
0418     }
0419 
0420     case RtemsTimerReqReset_Pre_Id_NA:
0421       break;
0422   }
0423 }
0424 
0425 static void RtemsTimerReqReset_Pre_Context_Prepare(
0426   RtemsTimerReqReset_Context    *ctx,
0427   RtemsTimerReqReset_Pre_Context state
0428 )
0429 {
0430   switch ( state ) {
0431     case RtemsTimerReqReset_Pre_Context_None: {
0432       /*
0433        * While the Timer Service Routine has never been scheduled since
0434        * creation of the timer. See also none.
0435        */
0436       ctx->pre_cond_contex = PRE_NONE;
0437       break;
0438     }
0439 
0440     case RtemsTimerReqReset_Pre_Context_Interrupt: {
0441       /*
0442        * While the timer is in interrupt context.
0443        */
0444       ctx->pre_cond_contex = PRE_INTERRUPT;
0445       break;
0446     }
0447 
0448     case RtemsTimerReqReset_Pre_Context_Server: {
0449       /*
0450        * While the timer is in server context.
0451        */
0452       ctx->pre_cond_contex = PRE_SERVER;
0453       break;
0454     }
0455 
0456     case RtemsTimerReqReset_Pre_Context_NA:
0457       break;
0458   }
0459 }
0460 
0461 static void RtemsTimerReqReset_Pre_Clock_Prepare(
0462   RtemsTimerReqReset_Context  *ctx,
0463   RtemsTimerReqReset_Pre_Clock state
0464 )
0465 {
0466   switch ( state ) {
0467     case RtemsTimerReqReset_Pre_Clock_None: {
0468       /*
0469        * While the timer has never been scheduled since creation of the timer.
0470        */
0471       T_eq_int( ctx->pre_cond_contex, PRE_NONE );
0472       break;
0473     }
0474 
0475     case RtemsTimerReqReset_Pre_Clock_Ticks: {
0476       /*
0477        * While the clock used to determine when the timer will fire is the
0478        * ticks based clock.
0479        */
0480       rtems_status_code status;
0481 
0482       if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0483         ctx->scheduled_ticks_till_fire = SCHEDULE_SOON;
0484         ctx->scheduled_invocations_a = 1;
0485         ctx->scheduled_user_data = &ctx->data_a;
0486         status = rtems_timer_fire_after(
0487           ctx->timer_id,
0488           ctx->scheduled_ticks_till_fire,
0489           TimerServiceRoutineA,
0490           ctx->scheduled_user_data
0491         );
0492       } else {
0493         ctx->scheduled_ticks_till_fire = SCHEDULE_LATER;
0494         ctx->scheduled_invocations_b = 1;
0495         ctx->scheduled_user_data = &ctx->data_b;
0496          status = rtems_timer_server_fire_after(
0497           ctx->timer_id,
0498           ctx->scheduled_ticks_till_fire,
0499           TimerServiceRoutineB,
0500           ctx->scheduled_user_data
0501         );
0502       }
0503       T_rsc_success( status );
0504       break;
0505     }
0506 
0507     case RtemsTimerReqReset_Pre_Clock_Realtime: {
0508       /*
0509        * While the clock used to determine when the timer will fire is the
0510        * realtime clock.
0511        */
0512       rtems_status_code status;
0513 
0514       if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
0515         status = rtems_timer_fire_when(
0516           ctx->timer_id,
0517           &tod_schedule,
0518           TimerServiceRoutineA,
0519           &ctx->data_a
0520         );
0521       } else {
0522         status = rtems_timer_server_fire_when(
0523           ctx->timer_id,
0524           &tod_schedule,
0525           TimerServiceRoutineB,
0526           &ctx->data_b
0527         );
0528       }
0529       T_rsc_success( status );
0530       break;
0531     }
0532 
0533     case RtemsTimerReqReset_Pre_Clock_NA:
0534       break;
0535   }
0536 }
0537 
0538 static void RtemsTimerReqReset_Pre_State_Prepare(
0539   RtemsTimerReqReset_Context  *ctx,
0540   RtemsTimerReqReset_Pre_State state
0541 )
0542 {
0543   switch ( state ) {
0544     case RtemsTimerReqReset_Pre_State_Inactive: {
0545       /*
0546        * While the timer is in inactive state.
0547        */
0548       TriggerTimer( ctx );
0549       T_eq_int(
0550         ctx->invocations_a + ctx->invocations_b,
0551         ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
0552       );
0553       ctx->invocations_a = 0;
0554       ctx->invocations_b = 0;
0555       ctx->pre_state = TIMER_INACTIVE;
0556       break;
0557     }
0558 
0559     case RtemsTimerReqReset_Pre_State_Scheduled: {
0560       /*
0561        * While the timer is in scheduled state.
0562        */
0563       /* The timer was already scheduled in the "Clock" pre-conditions. */
0564       ctx->pre_state = TIMER_SCHEDULED;
0565       break;
0566     }
0567 
0568     case RtemsTimerReqReset_Pre_State_Pending: {
0569       /*
0570        * While the timer is in pending state.
0571        */
0572       T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
0573       TriggerTimer( ctx );
0574       T_eq_int( ctx->invocations_a + ctx->invocations_b, 0 );
0575       ctx->pre_state = TIMER_PENDING;
0576       break;
0577     }
0578 
0579     case RtemsTimerReqReset_Pre_State_NA:
0580       break;
0581   }
0582 }
0583 
0584 static void RtemsTimerReqReset_Post_Status_Check(
0585   RtemsTimerReqReset_Context    *ctx,
0586   RtemsTimerReqReset_Post_Status state
0587 )
0588 {
0589   switch ( state ) {
0590     case RtemsTimerReqReset_Post_Status_Ok: {
0591       /*
0592        * The return status of rtems_timer_reset() shall be RTEMS_SUCCESSFUL.
0593        */
0594       T_rsc_success( ctx->status );
0595       break;
0596     }
0597 
0598     case RtemsTimerReqReset_Post_Status_InvId: {
0599       /*
0600        * The return status of rtems_timer_reset() shall be RTEMS_INVALID_ID.
0601        */
0602       T_rsc( ctx->status, RTEMS_INVALID_ID );
0603       break;
0604     }
0605 
0606     case RtemsTimerReqReset_Post_Status_NotDef: {
0607       /*
0608        * The return status of rtems_timer_reset() shall be RTEMS_NOT_DEFINED
0609        */
0610       T_rsc( ctx->status, RTEMS_NOT_DEFINED );
0611       break;
0612     }
0613 
0614     case RtemsTimerReqReset_Post_Status_NA:
0615       break;
0616   }
0617 }
0618 
0619 static void RtemsTimerReqReset_Post_Context_Check(
0620   RtemsTimerReqReset_Context     *ctx,
0621   RtemsTimerReqReset_Post_Context state
0622 )
0623 {
0624   Timer_Classes class;
0625   class = GetTimerClass( ctx->timer_id );
0626 
0627   switch ( state ) {
0628     case RtemsTimerReqReset_Post_Context_None: {
0629       /*
0630        * The timer shall have never been scheduled. See also none.
0631        */
0632       T_eq_int( class, TIMER_DORMANT );
0633       break;
0634     }
0635 
0636     case RtemsTimerReqReset_Post_Context_Interrupt: {
0637       /*
0638        * The timer shall be in interrupt context.
0639        */
0640       T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
0641       break;
0642     }
0643 
0644     case RtemsTimerReqReset_Post_Context_Server: {
0645       /*
0646        * The timer shall be in server context.
0647        */
0648       T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
0649       break;
0650     }
0651 
0652     case RtemsTimerReqReset_Post_Context_Nop: {
0653       /*
0654        * Objects referenced by the ``id`` parameter in past call to
0655        * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
0656        * call. See also Nop.
0657        */
0658       T_eq_int( class, ctx->pre_class );
0659       break;
0660     }
0661 
0662     case RtemsTimerReqReset_Post_Context_NA:
0663       break;
0664   }
0665 }
0666 
0667 static void RtemsTimerReqReset_Post_Clock_Check(
0668   RtemsTimerReqReset_Context   *ctx,
0669   RtemsTimerReqReset_Post_Clock state
0670 )
0671 {
0672   Timer_Classes class;
0673   class = GetTimerClass( ctx->timer_id );
0674 
0675   switch ( state ) {
0676     case RtemsTimerReqReset_Post_Clock_None: {
0677       /*
0678        * The timer shall have never been scheduled.
0679        */
0680       T_eq_int( class, TIMER_DORMANT );
0681       break;
0682     }
0683 
0684     case RtemsTimerReqReset_Post_Clock_Ticks: {
0685       /*
0686        * The timer shall use the ticks based clock.
0687        */
0688       T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
0689       break;
0690     }
0691 
0692     case RtemsTimerReqReset_Post_Clock_Realtime: {
0693       /*
0694        * The timer shall use the realtime clock.
0695        */
0696       T_eq_int(
0697         class & TIMER_CLASS_BIT_TIME_OF_DAY,
0698         TIMER_CLASS_BIT_TIME_OF_DAY
0699       );
0700       break;
0701     }
0702 
0703     case RtemsTimerReqReset_Post_Clock_Nop: {
0704       /*
0705        * Objects referenced by the ``id`` parameter in past call to
0706        * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
0707        * call.
0708        */
0709       T_eq_int( class, ctx->pre_class );
0710       break;
0711     }
0712 
0713     case RtemsTimerReqReset_Post_Clock_NA:
0714       break;
0715   }
0716 }
0717 
0718 static void RtemsTimerReqReset_Post_State_Check(
0719   RtemsTimerReqReset_Context   *ctx,
0720   RtemsTimerReqReset_Post_State state
0721 )
0722 {
0723   switch ( state ) {
0724     case RtemsTimerReqReset_Post_State_Scheduled: {
0725       /*
0726        * The timer shall be in scheduled state.
0727        */
0728       ctx->ticks_till_fire = TriggerTimer( ctx );
0729       T_eq_int( ctx->invocations_a + ctx->invocations_b, 1 );
0730       break;
0731     }
0732 
0733     case RtemsTimerReqReset_Post_State_Nop: {
0734       /*
0735        * Objects referenced by the ``id`` parameter in past call to
0736        * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
0737        * call.
0738        */
0739       T_eq_int( ctx->post_state, ctx->pre_state );
0740       break;
0741     }
0742 
0743     case RtemsTimerReqReset_Post_State_NA:
0744       break;
0745   }
0746 }
0747 
0748 static void RtemsTimerReqReset_Post_Interval_Check(
0749   RtemsTimerReqReset_Context      *ctx,
0750   RtemsTimerReqReset_Post_Interval state
0751 )
0752 {
0753   switch ( state ) {
0754     case RtemsTimerReqReset_Post_Interval_Last: {
0755       /*
0756        * The Timer Service Routine shall be invoked the same number of ticks
0757        * (see tick), as defined by the last scheduled interval, after a point
0758        * in time during the execution of the rtems_timer_reset() call.
0759        */
0760       T_eq_int( ctx->ticks_till_fire, ctx->scheduled_ticks_till_fire );
0761       break;
0762     }
0763 
0764     case RtemsTimerReqReset_Post_Interval_Nop: {
0765       /*
0766        * If and when the Timer Service Routine will be invoked shall not be
0767        * changed by the past call to rtems_timer_reset().
0768        */
0769       /*
0770        * Whether the timer is scheduled has already been tested by the
0771        * "Nop" "State" post-condition above.
0772        */
0773       T_eq_u32(
0774         ctx->post_scheduling_data.interval,
0775         ctx->pre_scheduling_data.interval
0776       );
0777       break;
0778     }
0779 
0780     case RtemsTimerReqReset_Post_Interval_NA:
0781       break;
0782   }
0783 }
0784 
0785 static void RtemsTimerReqReset_Post_Routine_Check(
0786   RtemsTimerReqReset_Context     *ctx,
0787   RtemsTimerReqReset_Post_Routine state
0788 )
0789 {
0790   switch ( state ) {
0791     case RtemsTimerReqReset_Post_Routine_Last: {
0792       /*
0793        * The function reference used to invoke the Timer Service Routine when
0794        * the timer will fire shall be the same one as the last one scheduled.
0795        */
0796       T_eq_int( ctx->invocations_a, ctx->scheduled_invocations_a );
0797       T_eq_int( ctx->invocations_b, ctx->scheduled_invocations_b );
0798       break;
0799     }
0800 
0801     case RtemsTimerReqReset_Post_Routine_Nop: {
0802       /*
0803        * The function reference used for any invocation of the Timer Service
0804        * Routine shall not be changed by the past call to rtems_timer_reset().
0805        */
0806       T_eq_ptr(
0807         ctx->post_scheduling_data.routine,
0808         ctx->pre_scheduling_data.routine
0809       );
0810       break;
0811     }
0812 
0813     case RtemsTimerReqReset_Post_Routine_NA:
0814       break;
0815   }
0816 }
0817 
0818 static void RtemsTimerReqReset_Post_UserData_Check(
0819   RtemsTimerReqReset_Context      *ctx,
0820   RtemsTimerReqReset_Post_UserData state
0821 )
0822 {
0823   switch ( state ) {
0824     case RtemsTimerReqReset_Post_UserData_Last: {
0825       /*
0826        * The user data argument for invoking the Timer Service Routine when the
0827        * timer will fire shall be the same as the last scheduled user data
0828        * argument.
0829        */
0830       T_eq_ptr( ctx->routine_user_data, ctx->scheduled_user_data);
0831       break;
0832     }
0833 
0834     case RtemsTimerReqReset_Post_UserData_Nop: {
0835       /*
0836        * The user data argument used for any invocation of the Timer Service
0837        * Routine shall not be changed by the past call to rtems_timer_reset().
0838        */
0839       T_eq_ptr(
0840         ctx->post_scheduling_data.user_data,
0841         ctx->pre_scheduling_data.user_data
0842       );
0843       break;
0844     }
0845 
0846     case RtemsTimerReqReset_Post_UserData_NA:
0847       break;
0848   }
0849 }
0850 
0851 static void RtemsTimerReqReset_Setup( RtemsTimerReqReset_Context *ctx )
0852 {
0853   rtems_status_code status;
0854   status = rtems_timer_initiate_server(
0855     RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
0856     RTEMS_MINIMUM_STACK_SIZE,
0857     RTEMS_DEFAULT_ATTRIBUTES
0858   );
0859   T_rsc_success( status );
0860 }
0861 
0862 static void RtemsTimerReqReset_Setup_Wrap( void *arg )
0863 {
0864   RtemsTimerReqReset_Context *ctx;
0865 
0866   ctx = arg;
0867   ctx->Map.in_action_loop = false;
0868   RtemsTimerReqReset_Setup( ctx );
0869 }
0870 
0871 /**
0872  * @brief Make sure the timer server is not running and the realtime clock is
0873  *   not set after this test.
0874  */
0875 static void RtemsTimerReqReset_Teardown( RtemsTimerReqReset_Context *ctx )
0876 {
0877   DeleteTimerServer();
0878   UnsetClock();
0879 }
0880 
0881 static void RtemsTimerReqReset_Teardown_Wrap( void *arg )
0882 {
0883   RtemsTimerReqReset_Context *ctx;
0884 
0885   ctx = arg;
0886   ctx->Map.in_action_loop = false;
0887   RtemsTimerReqReset_Teardown( ctx );
0888 }
0889 
0890 static void RtemsTimerReqReset_Prepare( RtemsTimerReqReset_Context *ctx )
0891 {
0892   rtems_status_code status;
0893   status = rtems_timer_create(
0894     rtems_build_name( 'T', 'I', 'M', 'E' ),
0895     &ctx->timer_id
0896   );
0897   T_rsc_success( status );
0898 
0899   ctx->data_a                    = ctx;
0900   ctx->data_b                    = ctx;
0901   ctx->invocations_a             = 0;
0902   ctx->invocations_b             = 0;
0903   ctx->ticks_till_fire           = SCHEDULE_NONE;
0904   ctx->routine_user_data         = NULL;
0905   ctx->scheduled_invocations_a   = 0;
0906   ctx->scheduled_invocations_b   = 0;
0907   ctx->scheduled_ticks_till_fire = SCHEDULE_NONE;
0908   T_rsc_success( rtems_clock_set( &tod_now ) );
0909 }
0910 
0911 static void RtemsTimerReqReset_Action( RtemsTimerReqReset_Context *ctx )
0912 {
0913   GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
0914   ctx->pre_class = GetTimerClass( ctx->timer_id );
0915   ctx->status = rtems_timer_reset( ctx->id_param );
0916   ctx->post_state = GetTimerState( ctx->timer_id );
0917   GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
0918   /* Ignoring return status: the timer server task may be suspended or not. */
0919   rtems_task_resume( GetTimerServerTaskId() );
0920 }
0921 
0922 static void RtemsTimerReqReset_Cleanup( RtemsTimerReqReset_Context *ctx )
0923 {
0924   T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
0925 }
0926 
0927 static const RtemsTimerReqReset_Entry
0928 RtemsTimerReqReset_Entries[] = {
0929   { 1, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_NA,
0930     RtemsTimerReqReset_Post_Context_NA, RtemsTimerReqReset_Post_Clock_NA,
0931     RtemsTimerReqReset_Post_State_NA, RtemsTimerReqReset_Post_Interval_NA,
0932     RtemsTimerReqReset_Post_Routine_NA, RtemsTimerReqReset_Post_UserData_NA },
0933   { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_InvId,
0934     RtemsTimerReqReset_Post_Context_Nop, RtemsTimerReqReset_Post_Clock_Nop,
0935     RtemsTimerReqReset_Post_State_Nop, RtemsTimerReqReset_Post_Interval_Nop,
0936     RtemsTimerReqReset_Post_Routine_Nop, RtemsTimerReqReset_Post_UserData_Nop },
0937   { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_NotDef,
0938     RtemsTimerReqReset_Post_Context_Nop, RtemsTimerReqReset_Post_Clock_Nop,
0939     RtemsTimerReqReset_Post_State_Nop, RtemsTimerReqReset_Post_Interval_Nop,
0940     RtemsTimerReqReset_Post_Routine_Nop, RtemsTimerReqReset_Post_UserData_Nop },
0941   { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_Ok,
0942     RtemsTimerReqReset_Post_Context_Server,
0943     RtemsTimerReqReset_Post_Clock_Ticks,
0944     RtemsTimerReqReset_Post_State_Scheduled,
0945     RtemsTimerReqReset_Post_Interval_Last,
0946     RtemsTimerReqReset_Post_Routine_Last, RtemsTimerReqReset_Post_UserData_Last },
0947   { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_Ok,
0948     RtemsTimerReqReset_Post_Context_Interrupt,
0949     RtemsTimerReqReset_Post_Clock_Ticks,
0950     RtemsTimerReqReset_Post_State_Scheduled,
0951     RtemsTimerReqReset_Post_Interval_Last,
0952     RtemsTimerReqReset_Post_Routine_Last, RtemsTimerReqReset_Post_UserData_Last }
0953 };
0954 
0955 static const uint8_t
0956 RtemsTimerReqReset_Map[] = {
0957   2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 2, 2, 0, 0, 0, 0, 3, 3, 3, 2, 2,
0958   2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
0959   1, 1
0960 };
0961 
0962 static size_t RtemsTimerReqReset_Scope( void *arg, char *buf, size_t n )
0963 {
0964   RtemsTimerReqReset_Context *ctx;
0965 
0966   ctx = arg;
0967 
0968   if ( ctx->Map.in_action_loop ) {
0969     return T_get_scope( RtemsTimerReqReset_PreDesc, buf, n, ctx->Map.pcs );
0970   }
0971 
0972   return 0;
0973 }
0974 
0975 static T_fixture RtemsTimerReqReset_Fixture = {
0976   .setup = RtemsTimerReqReset_Setup_Wrap,
0977   .stop = NULL,
0978   .teardown = RtemsTimerReqReset_Teardown_Wrap,
0979   .scope = RtemsTimerReqReset_Scope,
0980   .initial_context = &RtemsTimerReqReset_Instance
0981 };
0982 
0983 static inline RtemsTimerReqReset_Entry RtemsTimerReqReset_PopEntry(
0984   RtemsTimerReqReset_Context *ctx
0985 )
0986 {
0987   size_t index;
0988 
0989   index = ctx->Map.index;
0990   ctx->Map.index = index + 1;
0991   return RtemsTimerReqReset_Entries[
0992     RtemsTimerReqReset_Map[ index ]
0993   ];
0994 }
0995 
0996 static void RtemsTimerReqReset_TestVariant( RtemsTimerReqReset_Context *ctx )
0997 {
0998   RtemsTimerReqReset_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0999   RtemsTimerReqReset_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1000   RtemsTimerReqReset_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1001   RtemsTimerReqReset_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1002   RtemsTimerReqReset_Action( ctx );
1003   RtemsTimerReqReset_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1004   RtemsTimerReqReset_Post_Context_Check( ctx, ctx->Map.entry.Post_Context );
1005   RtemsTimerReqReset_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
1006   RtemsTimerReqReset_Post_State_Check( ctx, ctx->Map.entry.Post_State );
1007   RtemsTimerReqReset_Post_Interval_Check( ctx, ctx->Map.entry.Post_Interval );
1008   RtemsTimerReqReset_Post_Routine_Check( ctx, ctx->Map.entry.Post_Routine );
1009   RtemsTimerReqReset_Post_UserData_Check( ctx, ctx->Map.entry.Post_UserData );
1010 }
1011 
1012 /**
1013  * @fn void T_case_body_RtemsTimerReqReset( void )
1014  */
1015 T_TEST_CASE_FIXTURE( RtemsTimerReqReset, &RtemsTimerReqReset_Fixture )
1016 {
1017   RtemsTimerReqReset_Context *ctx;
1018 
1019   ctx = T_fixture_context();
1020   ctx->Map.in_action_loop = true;
1021   ctx->Map.index = 0;
1022 
1023   for (
1024     ctx->Map.pcs[ 0 ] = RtemsTimerReqReset_Pre_Id_Valid;
1025     ctx->Map.pcs[ 0 ] < RtemsTimerReqReset_Pre_Id_NA;
1026     ++ctx->Map.pcs[ 0 ]
1027   ) {
1028     for (
1029       ctx->Map.pcs[ 1 ] = RtemsTimerReqReset_Pre_Context_None;
1030       ctx->Map.pcs[ 1 ] < RtemsTimerReqReset_Pre_Context_NA;
1031       ++ctx->Map.pcs[ 1 ]
1032     ) {
1033       for (
1034         ctx->Map.pcs[ 2 ] = RtemsTimerReqReset_Pre_Clock_None;
1035         ctx->Map.pcs[ 2 ] < RtemsTimerReqReset_Pre_Clock_NA;
1036         ++ctx->Map.pcs[ 2 ]
1037       ) {
1038         for (
1039           ctx->Map.pcs[ 3 ] = RtemsTimerReqReset_Pre_State_Inactive;
1040           ctx->Map.pcs[ 3 ] < RtemsTimerReqReset_Pre_State_NA;
1041           ++ctx->Map.pcs[ 3 ]
1042         ) {
1043           ctx->Map.entry = RtemsTimerReqReset_PopEntry( ctx );
1044 
1045           if ( ctx->Map.entry.Skip ) {
1046             continue;
1047           }
1048 
1049           RtemsTimerReqReset_Prepare( ctx );
1050           RtemsTimerReqReset_TestVariant( ctx );
1051           RtemsTimerReqReset_Cleanup( ctx );
1052         }
1053       }
1054     }
1055   }
1056 }
1057 
1058 /** @} */