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