Threadx activation and deactivation timer timer tx_timer_activate


Analysis of activation and deactivation timer timer function.

tx_timer_activate

_tx_timer_activate_api (TX_TIMER * timer_ptr) to activate the timer has been created.

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

Deactivation timer API has two, one is the application calls the _tx_timer_deactivate_api, a _tx_timer_deactivate operating system is called by other modules of
the application to activate the timer may activate the timer again, _tx_timer_deactivate_api will hold timer remaining time 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 called by other modules for the operating system, only deactivation timer, the timer is deleted from the active list, the remaining time does not need to save the scheduled tx_remaining_ticks.
Such as: _tx_queue_send, _tx_semaphore_cleanup etc.

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);
}
Published 40 original articles · won praise 2 · Views 3063

Guess you like

Origin blog.csdn.net/qq_45683435/article/details/104237157