ucos如何保存局部變量到任務堆棧中


學習ucos好長一段時間,一直沒明白在os中任務是怎么保存局部變量在自己的棧中。今天終於弄明白了。

1.沒有OS時,任務如何保存局部變量

在我的知識體系里,我一直以為單片機中就只有一個棧,以stm32為例,在啟動文件中有怎么一段:

; Amount of memory (in bytes) allocated for Stack

; Tailor this value to your application needs

; <h> Stack Configuration

; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>

; </h>

Stack_Size      EQU     0x00000400

                      AREA    STACK, NOINIT, READWRITE, ALIGN=3

 Stack_Mem    SPACE   Stack_Size

__initial_sp

假設stm32的內存有16Kb,起始地址為,棧向下生長,從啟動文件中可以看到,棧的大小為0x400,我稱之為系統棧,系統棧的范圍為0x0x20000000~0x20000400 。在沒有OS的應用中(裸奔),cpu其實有兩個任務,一個是中斷任務,一個是main函數中的后台任務。當函數調用或者發生中斷時,就使用系統棧保存局部變量和寄存器狀態,也就是SP指向0x0x20000000~0x20000400。

2.ucos中如何保存局部變量

 其實有沒有操作系統都一樣,都把任務中的局部變量和當前的寄存器狀態保存在棧中,在UCOS中一個任務就分配一個棧,假設有兩個任務,申請分配對應的任務棧如下:

   static  OS_STK Task1Stk[128];  //假設任務1的堆棧地址為0x20000500,那么任務1中的局部變量和寄存器狀態將保存在0x20000500~0x20000580

   static  OS_STK Task2Stk[256]; //假設任務1的堆棧地址為0x20000600,那么任務2中的局部變量和寄存器狀態將保存在0x20000600~0x20000700

當任務1運行時,系統使用的棧不再是0x0x20000000~0x20000400,而是0x20000500~0x20000580,任務2運行時,系統中的棧指向0x20000600~0x20000700。那么如何切換SP呢?假設切換到任務1SP:
;保存任務1SP

    LDR     R1, =Task1Stk                                   ; 把SP存在R1中,在任務1中R1等於0x20000500~0x20000580
    LDR     R1, [R1]
    STR     R0, [R1]                                            ; R0 is SP of process being switched out

;切換到任務1的SP

    MSR     PSP, R0                                             ; Load PSP with new process SP

就這樣,在UCOS中的模擬系統棧,生成任務棧,局部變量在任務棧中的分配,而非在系統棧中。而我之前的困惑是以為任務中的局部變量是分配到系統棧中,待任務切換中把系統棧中的內容負責到任務棧中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM