- Cortex-M是32位RISC处理器,这意味着其数据总线、内部寄存器和指令长度都固定为32位。
- Cortex-M4处理器采用小端模式,这意味着一个32位数据
0x12345678
存放在地址0x20000000
时,地址0x20000003
处存放的是数据0x12
。
- 为了访问效率,Cortex-M处理器要求所有类型的数据(字节、半字、字)都必须进行地址对齐。
- Cortex-M的三级流水线在遇到跳转指令时,需要清空流水线,这会导致性能损失。
- Cortex-M的GPIO引脚在上电复位后,其状态与8051单片机一样,都为高电平输出状态。
- Cortex-M采用改进型哈佛结构,其程序总线和数据总线在硬件上是分离的,但地址空间是统一的。
- 所有16位和32位的Thumb-2指令都可以无差别地访问R0-R12所有通用寄存器。
- 在Cortex-M中,主栈指针MSP和进程栈指针PSP在物理上是两个完全独立的寄存器。
- 执行
BL Label
指令后,返回地址被存入R14(LR),此时LR中存放的是Label
的地址。
MOV PC, LR
这条指令可以实现从子程序返回,其效果与BX LR
完全相同。
- 读取PC寄存器的值,得到的是当前正在执行指令的地址。
- xPSR寄存器由APSR、IPSR和EPSR三部分组成,程序员可以通过
MSR
指令一次性修改xPSR中的所有位。
- IPSR寄存器中的数值为0时,表示当前处理器不处于任何异常或中断服务模式下。
- APSR中的S标志位(饱和标志)与N、Z、C、V标志位一样,可以作为条件转移指令的判断依据。
- 对字变量
LDR R0, [R1]
和半字变量LDRH R0, [R1]
进行非对齐访问时,处理器会产生一个硬件错误(HardFault)。
- Cortex-M的堆栈是向上生长的满栈模型,即SP指针指向栈顶最后一个有效数据,并且每次压栈时SP地址会增加。
- 执行指令
PUSH {R0, R1}
后,SP的值会减8,并且R0被存放在比R1更高的地址上。
- Cortex-M处理器复位后,会首先从地址0x00000004处读取复位向量,然后才从0x00000000处加载MSP的初始值。
- 向量表中的所有地址的最低位(LSB)必须为0,以表示处理器处于ARM状态。
- 中断服务程序的入口地址就是向量表中对应中断号位置存放的32位数值。
- NVIC中,优先级编号为3的中断可以抢占正在执行的优先级编号为5的中断。
- 如果两个中断的抢占优先级和响应优先级都完全相同,当它们同时请求中断时,中断号较小的那个会得到响应。
- Cortex-M响应中断时,硬件会自动压栈8个寄存器,这个过程不会被更高优先级的中断打断。
- 指令
MOVS R0, R1
在传送数据的同时,会根据R1的值更新APSR中的N和Z标志位。
- 执行
MOVW R0, #0x1234
后,R0的值为0x00001234
;紧接着执行MOVT R0, #0x5678
后,R0的值将变为0x56781234
。
LDRSB R0, [R1]
指令会从R1指向的地址加载一个字节,并将其进行零扩展到32位后存入R0。
- 指令
STR R0, [R1], #4
是一个后序变址的存储指令,它会先将R0的值存入R1指向的地址,然后将R1的值加4。
- 多重存储指令
STMDB R0!, {R1-R4}
中,DB
表示在存储之前先将地址递减(Decrease Before)。
B.LT Label
指令的跳转条件是APSR中的N标志位和V标志位不相等。
ITTEE EQ
指令块允许在条件相等时,顺序执行两条Then指令,在条件不等时,顺序执行两条Else指令。
- Cortex-M的位段操作(Bit-banding)本质上是通过软件查表和计算来实现对单个位的原子访问。
- 在STM32中,要将一个GPIO引脚配置为复用功能模式,需要设置
GPIOx_MODER
寄存器中对应的两位为10
。
- 向
GPIOx_BSRR
寄存器的BR1
位写1,可以使GPIOx_ODR
寄存器的第1位清零。
- STM32中的基本定时器(如TIM6, TIM7)也具备PWM输出和输入捕获功能。
- 在配置PWM模式时,定时器的周期由预分频寄存器(PSC)的值决定,占空比由自动重装载寄存器(ARR)的值决定。
- DMA控制器在进行一次数据传输前,必须由CPU设置源地址、目标地址和传输数量,一旦启动后,整个数据块的传输过程无需CPU干预。
- 在C语言中,定义一个指向外设基地址的结构体指针,可以直接通过
>
操作符来读写该外设的所有寄存器。
- Cortex-M处理器从异常返回时,必须执行
RETI
指令。
- 1MB的位段区可以映射到32MB的位段别名区,这意味着对别名区的一个字节地址的访问,会映射到对位段区中一个特定位的操作。
BX R0
指令执行时,如果R0的最低位是0,处理器将尝试切换到ARM状态并引发一个用法错误异常。
CMP R0, #0
指令执行后,如果R0的值为0,则APSR中的Z标志位会被置1。
- 链接寄存器LR (R14) 除了用于保存函数返回地址,在异常发生时,它会被硬件赋予一个特殊的EXC_RETURN值,用于指示异常返回时的处理器状态。
- 进程栈指针PSP只能在特权模式下被修改。
- 指令
LDR R0, =0x12345678
是一条伪指令,汇编器会将其转换为一条MOV
指令或一条LDR
指令从文字池中加载数据。
STRH R0, [R1, R2]
指令表示将R0的低16位存储到地址(R1+R2)处。
- SysTick定时器是一个24位的递减计数器,当它从1减到0时,可以产生一个SysTick异常。
- MPU(内存保护单元)可以把内存划分为多个区域,并为每个区域独立设置访问权限,但它不能防止DMA控制器对受保护区域的非法访问。
- 在一个抢占优先级高于当前执行代码的中断发生时,硬件压栈后,会立即从向量表取址并跳转,这个过程不存在流水线停顿。
- 即使一个GPIO端口被配置为输出模式,程序依然可以读取其
IDR
寄存器来获取该引脚的实际电平状态。
- 使用
__attribute__((packed))
关键字定义的C语言结构体,可以确保其成员变量在内存中是连续存放的,没有为了对齐而产生的填充字节,但这可能会导致非对齐访问,从而降低Cortex-M的访问性能。