任务切换的基础:模拟任务切换时寄存器的保存与恢复
生活随笔
收集整理的這篇文章主要介紹了
任务切换的基础:模拟任务切换时寄存器的保存与恢复
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 任務切換的基礎:模擬任務切換時寄存器的保存與恢復
1 任務切換的基礎:模擬任務切換時寄存器的保存與恢復
需求說明:使用PendSVC觸發異常,在異常處理函數中,保存R4-R11寄存器到緩沖區,再恢復R4-R11寄存器,以模擬任務切換時的寄存器保存與恢復。
文件組織結構如下圖:
main.c:
switch.c:
__asm void PendSV_Handler () {// blockPtr在main.c中定義,定義為:BlockType_t * blockPtr。// 在匯編代碼中,如要引用C中的符號,必 須先用IMPORT導入。有些類似于在C語言中的externIMPORT blockPtr// 加載寄存器存儲地址// LDR R0, =blockPtr ; 將blockPtr變量的地址加載到R0中// LDR R0, [R0] ; 再從該地址加載32位數據值,也就是將blockPtr的值加載到R0中。在main()中,我們已經設置:// BlockType_t block;// block.stackPtr = &stackBuffer[1024];// blockPtr = █// 所以,此時R0的值將會是block結構的起始地址。// LDR R0, [R0] ; 再次加載32位數據,顯示此次就是從block結構開始處加載32位值,根據block結構的定義:// typedef struct _BlockType_t {// unsigned long * stackPtr;// }BlockType_t// 顯然,此時R0的值就是stackPtr的值,也就是&stackBuffer[1024];LDR R0, =blockPtrLDR R0, [R0]LDR R0, [R0]// 保存寄存器// 此時R0的值就是&stackBuffer[1024]。然后,將R4, R5, .. R11寫入到stackBuff緩沖區中,順序不重要,你只需知道其與下面LDMIA的加載次序正好相反即可。寫入前,以R0中地址為基準,每寫入一個寄存器前,先對地址減去4,然后再寫入寄存器值。完成所有寫入之后,將最后的地址覆蓋到R0寄存器中STMDB R0!, {R4-R11}// 將最后的地址寫入到blockPtr中// LDR R1, =blockPtr ; 將blockPtr變量的地址加載到R1中// LDR R1, [R1] ; 再從該地址加載32位數據值,也就是將blockPtr的值加載到R1中。在main()中,我們已經設置:// BlockType_t block;// block.stackPtr = &stackBuffer[1024];// blockPtr = █// 所以,此時R1的值將會是block結構的起始地址。// STR R0, [R1] ; 將前面執行STM執行后,R0的值也就是最后寫入的地址寫入R1中地址指向的位置。// typedef struct _BlockType_t {// unsigned long * stackPtr;// }BlockType_t// 顯然,此時R1的值就是block結構的地址,也就是向將R0的值寫入到stackPtr。最終實現將最后的寫stackBuff的 地址保存到block.stackPtrLDR R1, =blockPtrLDR R1, [R1]STR R0, [R1]// 修改部分寄存器,用于測試// 測試代碼。用于檢查前面的保存(STMDB),以及后面的恢復(LDMIA)是否正確。如果保存和恢復正確,那么執行LDMIA后,R4,R5的值應為恢復之前的值。// 如果需要,可在此添加對其它寄存器的修改測試代碼。ADD R4, R4, #1ADD R5, R5, #1// 恢復寄存器// 與STMDB正好相反,從R0地址對應的存儲單元中讀取多個32位的單元,恢復到R4~R11寄存器。// 注意到,此時,R0為之前向存儲單元寫R4~R11的最后單元的地址,所以此時可以正確恢復。// 具體執行時,首先從當前地址對應的單元處加載數據恢復到寄存器,再將地址+4,如此反復,直到所有寄存器恢復完畢。LDMIA R0!, {R4-R11}// 異常返回// 異常返回指令,不同于從函數調用。此時LR的值不是函數的返回地址,而是一串特定的值,如0xFFFF_FFFxBX LR }參考資料:
總結
以上是生活随笔為你收集整理的任务切换的基础:模拟任务切换时寄存器的保存与恢复的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cortex-M3内核的指令系统
- 下一篇: 点阵的驱动