FreeRTOS 源码分析

本文详细介绍了Cortex-M0处理器的中断返回过程及关键指令的使用方法,包括堆栈八字节对齐的要求和实现、PC相对加载指令的应用、多寄存器加载指令的功能与语法、特殊寄存器写入指令的作用以及分支交换指令的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

__asm void vPortSVCHandler( void )
{
PRESERVE8


ldr r3, =pxCurrentTCB /* Restore the context. */
ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */
ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
msr psp, r0 /* Restore the task stack pointer. */
mov r0, #0
msr basepri, r0
orr r14, #0xd
bx r14

}

7.8.15. REQUIRE8 和 PRESERVE8

REQUIRE8 指令指定当前文件要求堆栈八字节对齐。 它设置 REQ8 生成属性以通知链接器。

PRESERVE8 指令指定当前文件保持堆栈八字节对齐。 它设置 PRES8 编译属性以通知链接器。

链接器检查要求堆栈八字节对齐的任何代码是否仅由保持堆栈八字节对齐的代码直接或间接地调用。

语法
REQUIRE8 {bool}
PRESERVE8 {bool}

其中:

bool

是一个可选布尔常数,取值为 {TRUE}{FALSE}

用法

如果您的代码保持堆栈八字节对齐,在需要时,可使用 PRESERVE8 设置文件的 PRES8 编译属性。 如果您的代码不保持堆栈八字节对齐,则可使用PRESERVE8 {FALSE} 确保不设置 PRES8 编译属性。

Note

如果您省略 PRESERVE8PRESERVE8 {FALSE},汇编器会检查修改 sp 的指令,以决定是否设置 PRES8 编译属性。 ARM 建议明确指定PRESERVE8

您可以通过以下方式启用警告:

armasm --diag_warning 1546

有关详细信息,请参阅命令语法

您将会收到类似以下警告:

"test.s", line 37: Warning: A1546W: Stack pointer update potentially 
                                breaks 8 byte stack alignment
       37 00000044         STMFD    sp!,{r2,r3,lr}
示例
REQUIRE8
REQUIRE8     {TRUE}      ; equivalent to REQUIRE8
REQUIRE8     {FALSE}     ; equivalent to absence of REQUIRE8
PRESERVE8    {TRUE}      ; equivalent to PRESERVE8
PRESERVE8    {FALSE}     ; NOT exactly equivalent to absence of PRESERVE8


ldr r3, =pxCurrentTCB/* Restore the context. */

The Cortex-M0 processor supports a useful PC relative load instruction for allowing efficient
literal data accesses. This instruction can be generated when we use the LDR pseudo
instruction for putting an immediate data value into a register. These data are stored alongside
the instructions, called literal pools.

Example:
LDR R0,=0x12345678 ; A pseudo instruction that uses literal load
; to put an immediate data into a register
LDR R0, [PC, #0x40] ; Load a data in current program address
; with offset of 0x40 into R0
LDR R0, label ; Load a data in current program
; referenced by label into R0

ldmia r0!, {r4-r11}

Function Read multiple memory data word into registers and update base register
Syntax LDMIA <Rn>!, {<Ra>, <Rb> ,..} ; Load multiple registers from memory
; and increment base register after completion
Note 

Ra = memory[Rn],

Rb = memory[Rnþ4],
.
and then update Rn to last read address plus 4
Rn, Ra, Rb .. are low registers. For example,
LDMIA R0!, {R1, R2, R5 e R7} ; Read multiple registers, R0 update to address after last
read operation.
LDMFD is another name for the same instruction, which was used for restoring data from
a Full Descending stack, in traditional ARM systems that use software managed stacks.

msr psp, r0

Function Move register into Special Register
Syntax MSR <SpecialReg>, <Rd>
Note Example:
MSRCONTROL, R0; Write R0 intoCONTROL register
MSR PRIMASK, R9; Write R9 into PRIMASK register

mov r0, #0

msr basepri, r0

The BASEPRI register allows interrupts to of certain priority level or lower to be
blocked, and the FAULTMASK provides additional fault management features.

orr r14, #0xd
bx r14

Function Logical OR
Syntax (UAL) ORRS <Rd>, <Rd>, <Rm>
Syntax (Thumb) ORR <Rd>, <Rm>
Note Rd
= OR(Rd, Rm), APSR.N, and APSR.Z update.
Rd and Rm are low registers.

Instruction BX (Branch and Exchange)
Function Branch to an address specified by a register, and change
processor state depending on bit[0] of the register.
Syntax BX <Rm>
Note Because the Cortex-M0 processor only supports Thumb code,
bit[0] of the register content (Rm) must be set to 1, otherwise it
means it is trying to switch to the ARM state and this will
generate a fault exception.

当r14为0xFFFFFFFX,执行是中断返回指令,cortext-m3的做法,X的bit0为1表示返回thumb状态,bit1和bit2分别表示返回后sp用msp还是psp、以及返回到特权模式还是用户模式


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值