任務堆棧的創建:
任務堆棧是任務的重要部分,堆棧是RAM中按照“先進先出(FIFO)”的原則組織的一塊連續的存儲空間。爲了滿足任務切換和響應中斷時保存CPU寄存器中的內容及任務調用其他函數時的需要,每個任務都應該有自己的堆棧。
任務堆棧的創建:
#define START_STK_SIZE 512 //堆棧大小
CPU_STK START_TASK_STK[STArT_STK_SIZE] //定義一個數組來作爲任務堆棧
將CPU現在情況導入任務堆棧
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
{
CPU_STK *p_stk;
(void)opt; /* Prevent compiler warning */
p_stk = &p_stk_base[stk_size]; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
*--p_stk = (CPU_STK)0x01000000u; /* xPSR */
*--p_stk = (CPU_STK)p_task; /* Entry Point */
*--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */
*--p_stk = (CPU_STK)0x12121212u; /* R12 */
*--p_stk = (CPU_STK)0x03030303u; /* R3 */
*--p_stk = (CPU_STK)0x02020202u; /* R2 */
*--p_stk = (CPU_STK)p_stk_limit; /* R1 */
*--p_stk = (CPU_STK)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
*--p_stk = (CPU_STK)0x11111111u; /* R11 */
*--p_stk = (CPU_STK)0x10101010u; /* R10 */
*--p_stk = (CPU_STK)0x09090909u; /* R9 */
*--p_stk = (CPU_STK)0x08080808u; /* R8 */
*--p_stk = (CPU_STK)0x07070707u; /* R7 */
*--p_stk = (CPU_STK)0x06060606u; /* R6 */
*--p_stk = (CPU_STK)0x05050505u; /* R5 */
*--p_stk = (CPU_STK)0x04040404u; /* R4 */
return (p_stk);
}
使用創建的任務堆棧
(CPU_STK * )&START_TASK_STK[0], //任務堆棧基地址
(CPU_STK_SIZE)START_STK_SIZE/10, //任務堆棧深度限位
(CPU_STK_SIZE)START_STK_SIZE, //任務堆棧大小
任務堆棧基地址:創建的任務堆棧的頭地址
任務堆棧深度限位:當任務堆棧快滿時的一個最小提示量,最大極限深度
任務堆棧大小:512*4Bits
任務控制塊結構 :
任務控制快是用來記錄與任務相關的信息的數據結構,每個任務都要有自己的任務控制塊。
OS_TCB StartTaskTCB; //創建一個任務控制塊
OS_TCB爲一個結構體,描述了任務控制塊,任務控制塊中的成員變量用戶不能直接訪問,更不可能改變他們
struct os_tcb
{
CPU_STK *StkPtr;
void *ExtPtr;
CPU_STK *StkLimitPtr
OS_TCB *NextPtr;
OS_TCB *Prev
......
#if OS_CFG_DBG_EN > 0u
OS_TCB *DbgPrevPtr;
OS_TCB *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
}
任務控制塊初始化:同樣,函數OSTaskCreate()在創建任務的時候會對任務的任務控制塊進行初始化。
優先級:任務執行的一個優先順序。
UCOSIII中任務優先級數由宏OS_CFG_PRIO_MAX來配置,UCOSIII中數值越小,優先級越高,最低可用優先級就是OS_CFG_PRIO_MAX-1
就緒表:
1.優先級爲映射表OSPrioTbl[]:用來記錄哪個優先級下有任務就緒
CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE];
2.就緒任務列表OSRdyList[]:用來記錄每一個優先級下所有就緒的任務
UCOSIII支持時間片輪轉調度,同一個優先級下可以有多個任務,因此我們還需要在確定是優先級下的哪個任務就緒了
struct os_rdy_list {
OS_TCB *HeadPtr //用於創建鏈表,指向鏈表頭
OS_TCB *TailPtr; //用於創建鏈表,指向鏈表尾
OS_OBJ_QTY NbrEntries; //此優先級下的任務數量
};
時間輪轉調度:執行完一個任務後,這個任務會自動插入到末尾,下一個任務會變成當前執行任務,然後繼續輪轉。