分析激活定時器和去激活定時器函數。
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);
}