FreeRTOS Time Management--Analysis of Two Delay Lists

The task scheduling of FreeRTOS generally uses the system tick clock. Each time the system tick clock is interrupted, 1 is added to record the number of system tick clock interruptions. The kernel will compare all blocked tasks with this variable to determine whether it has timed out. Means the waiting time is up and can be executed.

The data type of the variable xTickCount is related to the specific hardware. The 32-bit architecture hardware is generally an unsigned 32-bit variable, and the 8-bit or 16-bit architecture is generally an unsigned 16-bit variable. Even for 32-bit variables, xTickCount will overflow after accumulating to 0xFFFFFFFF. Therefore, it is necessary to judge whether the variable xTickCount overflows in the program. If it overflows (xTickCount is 0), call the macro taskSWITCH_DELAYED_LISTS() to exchange the delay list pointer and the overflow delay list pointer.

taskSWITCH_DELAYED_LISTS()                          
{                                                                                                   
    List_t *pxTemp;                                                                                 

    configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) );                                     

    pxTemp = pxDelayedTaskList;                                                                     
    pxDelayedTaskList = pxOverflowDelayedTaskList;                                                  
    pxOverflowDelayedTaskList = pxTemp;                                                             
    xNumOfOverflows++;                                                                              
    prvResetNextTaskUnblockTime();                                                                  
}

To solve the xTickCount overflow problem, FreeRTOS uses two delay lists: xDelayedTaskList1 and xDelayedTaskList2. And use the delay list pointer pxDelayedTaskList and the overflow delay list pointer pxOverflowDelayedTaskList to point to the above delay list 1 and delay list 2 respectively (when creating a task, point the delay list pointer to the delay list).
Note: The two delay list pointer variables and the two delay list variables above are static local variables defined in tasks.c.

For example, use the API delay function vTaskDelay( xTicksToDelay ) to delay the task by xTicksToDelay system tick cycles. The delay function will take the current system tick interruption times xTickCount as a reference, this value plus the delay time xTicksToDelay specified by the parameter, that is, xTickCount+ xTicksToDelay , is the next time to wake up the task. xTickCount+xTicksToDelay will be recorded in the task TCB and linked to the delay list along with the task. If the kernel determines that xTickCount+ xTicksToDelay overflows (greater than the maximum value that can be represented by 32 bits), it will hook the current task to the list pointed to by the list pointer pxOverflowDelayedTaskList, otherwise it will be hooked to the list pointed to by the list pointer pxDelayedTaskList. Tasks are inserted into the delay list sequentially according to the delay time.

xTimeToWake = xTickCount + xTicksToWait;

listSET_LIST_ITEM_VALUE(&(pxCurrentTCB->xStateListItem), xTimeToWake);

/*时间值已经溢出*/
if (xTimeToWake < xTickCount)
{                                                                                                                 
    vListInsert(pxOverflowDelayedTaskList, &(pxCurrentTCB->xStateListItem));
}
else
{
    vListInsert(pxDelayedTaskList, &(pxCurrentTCB->xStateListItem));

    if (xTimeToWake < xNextTaskUnblockTime)
    {
        xNextTaskUnblockTime = xTimeToWake;
    }
    else
    {
        mtCOVERAGE_TEST_MARKER();
    }
}

Therefore, when the system tick interrupt times counter xTickCount overflows, the delay list pointer pxDelayedTaskList and the overflow delay list pointer pxOverflowDelayedTaskList must be exchanged to correctly process the delayed task.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325854559&siteId=291194637