ARM內核寄存器的操作函數

在修改嵌入式底層的參數時需要使用一些內核寄存器的操作,在編譯器中往往都封裝了對應的函數。

1.__ASM uint32_t __get_PSP(void):獲取進程堆棧指針PSP。


2.__ASM void __set_PSP(uint32_t topOfProcStack):設置PSP。

3. __ASM uint32_t __get_MSP(void):獲取主堆棧指針MSP。

4.__ASM void __set_MSP(uint32_t mainStackPointer):設置MSP。

5.__ASM uint32_t __REV16(uint16_t value):反轉半字中字節順序,如0xABCD反轉後得到0xCDAB。

6.__ASM int32_t __REVSH(int16_t value):反轉字節順序,並做符號拓展。就是在__REV16函數得到的結果上再進行一次符號拓展。這兩個函數主要是方便進行大小端的切換。

7.__ASM void __CLREX(void):清除由LDREX指令造成的互斥鎖。LDREX和STREX是Cortex用來實現互斥訪問,保護臨界資源的指令,LDREX執行後,只有離它最近的一條存儲指令(STR,STREX)才能執行,其他的存儲指令都會被駁回,而CLREX就是用於清除互斥訪問狀態的標記。

8.__ASM uint32_t  __get_BASEPRI(void):獲取BASEPRI寄存器的值,優先級號高於該寄存器的中斷都會被屏蔽(優先級號越大,優先級越低),爲零時不屏蔽任何中斷。

9.__ASM void __set_BASEPRI(uint32_t basePri):設置BASEPRI的值。

10.__ASM uint32_t __get_PRIMASK(void):PRIMASK是一個只有一位的寄存器,置位時屏蔽絕大部分的異常中斷,只剩下NMI和HardFault可以響應。

11.__ASM void __set_PRIMASK(uint32_t priMask):設置PRIMASK的值。


12.__ASM uint32_t  __get_FAULTMASK(void):FAULTMASK也是一個只有一位的寄存器,爲1時只有NMI才能響應,其他異常與中斷全部被屏蔽。

13.__ASM void __set_FAULTMASK(uint32_t faultMask):設置FAULTMASK的值。

14.__ASM uint32_t __get_CONTROL(void):獲取CONTROL的值。寄存器CONTROL只有兩位。CONTROL[0]選擇特權級別,0爲特權模式,1爲非特權模式。CONTROL[1]用於選擇堆棧指針,0爲MSP,1爲PSP。

15.__ASM void __set_CONTROL(uint32_t control):設置CONTROL寄存器的值。

以上的函數都是操作ARM內核的特殊寄存器,其中BASEPRI,PRIMASK,FAULTMASK,CONTROL都只能在特權模式下被修改。


    sCon = __get_CONTROL();//獲取當前運行模式
    tCon = sCon & (~CON_BIT_PREVILEGE);//設置爲特權模式
    __set_CONTROL(tCon);
    
    SCB->VTOR = (unsigned int)appAddr;//設定棧頂指針
    s_stackPtr = *(unsigned int *)appAddr;
    runApp = *(AppHandler *)(appAddr + 4);
    
    __set_MSP(s_stackPtr);//設置主堆棧
    __set_PSP(s_stackPtr);//設置進程堆棧

    __asm("PUSH {R0}\n");//執行入棧的彙編語句
    runApp();
    __set_CONTROL(sCon);//還原到之前的運行模式

這段代碼是設定棧頂指針和跳轉到向量表的復位中斷
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章