📄 ptimer1.c
字号:
if ( timer_pos == BAD_TIMER_C ) { /* The timer identifier is erroneus */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* The timer is deleted */ status = rtems_timer_delete ( timerid ); if ( status == RTEMS_INVALID_ID ) { /* The timer identifier is erroneus */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* Initializes the data of the timer */ TIMER_INITIALIZE_S ( timer_pos ); return 0;}/* * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 *//* ************** * timer_settime * **************/int timer_settime( timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue){ rtems_status_code return_v; /* Return of the calls to RTEMS */ int timer_pos; /* Position of the timer in the table */ rtems_time_of_day rtems_time; /* Time in RTEMS */ /* First the position in the table of timers is obtained */ timer_pos = TIMER_POSITION_F ( timerid ); if ( timer_pos == BAD_TIMER_C ) { /* The timer identifier is erroneus */ rtems_set_errno_and_return_minus_one( EINVAL ); } if ( value == NULL ) { /* The stucture of times of the timer is free, and then returns an error but the variable errno is not actualized */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* If the function reaches this point, then it will be necessary to do * something with the structure of times of the timer: to stop, start * or start it again */ /* First, it verifies if the timer must be stopped */ if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) { /* The timer is stopped */ return_v = rtems_timer_cancel ( timerid ); /* The old data of the timer are returned */ if ( ovalue ) *ovalue = timer_struct[timer_pos].timer_data; /* The new data are set */ timer_struct[timer_pos].timer_data = *value; /* Indicates that the timer is created and stopped */ timer_struct[timer_pos].state = STATE_CREATE_STOP_C; /* Returns with success */ return 0; } /* * If the function reaches this point, then the timer will have to be * initialized with new values: to start it or start it again */ /* First, it verifies if the structure "value" is correct */ if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) || ( value->it_value.tv_nsec < MIN_NSEC_C ) ) { /* The number of nanoseconds is not correct */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* Then, "value" must be converted from seconds and nanoseconds to clock * ticks, to use it in the calls to RTEMS */ /* It is also necessary to take in account if the time is absolute * or relative */ switch (flags) { case TIMER_ABSTIME: /* The fire time is absolute: * It has to use "rtems_time_fire_when" */ /* First, it converts from struct itimerspec to rtems_time_of_day */ ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time ); return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL); switch ( return_v ) { case RTEMS_SUCCESSFUL: /* The timer has been started and is running */ /* Actualizes the data of the structure and * returns the old ones in "ovalue" */ if ( ovalue ) *ovalue = timer_struct[timer_pos].timer_data; timer_struct[timer_pos].timer_data = *value; /* It indicates that the time is running */ timer_struct[timer_pos].state = STATE_CREATE_RUN_C; /* Stores the time in which the timer was started again */ timer_struct[timer_pos].time = _TOD_Current; return 0; break; case RTEMS_INVALID_ID: /* XXX error handling */ break; case RTEMS_NOT_DEFINED: /* XXX error handling */ break; case RTEMS_INVALID_CLOCK: /* XXX error handling */ break; default: break; } break; case TIMER_RELATIVE_C: /* The fire time is relative: * It has to use "rtems_time_fire_after" */ /* First, it converts from seconds and nanoseconds to ticks */ /* The form in which this operation is done can produce a lost * of precision of 1 second */ /* This is the process to convert from nanoseconds to ticks * * There is a tick every 10 miliseconds, then the nanoseconds are * divided between 10**7. The result of this operation will be the * number of ticks */ timer_struct[timer_pos].ticks = ( SEC_TO_TICKS_C * value->it_value.tv_sec ) + ( value->it_value.tv_nsec / (NSEC_PER_SEC_C / SEC_TO_TICKS_C)); return_v = rtems_timer_fire_after ( timerid, timer_struct[timer_pos].ticks, FIRE_TIMER_S, NULL ); switch (return_v) { case RTEMS_SUCCESSFUL: /* The timer has been started and is running */ /* Actualizes the data of the structure and * returns the old ones in "ovalue" */ if ( ovalue ) *ovalue = timer_struct[timer_pos].timer_data; timer_struct[timer_pos].timer_data = *value; /* It indicates that the time is running */ timer_struct[timer_pos].state = STATE_CREATE_RUN_C; /* Stores the time in which the timer was started again */ timer_struct[timer_pos].time = _TOD_Current; return 0; break; case RTEMS_INVALID_ID: /* The timer identifier is not correct. In theory, this * situation can not occur, but the solution is easy */ rtems_set_errno_and_return_minus_one( EINVAL ); break; case RTEMS_INVALID_NUMBER: /* In this case, RTEMS fails because the values of timing * are incorrect */ /* * I do not know if errno must be actualized * * errno = EINVAL; */ rtems_set_errno_and_return_minus_one( EINVAL ); break; default: break; } break; default: break; /* It does nothing, although it will be probably necessary to * return an error */ } /* To avoid problems */ return 0;}/* * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 *//* ************** * timer_gettime * **************/int timer_gettime( timer_t timerid, struct itimerspec *value){ /* * IDEA: This function does not use functions of RTEMS to the handle * of timers. It uses some functions for managing the time. * * A possible form to do this is the following: * * - When a timer is initialized, the value of the time in * that moment is stored. * - When this function is called, it returns the difference * between the current time and the initialization time. */ rtems_time_of_day current_time; int timer_pos; unsigned32 hours; unsigned32 minutes; unsigned32 seconds; unsigned32 ticks; unsigned32 nanosec; /* Reads the current time */ current_time = _TOD_Current; timer_pos = TIMER_POSITION_F ( timerid ); if ( timer_pos == BAD_TIMER_C ) { /* The timer identifier is erroneus */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* Calculates the difference between the start time of the timer and * the current one */ hours = current_time.hour - timer_struct[timer_pos].time.hour; if ( current_time.minute < timer_struct[timer_pos].time.minute ) { minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute; hours--; } else { minutes = current_time.minute - timer_struct[timer_pos].time.minute; } if ( current_time.second < timer_struct[timer_pos].time.second ) { seconds = 60 - timer_struct[timer_pos].time.second + current_time.second; minutes--; } else { seconds = current_time.second - timer_struct[timer_pos].time.second; } if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) { ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks; seconds--; } else { ticks = current_time.ticks - timer_struct[timer_pos].time.ticks; } /* The time that the timer is running is calculated */ seconds = hours * 60 * 60 + minutes * 60 + seconds; nanosec = ticks * 10 * /* msec */ 1000 * /* microsec */ 1000; /* nanosec */ /* Calculates the time left before the timer finishes */ value->it_value.tv_sec = timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds; value->it_value.tv_nsec = timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec; value->it_interval.tv_sec = timer_struct[timer_pos].timer_data.it_interval.tv_sec; value->it_interval.tv_nsec = timer_struct[timer_pos].timer_data.it_interval.tv_nsec; return 0;}/* * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 *//* ***************** * timer_getoverrun * *****************/int timer_getoverrun( timer_t timerid){ /* * IDEA: This function must count the times the timer expires. * * The expiration of a timer must increase by one a counter. * After the signal handler associated to the timer finishs * its execution, FIRE_TIMER_S will have to set this counter to 0. */ int timer_pos; /* Position of the timer in the structure */ int overrun; /* Overflow count */ timer_pos = TIMER_POSITION_F ( timerid ); if ( timer_pos == BAD_TIMER_C ) { /* The timer identifier is erroneus */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* The overflow count of the timer is stored in "overrun" */ overrun = timer_struct[timer_pos].overrun; /* It is set to 0 */ timer_struct[timer_pos].overrun = 0; return overrun;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -