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、以及返回到特权模式还是用户模式


FreeRTOS是一个面向嵌入式系统的实时操作系统内核,具有轻量级、可移植、可扩展、开源等特性。下面是对FreeRTOS源码的简要讲解: 1. 代码结构:FreeRTOS源码包括内核代码和移植层代码,其中内核代码主要包括任务管理、调度器、时间管理、内存管理、中断管理等核心模块,移植层代码则负责将内核代码适配到不同的硬件平台上。 2. 任务管理:FreeRTOS中的任务是基本的执行单元,通过任务管理模块可以创建、删除、挂起、恢复、设置任务优先级等操作,使得任务能够得到有效的管理和调度。 3. 调度器:FreeRTOS中采用优先级抢占式调度算法,任务的优先级越高则被调度的概率越大。调度器模块负责将任务按照优先级进行调度,并且提供了任务切换和上下文保存的功能。 4. 时间管理:FreeRTOS中提供了多种时间管理方式,包括软件定时器、硬件定时器、时间片轮转等,可以满足不同应用场景下的时间要求。 5. 内存管理:FreeRTOS中采用了三种不同的内存管理方式,包括静态内存管理、动态内存管理和内存池管理,可以有效地管理内存资源。 6. 中断管理:FreeRTOS中提供了丰富的中断管理功能,包括中断嵌套、中断控制、中断处理等,可以有效地处理各种中断情况。 总的来说,FreeRTOS源码具有清晰的结构、丰富的功能和高度的可移植性,对于嵌入式系统开发来说是一个非常优秀的实时操作系统内核。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值