📄 osal_timers.c
字号:
*
* @param byte task_id - task id of timer to check
* @param UINT16 event_id - identifier of timer to be checked
*
* @return Return the timer's tick count if found, zero otherwise.
*/
UINT16 osal_get_timeoutEx( byte task_id, UINT16 event_id )
{
halIntState_t intState;
uint16 rtrn = 0;
osalTimerRec_t *tmr;
HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
tmr = osalFindTimer( task_id, event_id );
if ( tmr )
{
rtrn = tmr->timeout;
}
HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
return rtrn;
}
/*********************************************************************
* @fn osal_timer_activate
*
* @brief
*
* Turns the hardware timer on or off
*
* @param byte turn_on - false - turn off, true - turn on
*
* @return none
*/
void osal_timer_activate( byte turn_on )
{
osal_timer_hw_setup( turn_on );
timerActive = turn_on;
}
/*********************************************************************
* @fn osal_timer_num_active
*
* @brief
*
* This function counts the number of active timers.
*
* @return byte - number of timers
*/
byte osal_timer_num_active( void )
{
halIntState_t intState;
byte num_timers = 0;
osalTimerRec_t *srchTimer;
HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
// Head of the timer list
srchTimer = timerHead;
// Count timers in the list
while ( srchTimer != NULL )
{
num_timers++;
srchTimer = srchTimer->next;
}
HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
return num_timers;
}
/*********************************************************************
* @fn osal_timer_hw_setup
*
* @brief
*
* Setup the timer hardware.
*
* @param byte turn_on
*
* @return void
*/
void osal_timer_hw_setup( byte turn_on )
{
if (turn_on)
{
HalTimerStart (OSAL_TIMER, tmr_count );
}
else
{
HalTimerStop (OSAL_TIMER);
}
}
#if defined( POWER_SAVING )
/*********************************************************************
* @fn osal_sleep_timers
*
* @brief
*
* This function will enable interrupts if timers are running.
*
* @param none
*
* @return none
*/
void osal_sleep_timers( void )
{
#ifndef TIMER_INT
if ( osal_timer_num_active() )
osal_set_timer_interrupt( TRUE );
#endif
}
/*********************************************************************
* @fn osal_unsleep_timers
*
* @brief
*
* This function will disable interrupts if timers are running.
*
* @param none
*
* @return none
*/
void osal_unsleep_timers( void )
{
#ifndef TIMER_INT
osal_set_timer_interrupt( FALSE );
#endif
}
#endif
/*********************************************************************
* @fn osal_set_timer_interrupt
*
* @brief
*
* Setup the timer hardware interrupt.
*
* @param byte turn_on
*
* @return void
*********************************************************************/
void osal_set_timer_interrupt( byte turn_on )
{
// Enable or disable timer interrupts
HalTimerInterruptEnable ( OSAL_TIMER, HAL_TIMER_CH_MODE_OUTPUT_COMPARE, turn_on);
}
/*********************************************************************
* @fn osalTimerUpdate
*
* @brief Update the timer structures for a timer tick.
*
* @param none
*
* @return none
*********************************************************************/
static void osalTimerUpdate( uint16 updateTime )
{
halIntState_t intState;
osalTimerRec_t *srchTimer;
osalTimerRec_t *prevTimer;
osalTimerRec_t *saveTimer;
HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
// Update the system time
osal_systemClock += updateTime;
// Look for open timer slot
if ( timerHead != NULL )
{
// Add it to the end of the timer list
srchTimer = timerHead;
prevTimer = (void *)NULL;
// Look for open timer slot
while ( srchTimer )
{
// Decrease the correct amount of time
if (srchTimer->timeout <= updateTime)
srchTimer->timeout = 0;
else
srchTimer->timeout = srchTimer->timeout - updateTime;
// When timeout, execute the task
if ( srchTimer->timeout == 0 )
{
osal_set_event( srchTimer->task_id, srchTimer->event_flag );
// Take out of list
if ( prevTimer == NULL )
timerHead = srchTimer->next;
else
prevTimer->next = srchTimer->next;
// Next
saveTimer = srchTimer->next;
// Free memory
osal_mem_free( srchTimer );
srchTimer = saveTimer;
}
else
{
// Get next
prevTimer = srchTimer;
srchTimer = srchTimer->next;
}
}
#ifdef POWER_SAVING
osal_retune_timers();
#endif
}
HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
}
/*********************************************************************
* @fn osal_update_timers
*
* @brief Update the timer structures for timer ticks.
*
* @param none
*
* @return none
*/
void osal_update_timers( void )
{
osalTimerUpdate( tmr_decr_time );
}
#ifdef POWER_SAVING
/*********************************************************************
* @fn osal_adjust_timers
*
* @brief Update the timer structures for elapsed ticks.
*
* @param none
*
* @return none
*********************************************************************/
void osal_adjust_timers( void )
{
uint16 eTime;
if ( timerHead != NULL )
{
// Compute elapsed time (msec)
eTime = TimerElapsed() / TICK_COUNT;
if ( eTime )
osalTimerUpdate( eTime );
}
}
#endif
#ifdef POWER_SAVING
/*********************************************************************
* @fn osal_retune_timers
*
* @brief
*
* Adjust CPU sleep time to the lowest timeout value. If the timeout
* value is more then RETUNE_THRESHOLD, then the sleep time will be
* RETUNE_THRESHOLD.
*
* @param none
*
* @return none
*********************************************************************/
void osal_retune_timers( void )
{
halIntState_t intState;
uint16 nextTimeout;
HAL_ENTER_CRITICAL_SECTION( intState ); // Hold off interrupts.
// Next occuring timeout
nextTimeout = osal_next_timeout();
// Make sure timer counter can handle it
if ( !nextTimeout || (nextTimeout > RETUNE_THRESHOLD) )
nextTimeout = RETUNE_THRESHOLD;
if (nextTimeout != tmr_decr_time)
{
// Stop the clock
osal_timer_activate( FALSE );
// Alter the rolling time
tmr_decr_time = nextTimeout;
tmr_count = (uint32)nextTimeout * TICK_TIME;
// Restart the clock
osal_timer_activate( TRUE );
}
HAL_EXIT_CRITICAL_SECTION( intState ); // Re-enable interrupts.
}
/*********************************************************************
* @fn osal_next_timeout
*
* @brief
*
* Search timer table to return the lowest timeout value. If the
* timer list is empty, then the returned timeout will be zero.
*
* @param none
*
* @return none
*********************************************************************/
uint16 osal_next_timeout( void )
{
uint16 nextTimeout;
osalTimerRec_t *srchTimer;
if ( timerHead != NULL )
{
// Head of the timer list
srchTimer = timerHead;
nextTimeout = OSAL_TIMERS_MAX_TIMEOUT;
// Look for the next timeout timer
while ( srchTimer != NULL )
{
if (srchTimer->timeout < nextTimeout)
{
nextTimeout = srchTimer->timeout;
}
// Check next timer
srchTimer = srchTimer->next;
}
}
else
{
// No timers
nextTimeout = 0;
}
return ( nextTimeout );
}
#endif // POWER_SAVING
/*********************************************************************
* @fn osal_GetSystemClock()
*
* @brief Read the local system clock.
*
* @param none
*
* @return local clock in milliseconds
*/
uint32 osal_GetSystemClock( void )
{
return ( osal_systemClock );
}
/*********************************************************************
*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -