目录
- 实现 CM3
- 流水线
- CM3 详细框图
- CM3 总线接口
- 总线连接模板
- 异常
- 异常类型
- 优先级定义
- 优先级组
- 向量表
- 中断输入于挂起
- NMI
- 中断挂起
- Fault 类异常
- 总线 faults
- 存储器管理 faults
- 用法 faults
- SVC 与 PendSV
实现 CM3
流水线
CM3 处理器使用 3 级流水线,分别是:取指,解码和执行
CM3 有时候会一次取出两个 16 位指令(合计 32 位指令),先处理一个然后等一个周期后再处理下一个
处于对 Thumb 兼容性考虑,取 PC 时,会返回当前指令地址+4 值
处理器内核预取单元有一个指令缓冲区
,让后续执行的指令在这里排队
CM3 详细框图
缩写 | 含义 |
---|---|
NVIC | 嵌套向量中断控制器 |
SYSTICK Timer | 一个简易的周期定时器,用于提供时基,亦被操作系统所使用 |
MPU | 存储器保护单元(可选) |
CM3BusMatrix | 内部的 AHB 互连 |
AHB to APB | 把 AHB 转换为 APB 的总线桥 |
SW-DP/SWJ-DP | 串行线调试端口/串行线 JTAG 调试端口。通过串行线调试协议或者是传统的 JTAG 协议(专用于 SWJ-DP),都可以用于实现与调试接口的连接 |
AHB-AP AHB | 访问端口,它把串行线/SWJ 接口的命令转换成 AHB 数据传送 |
ETM | 嵌入式跟踪宏单元(可选组件),调试用。 用于处理指令跟踪 |
DWT | 数据观察点及跟踪单元,调试用。这是一个处理数据观察点功能的模块 |
ITM | 仪器化跟踪宏单元 |
TPIU | 跟踪单元的接口单元。所有跟踪单元发出的调试信息都要先送给它,它再转发给外部跟踪捕获硬件的 |
FPB Flash | 地址重载及断点单元 |
ROM 表 | 一个小的查找表,其中存储了配置信息 |
CM3 处理器中各个重要模块介绍:
- CM3Core:CPU
- NVIC:支持中断嵌套,向量中断机制可以在中断发生时,自动取出对应服务例程的入口地址
- SysTick 定时器:在 NVIC 内部实现,可以每隔一定时间产生中断,即便系统睡眠也可以工作
- 存储器保护单元:把存储器划分为多个区进行保护
- BusMatrix:CM3 总线核心,通过他让数据在不同总线间传输
- AHB to APB Bridge:总线桥,把多个 APB 设备连接到私有外设总线
- SW-DP/SWJ-DP:串行调试
- AHB-AP:无
- ETM 嵌入式跟踪宏单元:实时指令跟踪,
- DWT 数据观察点及跟踪单元:通过其设置数据观察点
- ITM 仪器化追踪宏单元:无
- FPB:提供 flash 地址重载与断点功能
CM3 总线接口
I-Code 总线
一条 32 位总线,进行取指操作
D-Code 总线
一条 32 位总线,进行数据访问操作,连接到该总线的设备不需要支持非对齐访问
系统总线
负责数据传送,他们都是对齐的
外部私有外设总线
基于 APB 协议的 32 为总线,负责私有外设访问
调试访问端口总线
专用于挂接调试接口
总线连接模板
异常
异常类型
编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断
中断不等于异常
15 个可用的系统异常表
优先级定义
优先级的数值越小,则优先级越高。
CM3 支持中断嵌套,使得高优先级异常会抢占(preempt)低优先级异常
三个特殊的系统异常:复位,NMI 以及硬 fault
,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常
CM3 还把 256 级优先级按位分成高低两段,分别称为抢占优先级和子优先级
NVIC 中有一个寄存器保存优先级组,他把优先级分为两段:
MSB 所在的位段对应抢占优先级; LSB 所在的位段对应子优先级
优先级组
CM3 支持 8 个不同的中断优先级,通常被分成 4 个优先级组
CM3 中断优先级组分配的四种主流方式:
Preemptive Priority Grouping (0 位抢占优先级组)
:
这种模式下,优先级分组被禁用,所有中断的优先级都是唯一的。优先级值高的中断总是可以打断正在执行的优先级值低的中断。这是最简单的中断优先级模式,但在复杂的应用中可能不够灵活。
No Preemptive Priority Grouping (4 位抢占优先级组)
:
这种模式下,中断被分为 4 个优先级组,每组内有 2 个优先级。每个组的中断不会互相打断,但是一个组内的高优先级中断可以打断低优先级中断。这提供了一定程度的分层和优先级控制。
Priority Grouping (3 位抢占优先级组)
:
这种模式下,中断被分为 8 个优先级组,每组内有 1 个优先级。这意味着每个中断都有唯一的优先级,没有中断会被其他中断完全屏蔽。这提供了更精细的优先级控制,但在复杂应用中可能需要更多的配置。
Priority Grouping (2 位抢占优先级组)
:
这种模式下,中断被分为 16 个优先级组,每组内有 1 个优先级。与上述模式相比,这种模式提供了更大的灵活性,但配置会更加复杂。
向量表
Cortex-M3
处理器使用中断向量表来管理不同中断的入口地址。
中断向量表是一个存储了中断处理程序地址的数组,每个元素对应一个特定的中断号。
当中断发生时,处理器会根据中断号从向量表中读取对应的地址,然后跳转到相应的中断处理程序。
中断向量表通常位于内存的起始地址处。向量表中的每个元素都是一个 4 字节(32 位)的地址,指向对应中断的处理程序
可以在 SRAM 中开出一块空间用于存储向量表
中断输入于挂起
NMI
NMI(Non-Maskable Interrupt,非屏蔽中断)是一种特殊类型的中断,在嵌入式系统中常用于处理一些紧急和重要的事件。与普通的可屏蔽中断不同,NMI 是无法被屏蔽或阻止的中断,即使处理器处于屏蔽中断状态(例如,全局中断被禁用),NMI 仍然可以触发。
当 NMI 发生时,处理器会跳转到 NMI 处理程序的入口地址执行相应的操作
中断挂起
中断输入脚置位有效后,他就被挂起,此时无法撤销中断请求
若在中断得到响应前消除挂起状态,则中断被取消
中断服务例程开始执行时,其挂起状态会被硬件自动清除
中断源一直维持中断请求信号,则该中断再完成一轮服务历程后又会被立刻赋予挂起状态进行下一轮
中断源以脉冲的形式发送 N 多个中断请求信号,最终只会接受一个
Fault 类异常
总线 faults
该 fault 可能产生的情况:
- 当 AHB 接口上正在传送数据时,回复了一个错误信号
- 在处理器启动中断服务序列(sequence)后读取向量时
- 中断处理起始阶段的堆栈 PUSH 动作
- 中断处理收尾阶段的堆栈 POP 动作
总线 fault 一旦检测到更高优先级异常,就会先执行后者,自己就挂起
总线 fault 是被某同级或更高优先级异常的服务例程引发的,则会变成硬 fault,使得最后执行的是硬 fault 的服务例程
欲使能总线 fault 服务例程前,总线 fault 服务例程的入口地址必须已经在向量表中配置好
总线 fault 状态寄存器(BFSR)
位于 NVIC 内部,可以找出产生 fault 的原因
存储器管理 faults
触发该 faults 的原因有如下四点:
- 访问了所有 MPU regions 覆盖范围之外的地址
- 访问了没有存储器与之对应的空地址
- 往只读 region 写数据
- 用户级下访问了只允许在特权级下访问的地址
MemManage fault 被除能,则会上访成硬 faults
若该硬 faults 执行时又导致了 MemManage fault,则内核被锁定
MemManage fault 必须被使能才能正常响应
用法 faults
用法 faults 一个重要的功能是:
执行了协处理器指令。Cortex-M3 本身并不支持协处理器,但是通过 fault 异常机制,可以建立一套“软件模拟”的机制,来执行一段程序模拟协处理器的功能
其余功能以及使能除能啥的情况和存储器 faults 基本一致,在这里不做过多介绍
导致用法 faults 最常见的原因是:视图切入 ARM 状态
SVC 与 PendSV
OS 不允许用户直接操作硬件,故出现了对应的桥梁 SVC(系统服务调用)
SVC 可以这样定义:
操作系统提供系统服务函数,用户通过 SVC 对这些函数发出请求,并以此来间接控制硬件
SVC 异常可以通过执行 SVC 指令来产生;
SVC 指令需要一个立即数,充当系统调用代号
PendSV 和 SVC 作用一致,只不过他可以被挂起
PendSV 异常处理程序通常会保存当前任务的上下文,并加载下一个任务的上下文,从而实现任务切换
PendSV 的任务优先级较低,故可以被许多高优先级例程打断