uc/os-ii任務與任務管理

把一個大型任務分解成多個小任務,然後在計算機中通過運行這些小任務,最終達到完成大任務的目的。在μC/OS-II中,與上述那些小任務對應的程序實體就叫做“任務”(實質上是一個線程–有私有空間的任務叫做進程,沒有私有空間的任務叫做線程),μC/OS-II就是一個能對這些小任務的運行進行管理和調度的多任務操作系統。

從應用程序設計的角度來看,μC/OS-II的任務就是一個用戶編寫的C函數和與之相關聯的一些數據結構而構成的一個實體。在內存中應該存有任務的代碼和與該任務配套的堆棧。

一個完整的任務應該有如下三部分:
1. 任務代碼(程序)
2. 任務的私有堆棧(用以保護運行環境)
3. 任務控制塊(提供私有堆棧也是虛擬處理器的位置)

μC/OS-Ⅱ的任務管理函數共有9個:

  • 2個建立任務函數
  • 1個堆棧檢驗函數
  • 1個優先級變更函數
  • 1個任務掛起函數
  • 1個任務恢復函數
  • 1個刪除任務函數
  • 1個請求刪除任務函數
  • 1個任務信息的獲取函數

這些任務管理函數後面再詳細分析,這裏重點講一下任務堆棧。
任務棧是用於保存任務函數中所用寄存器、變量和數據結構的堆棧。µC/OS-Ⅱ的任務棧必須聲明爲OS_STK類型,它有如下特點:(1) 每個任務都可以有自己不同的堆棧空間;(2) 堆棧聲明應放置在函數的外面;(3) 堆棧由連續的內存空間組成。
每個任務在創建的時候都要調用OSTaskStkInit() 初始化任務堆棧。初始化任務堆棧需要清楚處理器平臺堆棧的生長方向,Corex-M3的堆棧是向下生長的。

如下定義的任務堆棧,則棧頂指針應STARTUP_TASK_STK_SIZE-1]

static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE]; //define stack

堆棧初始化在不同的處理器平臺有差異,以下爲在STM32上移植系統的堆棧初始化函數源碼,其實任務堆棧的初始化就是對該任務的虛擬處理器的初始化(復位)。

OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{
    OS_STK *stk;


    (void)opt;                                   /* 'opt' is not used, prevent warning                 */
    stk       = ptos;                            /* Load stack pointer                                 */

                                                 /* Registers stacked as if auto-saved on exception    */
    *(stk)    = (INT32U)0x01000000L;             /* xPSR                                               */
    *(--stk)  = (INT32U)task;                    /* Entry Point                                        */
    *(--stk)  = (INT32U)0xFFFFFFFEL;             /* R14 (LR) (init value will cause fault if ever used)*/
    *(--stk)  = (INT32U)0x12121212L;             /* R12                                                */
    *(--stk)  = (INT32U)0x03030303L;             /* R3                                                 */
    *(--stk)  = (INT32U)0x02020202L;             /* R2                                                 */
    *(--stk)  = (INT32U)0x01010101L;             /* R1                                                 */
    *(--stk)  = (INT32U)p_arg;                   /* R0 : argument                                      */

                                                 /* Remaining registers saved on process stack         */
    *(--stk)  = (INT32U)0x11111111L;             /* R11                                                */
    *(--stk)  = (INT32U)0x10101010L;             /* R10                                                */
    *(--stk)  = (INT32U)0x09090909L;             /* R9                                                 */
    *(--stk)  = (INT32U)0x08080808L;             /* R8                                                 */
    *(--stk)  = (INT32U)0x07070707L;             /* R7                                                 */
    *(--stk)  = (INT32U)0x06060606L;             /* R6                                                 */
    *(--stk)  = (INT32U)0x05050505L;             /* R5                                                 */
    *(--stk)  = (INT32U)0x04040404L;             /* R4                                                 */

    return (stk);
}

OSTaskStkInit()在Cortex-M3中主要功能爲初始化任務的棧的桔構,使任務的棧看起來就好像剛發生了一箇中斷一樣。Cortex-M3中斷時,xPSR、PC、LR、R12、R3--R0自動入棧,R11--R4需手動保存。這裏的值R1--R12 沒有實際意義,相應的數值只爲調試方便。

初始化後各寄存器的值如下這裏寫圖片描述
xPSR=0x0100000,xPSR T位置1,否則第一次執行任務是Fault。
PC=task,指向任務入口。
R14=0xFFFFFFFE,是一個非法值,主要目的是不讓使用R14,任務不能返回。
R0=p_arg,用於傳遞任務的參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章