pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on
entry/exit of interrupts. */
*pxTopOfStack = portINITIAL_XPSR; /* xPSR */
pxTopOfStack--;
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
pxTopOfStack--;
*pxTopOfStack = 0; /* LR */
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
return pxTopOfStack;
}
当一个任务被中断的时候,ARM Cortex-M3处理器就压寄存器入堆栈。pxPortInitialiseStack()修改堆栈使之看来像是即便任务实际上还未开始运行,寄存器就已经被压入了。已知的被存储到堆栈,赋给ARM寄存器xPSR,PC,LR,和R0。freertos操作系统剩余的寄存器R1-R12获得由栈顶指针递减分配给它们的寄存器空间,但没有具体的数据存储在这些寄存器堆栈内。ARM架构告诉我们那些寄存器在复位的时候未被定义,所以一个(非弱智的)程序将不依赖于已知的。
堆栈准备好后,任务几乎是同时准备运行。首先,FreeRTOS禁用中断:我们将开始使用就绪列表和其他任务调度的数据结构,同时我们不希望它们被其他人背着我们私底下修改。
如果这是被创建的第一个任务,FreeRTOS将初始化调度的任务列表。FreeRTOS操作系统的调度有一个就绪列表的数组,pxReadyTasksLists [],为每一个可能的优先级提供一个就绪列表。FreeRTOS也有一些其他的列表用来跟踪任务的挂起,终止和延时。现在这些也都是初始化的。
任何第一次初始化完成后,新的任务以它指定的优先级被加入就绪列表。中断被重新启用,同时新任务的创建完成。
3.5. 列表
任务之后,最常用的FreeRTOS数据结构是列表。FreeRTOS使用列表结构来跟踪调度任务,并执行队列。

图3.3:就绪列表全貌
这个FreeRTOS的列表是一个有着几个有趣的补充的标准循环双链表。下面就是列表元素:
struct xLIST_ITEM
{
portTickType xItemValue; /* The value being listed. In most cases
this is used to sort the list in
descending order. */
volatile struct xLIST_ITEM * pxNext; /* Pointer to the next xListItem in the
list. */
volatile struct xLIST_ITEM * pxPrevious; /* Pointer to the previous xListItem in
the list. */
void * pvOwner; /* Pointer to the object (normally a TCB)
that contains the list item. There is
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-30698-6.html