分析激活定时器和去激活定时器函数。
tx_timer_activate
_tx_timer_activate_api(TX_TIMER *timer_ptr) 用来激活已经创建的定时器。
UINT _tx_timer_activate_api(TX_TIMER *timer_ptr)
{
/* Check for an already active timer or a timer with a zero
expiration. */
#def 如果定时器已经激活或者剩余时间为0,那就不需要激活,直接返回
if ((timer_ptr -> tx_timer_internal.tx_list_head) ||
(!timer_ptr -> tx_timer_internal.tx_remaining_ticks))
{
/* Timer is already active or is being activated with a zero
expiration. */
return (TX_ACTIVATE_ERROR);
}
/* Call actual activation function. */
#def 继续激活定时器,参数为TX_INTERNAL_TIMER指针
_tx_timer_activate(&(timer_ptr -> tx_timer_internal));
/* Return TX_SUCCESS. */
return (TX_SUCCESS);
}
_tx_timer_activate:
UINT _tx_timer_activate(TX_INTERNAL_TIMER *timer_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_INTERNAL_TIMER **timer_list;
REG_3 UINT expiration_time;
/* Disable interrupts. */
#def 禁止中断,防止下面操作被打断
TX_DISABLE
/* Determine if the timer still needs activation. */
#def 还是先判断剩余时间不为0,并且没有被激活。虽然前面判断过但关中断前有可能线程被抢占后关闭了这个定时器,是否应该先判断timer_ptr 不为null?
if ((timer_ptr -> tx_remaining_ticks) &&
(timer_ptr -> tx_list_head == TX_NULL))
{
/* Activate the timer. */
/* Calculate the amount of time remaining for the timer. */
#def 如果剩余tick大于32,那么插入到从当前开始的第32个,注意回绕;
#def 第32个tick 超时处理时,会重新计算在插入合适位置
if (timer_ptr -> tx_remaining_ticks > TX_TIMER_ENTRIES)
{
/* Set expiration time to the maximum number of entries. */
expiration_time = TX_TIMER_ENTRIES - 1;
}
else
{
/* Timer value fits in the timer entries. */
/* Set the expiration time. */
expiration_time = (UINT) timer_ptr -> tx_remaining_ticks - 1;
}
/* At this point, we are ready to put the timer on one of
the timer lists. */
/* Calculate the proper place for the timer. */
#def 上面expiration_time剩余时间减了1,因为_tx_timer_current_ptr 已经进行了加1,为下一个tick
#def 找到对应的挂载链表,当前节拍时间+剩余tick
timer_list = _tx_timer_current_ptr + expiration_time;
#def 如果大于了最后一个位置,从第一个继续算。回绕
if (timer_list >= _tx_timer_list_end)
{
/* Wrap from the beginning of the list. */
timer_list = _tx_timer_list_start +
(timer_list - _tx_timer_list_end);
}
/* Now put the timer on this list. */
#def 插入到前面选择的timer_list 链表中,插入到链表的最后面
if (*timer_list)
{
/* This list is not NULL, add current timer to the end. */
timer_ptr -> tx_active_next = *timer_list;
timer_ptr -> tx_active_previous = (*timer_list) -> tx_active_previous;
(timer_ptr -> tx_active_previous) -> tx_active_next = timer_ptr;
(*timer_list) -> tx_active_previous = timer_ptr;
#def tx_list_head 指向链表头部,标志了已经插入到了激活链表
timer_ptr -> tx_list_head = timer_list;
}
else
{
/* This list is NULL, just put the new timer on it. */
/* Setup the links in this timer. */
timer_ptr -> tx_active_next = timer_ptr;
timer_ptr -> tx_active_previous = timer_ptr;
#def tx_list_head 指向链表头部,标志了已经插入到了激活链表
timer_ptr -> tx_list_head = timer_list;
/* Setup the list head pointer. */
*timer_list = timer_ptr;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Return TX_SUCCESS. */
return (TX_SUCCESS);
}
tx_timer_deactivate
去激活定时器API有两个,一个是应用程序调用的_tx_timer_deactivate_api,一个是操作系统其它模块调用的_tx_timer_deactivate
应用程序去激活定时器后,可能会再次激活定时器, _tx_timer_deactivate_api中会保持定时器剩余时间tx_remaining_ticks
#define tx_timer_deactivate _tx_timer_deactivate_api
_tx_timer_deactivate_api
UINT _tx_timer_deactivate_api(TX_TIMER *timer_ptr)
{
TX_INTERRUPT_SAVE_AREA
REG_1 TX_INTERNAL_TIMER *internal_ptr; /* Internal timer pointer */
REG_2 ULONG ticks_left; /* Ticks left before expiration */
/* Setup internal timer pointer. */
internal_ptr = &(timer_ptr -> tx_timer_internal);
/* Disable interrupts while the remaining time before expiration is
calculated. */
#def 禁止中断
TX_DISABLE
/* Determine if the head pointer is within the timer expiration list. */
#def 检查去激活定时器链表头部在定时器链表数组中
if ((internal_ptr -> tx_list_head >= _tx_timer_list_start) &&
(internal_ptr -> tx_list_head < _tx_timer_list_end))
{
/* This timer is active and has not yet expired. */
/* Calculate the amount of time that has elapsed since the timer
was activated. */
/* Is this timer's entry after the current timer pointer? */
#def 计算出定时器超时节拍和当前节拍差值,也就是定时器所在链表和当前链表差值
#def 当前时间就是从上次插入链表已经走过的时间
if (internal_ptr -> tx_list_head >= _tx_timer_current_ptr)
{
/* Calculate ticks left to expiration - just the difference between this
timer's entry and the current timer pointer. */
ticks_left = (internal_ptr -> tx_list_head - _tx_timer_current_ptr) + 1;
}
else
{
#def 回绕时计算
/* Calculate the ticks left with a wrapped list condition. */
ticks_left = (internal_ptr -> tx_list_head - _tx_timer_list_start);
ticks_left = ticks_left + (_tx_timer_list_end - _tx_timer_current_ptr) + 1;
}
/* Adjust the remaining ticks accordingly. */
#def 计算剩余时间,如果之前插入链表时,剩余时间大于32,现在要先减去32,在加上前面计算的差值
if (internal_ptr -> tx_remaining_ticks > TX_TIMER_ENTRIES)
{
/* Subtract off the last full pass through the timer list and add the
time left. */
internal_ptr -> tx_remaining_ticks =
(internal_ptr -> tx_remaining_ticks - TX_TIMER_ENTRIES) + ticks_left;
}
else
{
/* Just put the ticks left into the timer's remaining ticks. */
#def 之前插入链表时,定时时间在32以内,剩余时间就是前面计算的差值
internal_ptr -> tx_remaining_ticks = ticks_left;
}
}
/* Determine if the timer still needs deactivation. */
#def 删除定时器从链表中,先判断还在链表中
if (internal_ptr -> tx_list_head)
{
/* See if this is the only timer in the list. */
#def 对应数组链表中只有这一个定时器
if (internal_ptr == internal_ptr -> tx_active_next)
{
/* Yes, the only timer on the list. */
/* Determine if the head pointer needs to be updated. */
if (*(internal_ptr -> tx_list_head) == internal_ptr)
{
/* Update the head pointer. */
*(internal_ptr -> tx_list_head) = TX_NULL;
}
/* Clear the timer's list head pointer. */
internal_ptr -> tx_list_head = TX_NULL;
}
else
{
#def 链表中有多个定时器
/* At least one more timer is on the same expiration list. */
/* Update the links of the adjacent timers. */
(internal_ptr -> tx_active_next) -> tx_active_previous =
internal_ptr -> tx_active_previous;
(internal_ptr -> tx_active_previous) -> tx_active_next =
internal_ptr -> tx_active_next;
/* Determine if the head pointer needs to be updated. */
if (*(internal_ptr -> tx_list_head) == internal_ptr)
{
/* Update the next timer in the list with the list head
pointer. */
(internal_ptr -> tx_active_next) -> tx_list_head = internal_ptr -> tx_list_head;
/* Update the head pointer. */
*(internal_ptr -> tx_list_head) = internal_ptr -> tx_active_next;
}
/* Clear the timer's list head pointer. */
#def tx_list_head 设置为空
internal_ptr -> tx_list_head = TX_NULL;
}
}
/* Restore interrupts to previous posture. */
TX_RESTORE
/* Return TX_SUCCESS. */
return (TX_SUCCESS);
}
_tx_timer_deactivate
_tx_timer_deactivate用于操作系统其它模块调用,只需去激活定时器,把定时器从激活链表中删除,不需要保存定时剩余时间tx_remaining_ticks 。
如:_tx_queue_send,_tx_semaphore_cleanup等等
UINT _tx_timer_deactivate(TX_INTERNAL_TIMER *timer_ptr)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* Determine if the timer still needs deactivation. */
#def 删除定时器从链表中,先判断还在链表中
if (timer_ptr -> tx_list_head)
{
/* Deactivate the timer. */
/* See if this is the only timer in the list. */
if (timer_ptr == timer_ptr -> tx_active_next)
{
#def 对应数组链表中只有这一个定时器
/* Yes, the only timer on the list. */
/* Determine if the head pointer needs to be updated. */
if (*(timer_ptr -> tx_list_head) == timer_ptr)
{
/* Update the head pointer. */
*(timer_ptr -> tx_list_head) = TX_NULL;
}
/* Clear the timer's list head pointer. */
#def tx_list_head 设置为空
timer_ptr -> tx_list_head = TX_NULL;
}
else
{
#def 链表中有多个定时器
/* At least one more timer is on the same expiration list. */
/* Update the links of the adjacent timers. */
(timer_ptr -> tx_active_next) -> tx_active_previous =
timer_ptr -> tx_active_previous;
(timer_ptr -> tx_active_previous) -> tx_active_next =
timer_ptr -> tx_active_next;
/* Determine if the head pointer needs to be updated. */
if (*(timer_ptr -> tx_list_head) == timer_ptr)
{
/* Update the next timer in the list with the list head
pointer. */
(timer_ptr -> tx_active_next) -> tx_list_head = timer_ptr -> tx_list_head;
/* Update the head pointer. */
*(timer_ptr -> tx_list_head) = timer_ptr -> tx_active_next;
}
/* Clear the timer's list head pointer. */
#def tx_list_head 设置为空
timer_ptr -> tx_list_head = TX_NULL;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Return TX_SUCCESS. */
return (TX_SUCCESS);
}