Cortex-M3处理器采用ARMv7-M架构,其指令集设计充分考虑了嵌入式系统的实时性和效率需求。Thumb-2指令集作为核心,融合了16位和32位指令的优势,在代码密度和性能之间取得了良好平衡。这种混合编码方案使得典型应用的代码尺寸比纯32位架构减少约30%,同时保持了接近32位处理器的性能表现。
指令流水线采用3级设计(取指、解码、执行),通过预取技术和分支预测机制提升流水线效率。特别值得注意的是,所有指令都支持条件执行,这显著减少了分支指令的使用频率,避免了因分支预测失败导致的流水线清空现象。
CBZ(Compare and Branch on Zero)和CBNZ(Compare and Branch on Non-Zero)是专为优化条件分支设计的指令,其机器编码格式如下:
code复制[15:11] | [10:8] | [7:0]
opcode | Rn | imm8
典型应用场景包括循环控制和空指针检查:
assembly复制; 空指针检查示例
CBZ R0, error_handler ; 如果R0为0跳转到错误处理
LDR R1, [R0] ; 安全访问指针内容
; 循环控制示例
mov r5, #10 ; 初始化计数器
loop_start:
; 循环体代码...
subs r5, r5, #1 ; 计数器减1
CBNZ r5, loop_start ; 不为零则继续循环
重要提示:CBZ/CBNZ指令只能使用R0-R7寄存器,且跳转范围限制在+4到+130字节之间。在IT块内部禁止使用这些指令,否则会导致不可预测行为。
IT(If-Then)指令实现了ARM架构的条件执行机制,最多可包含4条后续指令。其语法格式为:
code复制IT{x{y{z}}} cond
其中x/y/z可以是T(Then)或E(Else),cond为基准条件码(如EQ、NE等)。
实际开发中的典型应用:
assembly复制; 三操作数条件执行
ITTTE NE ; 前3条指令条件为NE,第4条为EQ
ANDNE R0, R0, R1 ; 仅当NE时执行AND操作
ADDSNE R2, R2, #1 ; NE时执行带标志位的加法
MOVNE R3, #0 ; NE时立即数传送
MOVEQ R3, #1 ; EQ时设置不同值
; 条件数据处理
CMP R0, #10 ; 比较R0与10
ITE GT ; IF-THEN-ELSE块
ADDGT R1, R0, #5 ; 大于10时加5
ADDLE R1, R0, #2 ; 小于等于时加2
IT指令使用注意事项:
TBB(Table Branch Byte)和TBH(Table Branch Halfword)实现了高效的跳转表功能,特别适合switch-case场景:
assembly复制; 字节跳转表示例
ADR.W R0, jumptable ; 加载跳转表基址
TBB [R0, R1] ; 根据R1索引跳转
jumptable:
.byte (case0-jumptable)/2
.byte (case1-jumptable)/2
.byte (case2-jumptable)/2
case0: ; 处理case 0
case1: ; 处理case 1
case2: ; 处理case 2
; 半字跳转表示例
TBH [PC, R1, LSL #1] ; PC相对寻址,R1索引×2
jumptable_h:
.hword (caseA-jumptable_h)/2
.hword (caseB-jumptable_h)/2
.hword (caseC-jumptable_h)/2
跳转偏移量计算规则:
Cortex-M3的NVIC支持8位优先级配置(实际实现可能只使用高几位),优先级数值越小优先级越高。优先级分组机制通过AIRCR.PRIGROUP字段配置:
| PRIGROUP值 | 抢占优先级位宽 | 子优先级位宽 |
|---|---|---|
| 0 | 7 | 1 |
| 1 | 6 | 2 |
| ... | ... | ... |
| 7 | 0 | 8 |
优先级配置示例代码:
c复制// 设置优先级分组(抢占优先级3位,子优先级5位)
NVIC_SetPriorityGrouping(4);
// 配置UART中断优先级(抢占优先级2,子优先级1)
NVIC_SetPriority(UART_IRQn, (2<<5) | (1<<0));
NVIC寄存器采用位带机制,支持高效的单比特操作:
c复制#define NVIC_ISER0 (*((volatile uint32_t *)0xE000E100))
#define NVIC_ICER0 (*((volatile uint32_t *)0xE000E180))
// 使能UART中断(IRQn=5)
NVIC_ISER0 = (1 << 5);
// 禁用UART中断
NVIC_ICER0 = (1 << 5);
c复制// 手动触发中断(可用于软件中断)
NVIC->ISPR[0] = (1 << 5); // 挂起UART中断
// 清除挂起状态
NVIC->ICPR[0] = (1 << 5);
c复制// 设置UART中断优先级为0xC0
NVIC->IPR[5/4] |= (0xC0 << (8 * (5%4)));
尾链技术(Tail-chaining):
当新中断请求到达时,若其优先级高于当前中断但低于被抢占中断,处理器会直接跳转到新中断服务程序,跳过不必要的状态保存/恢复操作。
迟到机制(Late-arriving):
高优先级中断在保存当前中断上下文期间到达时,处理器会优先处理更高优先级中断,避免不必要的嵌套。
中断屏蔽控制:
assembly复制CPSID i ; 禁用所有中断(设置PRIMASK)
CPSIE i ; 启用中断(清除PRIMASK)
CPSID f ; 禁用所有异常(包括硬错误,设置FAULTMASK)
assembly复制STR R0, [R1] ; 存储数据
DMB ; 确保存储完成
LDR R2, [R3] ; 加载数据
assembly复制STR R0, [R1] ; 修改MPU配置
DSB ; 确保配置生效
ISB ; 清空流水线
assembly复制MSR CONTROL, R0 ; 修改控制寄存器
ISB ; 确保上下文切换
assembly复制MRS R0, PRIMASK ; 读取中断屏蔽状态
ORR R0, R0, #1 ; 设置中断禁止位
MSR PRIMASK, R0 ; 写回寄存器
MRS R0, CONTROL ; 读取线程模式状态
ORR R0, R0, #1 ; 切换到用户模式
MSR CONTROL, R0 ; 写回寄存器
ISB ; 必须的屏障指令
| 寄存器 | 功能描述 | 访问权限 |
|---|---|---|
| PRIMASK | 中断屏蔽控制(1=屏蔽) | 特权 |
| FAULTMASK | 异常屏蔽控制(1=屏蔽) | 特权 |
| BASEPRI | 优先级屏蔽阈值 | 特权 |
| CONTROL | 线程模式/堆栈选择 | 特权/用户 |
code复制中断延迟 = 固定周期(12-16) + 存储器访问延迟 + 上下文保存周期
通过以下措施可缩短延迟:
c复制// 使用DWT周期计数器测量代码执行时间
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
uint32_t start = DWT->CYCCNT;
// 被测代码
uint32_t end = DWT->CYCCNT;
uint32_t cycles = end - start;
assembly复制WFI ; 等待中断(保持时钟运行)
WFE ; 等待事件(可停止时钟)
c复制// 进入低功耗前保存必要状态
__disable_irq();
PWR->CR |= PWR_CR_LPDS; // 配置低功耗模式
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
__WFI(); // 进入深度睡眠