Threadx 激活定時器和去激活定時器tx_timer_activate


分析激活定時器和去激活定時器函數。

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章