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);
}
发布了40 篇原创文章 · 获赞 2 · 访问量 3063

猜你喜欢

转载自blog.csdn.net/qq_45683435/article/details/104237157