⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ptimer1.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp */#if HAVE_CONFIG_H#include "config.h"#endif #include <assert.h>#include <time.h>#include <errno.h>#include <rtems/system.h>#include <rtems/score/isr.h>#include <rtems/score/thread.h>#include <rtems/score/tod.h>#include <rtems/posix/time.h>/************************************//* These includes are now necessary *//************************************/#include <sys/features.h>#include <rtems/rtems/status.h>#include <rtems/rtems/types.h>#include <rtems/rtems/timer.h>#include <rtems/rtems/clock.h>#include <rtems/posix/psignal.h>#include <rtems/score/wkspace.h>#include <pthread.h>#include <stdio.h>#include <signal.h>#include <rtems/seterr.h>#include <rtems/posix/timer.h>/*****************************//* End of necessary includes *//*****************************//* ************  * Constants * ************/ /*#define DEBUG_MESSAGES *//* * Data for the signals  *//*********************************** * Definition of Internal Functions ***********************************//* *************************************************************************** * TIMER_INITIALIZE_S * *  Description: Initialize the data of a timer  * ***************************************************************************/extern void TIMER_INITIALIZE_S ( int timer_pos );/* *************************************************************************** * _POSIX_Timer_Manager_initialization * *  Description: Initialize the internal structure in which the data of all  *               the timers are stored * ***************************************************************************//* split to reduce minimum size *//* *************************************************************************** * FIRST_FREE_POSITION_F  * *  Description: Returns the first free position in the table of timers. *               If there is not a free position, it returns NO_MORE_TIMERS_C  * ***************************************************************************/int FIRST_FREE_POSITION_F (){   int index;   for (index=0; index<timer_max; index++) {      if ( timer_struct[index].state == STATE_FREE_C ) {         return index;      }   }      /* The function reaches this point only if all the position are occupied */   return NO_MORE_TIMERS_C;}/* *************************************************************************** * TIMER_POSITION_F  * *  Description: Returns the position in the table of timers in which the *               data of the timer are stored. *               If the timer identifier does not exist, it returns *               BAD_TIMER_C * ***************************************************************************/int TIMER_POSITION_F ( timer_t timer_id ){  int index;  for (index=0; index<timer_max; index++ ) {     /* Looks for the position of the timer. The timer must exist and the      * position can not be free */     if ( ( timer_struct[index].timer_id == timer_id ) &&          ( timer_struct[index].state != STATE_FREE_C ) ) {        return index;     }  }  /* If the function reaches this point is because the timer identifier   * is not correct */   return BAD_TIMER_C;}/* *************************************************************************** * COPY_ITIMERSPEC_S  * *  Description: Does a copy of a variable of type struct itimerspec   * ***************************************************************************/void COPY_ITIMERSPEC_S ( const struct itimerspec *source,                          struct itimerspec *target ){   target->it_value.tv_sec     = source->it_value.tv_sec;   target->it_value.tv_nsec    = source->it_value.tv_nsec;   target->it_interval.tv_sec  = source->it_interval.tv_sec;   target->it_interval.tv_nsec = source->it_interval.tv_nsec;}/* *************************************************************************** * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S  * *  Description: This function converts the data of a structure itimerspec  *               into structure rtems_time_of_day  * ***************************************************************************/void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S    ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time ){   unsigned long int seconds;   /* The leap years and the months with 28, 29 or 31 days have not been    * considerated. It will be made in the future */    seconds            = itimer->it_value.tv_sec;   rtems_time->year   = seconds / SECONDS_PER_YEAR_C;   seconds            = seconds % SECONDS_PER_YEAR_C;   rtems_time->month  = seconds / SECONDS_PER_MONTH_C;   seconds            = seconds % SECONDS_PER_MONTH_C;   rtems_time->day    = seconds / SECONDS_PER_DAY_C;   seconds            = seconds % SECONDS_PER_DAY_C;   rtems_time->hour   = seconds / SECONDS_PER_HOUR_C;   seconds            = seconds % SECONDS_PER_HOUR_C;   rtems_time->minute = seconds / SECONDS_PER_MINUTE_C;   seconds            = seconds % SECONDS_PER_MINUTE_C;   rtems_time->second = seconds;   rtems_time->ticks  = itimer->it_value.tv_nsec/                        (NSEC_PER_SEC_C / SEC_TO_TICKS_C);}/* *************************************************************************** * FIRE_TIMER_S  * *  Description: This is the operation that is ran when a timer expires * ***************************************************************************/rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data) {  int               timer_pos;  /* Position in the table of the timer that    			         *  has expirated 			     */  rtems_status_code return_v;   /* Return value of rtems_timer_fire_after    */  int               sig_number; /* Number of the signal to send              */   /* The position of the table of timers that contains the data of the    * expired timer will be stored in "timer_pos". In theory a timer can not   * expire if it has not been created or has been deleted */   timer_pos = TIMER_POSITION_F(timer);  /* Increases the number of expiration of the timer in one unit. */  timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1;  if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec  != 0 ) ||       ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) {     /* The timer must be reprogrammed */     return_v = rtems_timer_fire_after ( timer,                                         timer_struct[timer_pos].ticks,                                         FIRE_TIMER_S,                                         NULL );     /* Stores the time when the timer was started again */      timer_struct[timer_pos].time = _TOD_Current;          /* The state has not to be actualized, because nothing modifies it */     timer_struct[timer_pos].state = STATE_CREATE_RUN_C;  } else {     /* Indicates that the timer is stopped */      timer_struct[timer_pos].state = STATE_CREATE_STOP_C;  }  /*    * The sending of the signal to the process running the handling function   * specified for that signal is simulated   */  sig_number = timer_struct[timer_pos].inf.sigev_signo;  if( pthread_kill ( timer_struct[timer_pos].thread_id ,                     timer_struct[timer_pos].inf.sigev_signo ) ) {     /* XXX error handling */  }   /*   * After the signal handler returns, the count of expirations of the   * timer must be set to 0.   */  timer_struct[timer_pos].overrun = 0;}/* *********************************************************************  *  14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264 * ********************************************************************//* ************** * timer_create * **************/int timer_create(  clockid_t        clock_id,  struct sigevent *evp,  timer_t         *timerid){  rtems_status_code return_v;  /* return value of the operation    */  rtems_id          timer_id;  /* created timer identifier         */  int               timer_pos; /* Position in the table of timers  */  if ( clock_id != CLOCK_REALTIME )    rtems_set_errno_and_return_minus_one( EINVAL ); /*   *  The data of the structure evp are checked in order to verify if they  *  are coherent.   */  if (evp != NULL) {    /* The structure has data */    if ( ( evp->sigev_notify != SIGEV_NONE ) &&          ( evp->sigev_notify != SIGEV_SIGNAL ) ) {       /* The value of the field sigev_notify is not valid */       rtems_set_errno_and_return_minus_one( EINVAL );     }     if ( !evp->sigev_signo )       rtems_set_errno_and_return_minus_one( EINVAL );     if ( !is_valid_signo(evp->sigev_signo) )       rtems_set_errno_and_return_minus_one( EINVAL );  }   /*   *  A timer is created using the primitive rtems_timer_create   */  return_v = rtems_timer_create ( clock_id, &timer_id );  switch (return_v) {     case RTEMS_SUCCESSFUL :        /*        * The timer has been created properly        */         /* Obtains the first free position in the table of timers */        timer_pos = FIRST_FREE_POSITION_F();        if ( timer_pos == NO_MORE_TIMERS_C ) {           /* There is not position for another timers in spite of RTEMS 	    * supports it. It will necessaty to increase the structure used */           rtems_set_errno_and_return_minus_one( EAGAIN );        }        /* Exit parameter */        *timerid  = timer_id;        /* The data of the created timer are stored to use them later */        timer_struct[timer_pos].state     = STATE_CREATE_NEW_C;        /* NEW VERSION*/        timer_struct[timer_pos].thread_id = pthread_self ();                if ( evp != NULL ) {           timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify;           timer_struct[timer_pos].inf.sigev_signo  = evp->sigev_signo;           timer_struct[timer_pos].inf.sigev_value  = evp->sigev_value;        }        timer_struct[timer_pos].timer_id = timer_id;        timer_struct[timer_pos].overrun  = 0;        timer_struct[timer_pos].timer_data.it_value.tv_sec     = 0;        timer_struct[timer_pos].timer_data.it_value.tv_nsec    = 0;        timer_struct[timer_pos].timer_data.it_interval.tv_sec  = 0;        timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;        return 0;     case RTEMS_INVALID_NAME : /* The assigned name is not valid */       rtems_set_errno_and_return_minus_one( EINVAL );     case RTEMS_TOO_MANY :       /* There has been created too much timers for the same process */       rtems_set_errno_and_return_minus_one( EAGAIN );          default :       /*        * Does nothing. It only returns the error without assigning a value        * to errno. In theory, it can not happen because the call to        * rtems_timer_create can not return other different value.         */       rtems_set_errno_and_return_minus_one( EINVAL );  }  /*    * The next sentence is used to avoid singular situations    */  rtems_set_errno_and_return_minus_one( EINVAL );}/* *  14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266 */int timer_delete(  timer_t timerid){  /*  * IDEA: This function must probably stop the timer first and then delete it  *  *       It will have to do a call to rtems_timer_cancel and then another  *       call to rtems_timer_delete.  *       The call to rtems_timer_delete will be probably unnecessary,   *       because rtems_timer_delete stops the timer before deleting it.  */  int               timer_pos;  rtems_status_code status;   /* First the position in the table of timers is obtained */   timer_pos = TIMER_POSITION_F ( timerid );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -