📄 rtos_services.c
字号:
case eTimerSuspended:
return 0 ;
default:
{
}
}
return 0 ;
}
static void s_update_timers()
{
int8u l_timer ;
timer_info *lp_timer ;
// update user defined timers
for (l_timer = 0; l_timer < s_number_of_timers ; l_timer++)
{
lp_timer = s_timers + l_timer ;
if (s_updatable_timer(l_timer) )
{
switch (lp_timer->type)
// WAR STORY
// it is always good practice to place the most common cases at the beginning
// of the switch block, due to performnce reasons (pipeline prefetch related issues...)
{
case eOneShotNonRelease:
{
if (--(lp_timer->deadline) == 0)
{
lp_timer->callback(lp_timer->parameter) ; // fire the callback
// prevent continuous unnecessary updates (let 's_updatable_timer' filter
// out unnecessary timers)
lp_timer->state = eTimerAllocated ;
}
break ;
}
case ePeriod:
{
if (--(lp_timer->deadline) == 0)
{
lp_timer->callback(lp_timer->parameter) ; // fire the callback
lp_timer->deadline = lp_timer->period ; // reload the l_timer
}
break ;
}
case eFlag: // see also 'rtos_flag_timer_inform_in'.
{
// if the timer has already expired before this timer tick,
// its 'too late' counter needs to be incremented
if (lp_timer->deadline == 0)
{
// once the timer has expired, start counting
(*(lp_timer->missed_deadline_counter))++ ;
lp_timer->state = eTimerNotAllocated ; // free this timer - it is done
}
else
{
// the client module (timer owner) should
// poll the timer until the pointed value (int32s*) that it passed
// to EOS is not 0. once that occurs, that pointer to a positive
// value indicating how late the timer was polled in comparison
// with the original deadline.
--lp_timer->deadline ;
}
break ;
}
case eOneShot:
{
if (--(lp_timer->deadline) == 0)
{
lp_timer->callback(lp_timer->parameter) ; // fire the callback
lp_timer->state = eTimerNotAllocated ; // free this timer - it is done
}
break ;
}
}
}
}
}
static void s_timer3_irq (void) interrupt 0x23
{
g_tick_count++ ;
}
static void s_timer6_irq (void) interrupt 0x26
{
#ifdef _DEBUG // a fix for saturation of timer interrupts on PC environment
GPT12E_T6IC = 0 ;
#endif
s_update_timers() ;
#ifdef _DEBUG
GPT12E_T6IC = IC_IE(1) | IC_ILVL(7) | IC_GLVL(1) ; /* Timer 6 interrupt enabled, Level 7, Group 1 */
#endif
}
// setup GPT3, used for timing services
static void s_timer3_setup()
{
#ifdef _DEBUG
GPT12E_T3CON = 0x0480 ; // load timer 3 control register
GPT12E_T3 = 0x00F9 ; // load timer 3 register
GPT12E_T2CON = 0x0027 ; // load timer 2 control register
GPT12E_T2 = 0x0F9 ; // load timer 2 register
#else
/// - prescaler for timer block 1 is 8
/// -----------------------------------------------------------------------
/// Configuration of the GPT1 Core Timer 3:
/// -----------------------------------------------------------------------
/// - timer 3 works in timer mode
/// - external up/down control is disabled
/// - prescaler factor is 8
/// - up/down control bit is set
/// - alternate output function T3OUT (P3.3) is disabled
/// - timer 3 output toggle latch (T3OTL) is set to 0
// will generate an interrupt every 100[祍] at 40[MHz]
GPT12E_T3CON = 0x0080 ; // load timer 3 control register
GPT12E_T3 = 0x01F3 ; // load timer 3 register
/// -----------------------------------------------------------------------
/// Configuration of the GPT1 Auxiliary Timer 2:
/// -----------------------------------------------------------------------
/// - timer 2 works in reload mode
/// - external up/down control is disabled
/// - timer 2 is disabled
/// - timer 2 run bit is reset
GPT12E_T2CON = 0x0020 ; // load timer 2 control register
GPT12E_T2 = 0x01F3 ; // load timer 2 register
#endif
GPT12E_T3IC = IC_IE(1) | IC_ILVL(7) | IC_GLVL(2) ; /* Timer 3 interrupt enabled, Level 7, Group 1 */
GPT12E_T3CON_T3R = 1 ; /* Start Timer */
}
static void s_timer6_setup()
{
GPT12E_T6CON = 0x8081 ; // load timer 6 control register
#ifdef _DEBUG
GPT12E_T6 = 0x00F9 ; // load timer 6 register
GPT12E_CAPREL = 0x00F9 ; // load CAPREL register
#else
/// -----------------------------------------------------------------------
/// Configuration of the GPT2 Core Timer 6:
/// -----------------------------------------------------------------------
/// - timer 6 works in timer mode
/// - prescaler factor is 4
/// - up/down control bit is set
/// - external up/down control is disabled
/// - alternate output function T6OUT (P3.1) is disabled
/// - timer 6 output toggle latch (T6OTL) is set to 0
/// - CAPREL is used as a reload register for the core timer T6
/// - timer 6 is not cleared on a capture
GPT12E_T6CON = 0x8080; // load timer 6 control register
GPT12E_T6 = 0x03E7; // load timer 6 register
/// -----------------------------------------------------------------------
/// Configuration of the GPT2 CAPREL:
/// -----------------------------------------------------------------------
/// - capture T5 into CAPREL is disabled
/// - capture trigger from pin CAPIN
/// - capure is disabled
/// - timer 5 is not cleared on a capture
/// - timer 5 is just captured without any correction
GPT12E_CAPREL = 0x03E7; // load CAPREL register
#endif
GPT12E_T6IC = IC_IE(1) | IC_ILVL(7) | IC_GLVL(1) ; /* Timer 6 interrupt enabled, Level 6, Group 2 */
GPT12E_T6CON_T6R = 1 ; // timer 6 run bit is set
}
static int8u s_find_task(int16s id, int16s *index)
{
int16s n ;
task_info *lp_task ;
for (n = 0; n < MAX_TASKS; n++)
{
lp_task = g_tcb + n ;
if ( (lp_task->id == id) && (lp_task->status != eTaskNotAllocated) )
{
*index = n ;
return 1 ;
}
}
return 0 ;
}
static int16s s_find_next_available_task_index()
{
int16s l_task ;
task_info *lp_task ;
for (l_task = 0; l_task < MAX_TASKS; l_task++)
{
lp_task = g_tcb + l_task ;
if (lp_task->status == eTaskNotAllocated)
{
return l_task ;
}
}
return ERR_MAX_TASKS_ALLOCATED ;
}
static int8u s_find_timer(int16s a_id, int16u *ap_index)
{
int16u l_timer ;
timer_info *lp_timer ;
for (l_timer = 0; l_timer < MAX_TIMERS; l_timer++)
{
lp_timer = s_timers + l_timer ;
if ( (lp_timer->id == a_id) && (lp_timer->state != eTimerNotAllocated) )
{
*ap_index = l_timer ;
return 1 ;
}
}
return 0 ;
}
// this callback is invoked is a timeout waiting for a message has elapsed. see 'rtos_msg_wait'.
static void s_task_wait_msg_timer_expired(int32s a_param)
{
int16s l_index, l_result ;
task_info *lp_task ;
if ( !s_find_task( (int16s)a_param, &l_index))
{
software_error("%s %s %d", resolve_system_message(ERR_TASK_NOT_FOUND), __FILE__, __LINE__ ) ;
}
// WAR STORY
// the test whether the task's status is indeed 'eTaskWaitingForMessage' is needed due to the scenario
// described in the following timing diagram:
//
// wait for message timeout
// task1 ----|
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -