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);//还原到之前的运行模式

这段代码是设定栈顶指针和跳转到向量表的复位中断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值