【嵌入式八股17】Cortex
一、ARM 内核发展历史
ARM 内核随着技术发展不断演进,不同内核基于不同架构,在性能、功能等方面各有特点,以下是一些常见 ARM 内核及其对应的架构:
ARM7 | ARMv6 |
Cortex-M0 | ARMv6-M |
Cortex-M0+ | ARMv6-M |
Cortex-M3 | ARMv7-M |
Cortex-M4 | ARMv7-M |
Cortex-M7 | ARMv7-M |
ARM9 | ARMv6 |
ARM11 | ARMv6 |
ARM12 | ARMv6 |
Cortex-A7 | ARMv7-A |
Cortex-A8 | ARMv7-A |
Cortex-A9 | ARMv7-A |
Cortex-A15 | ARMv7-A |
Cortex-A17 | ARMv7-A |
Cortex-A53 | ARMv8 |
Cortex-A57 | ARMv8 |
Cortex-A72 | ARMv8 |
二、Cortex-M0 系列芯片系统框图
Cortex-M0 系列芯片系统主要由多个关键部分组成,其系统框图展示了芯片内部的架构和各部分之间的关系,以下是系统的主要组成部分: 
- 中断控制器:负责管理芯片的中断请求,协调中断的处理过程。
- M0 内核:芯片的核心处理单元,执行指令和处理数据。
- AHB 总线:用于连接系统中的高速设备,实现数据的高速传输。
- 存储器和外设:包括芯片的内存以及各种外部设备,如传感器、通信接口等。
- 电源管理:控制芯片的电源供应,实现节能和稳定供电。
- 时钟树:为系统提供时钟信号,确保各部件的同步运行。
- 调试系统:方便开发人员对芯片进行调试和测试,查找和解决问题。
三、Cortex-M 系列寄存器
(一)通用寄存器
Cortex-M 系列包含多个通用寄存器,用于数据的存储和处理,在程序执行过程中发挥着重要作用,以下是通用寄存器列表:
(二)M0 特殊寄存器
除通用寄存器外,Cortex-M0 还有一些特殊寄存器,用于特定的功能和系统控制,以下是 M0 的特殊寄存器:
(三)M3/M4/M7 特殊寄存器
Cortex-M3、M4、M7 在 M0 特殊寄存器的基础上,还增加了一些特殊寄存器,以满足更复杂的功能需求,以下是它们的特殊寄存器:
1. MSP 和 PSP
- MSP(主堆栈指针):在中断处理中使用,系统复位后默认使用 MSP,在中断处理过程中也使用 MSP。
- PSP(进程堆栈指针):用于线程栈,通过配置 CONTROL 寄存器的相关位来切换使用 MSP 或 PSP。当 CONTROL 寄存器的第 1 位写 1 时,表示切换成 PSP。
2. xPSR
xPSR(程序状态寄存器)中的 IPSR(中断号寄存器)可以用来判断当前处于什么中断,帮助程序进行中断处理和状态判断。
3. PRIMASK
PRIMASK 是中断屏蔽寄存器,向其写 1 可以屏蔽所有中断(除了不可屏蔽中断和 hardfault 硬件错误中断),从而在需要时保护关键代码段不被中断干扰。
4. CONTROL
CONTROL 寄存器具有多种功能,其中第 1 位写 1 表示切换成 PSP;第 0 位用于控制线程模式的特权级别,0 表示特权级的线程模式,1 表示用户级的线程模式,而 Handler 模式永远都是特权级的。
5. FAULTMASK
FAULTMASK 寄存器用于屏蔽所有的 fault(NMI 不可屏蔽中断不受影响),当需要临时屏蔽错误异常时,可以使用该寄存器。
6. BASEPRI
BASEPRI 寄存器可以屏蔽所有优先级不高于某个具体数值的中断,通过设置该寄存器的值,可以灵活控制中断的响应。
四、栈空间操作
在 Cortex-M 系列中,栈的操作具有特定的规则:
- 栈的增长方向:栈向下递减,即栈顶地址随着数据的入栈而减小。
- 栈指针的指向:栈指针(SP)始终指向栈的最后一个数据,每次执行数据存储操作(push)前,SP 会首先减小,为新数据腾出空间。
五、异常和中断
(一)Cortex-M0 的异常和中断
Cortex-M0 最多支持 32 个外部中断,同时还包括一些系统异常,主要用于操作系统和错误处理,以下是一些主要的系统异常:
reset | 1 | 上电复位、系统复位,是系统启动时的初始状态。 |
NMI(不可屏蔽中断) | 2 | 由外部 NMI 输入脚触发,不可被屏蔽,用于处理关键的紧急事件。 |
hardfault(硬件错误) | 3 | 当系统出现硬件故障时触发,如存储器访问错误等。 |
SVCall(系统调用) | 11 | 用于执行系统服务调用指令,实现用户程序与操作系统之间的交互。 |
PendSV(挂起系统调用) | 13 | 为系统设备而设的“可悬挂请求”,常用于任务切换等场景。 |
systick(系统滴答) | 15 | 系统滴答定时器,提供周期性的时钟信号,用于系统的定时操作。 |
(二)NVIC(可嵌套向量中断控制器)
NVIC 是 Cortex-M 系列芯片中用于管理中断的重要部件,具有以下特点:
- 中断可嵌套:当一个中断正在处理时,如果有更高优先级的中断到来,可以中断当前的中断处理,先处理更高优先级的中断。
- 相同优先级的中断不可嵌套:对于相同优先级的中断,不会相互嵌套,必须等待当前中断处理完毕后,才能处理相同优先级的其他中断。
- 相同中断不可嵌套:同一个中断在处理过程中不会再次被嵌套处理,避免了递归调用的问题。
六、系统操作寄存器
Cortex-M 系列芯片包含许多系统管理的寄存器,它们分布在不同的地址范围,用于实现各种系统功能,以下是主要的系统操作寄存器及其地址范围和说明:
0xE000E008 - 0xE000E00F | System Control Block Table(系统控制块表) |
0xE000E010 - 0xE000E01F | 预留 |
0xE000E010 - 0xE000E01F | SysTick 操作寄存器(SysTick 定时器的控制和配置) |
0xE000E100 - 0xE000E4EF | NVIC 操作寄存器(中断控制器的相关配置和操作) |
0xE000ED00 - 0xE000ED3F | 系统控制块(包含一些系统控制和状态信息) |
0xE000EF00 - 0xE000EF03 | NVIC(中断控制器的部分寄存器) |
(一)NVIC 寄存器
NVIC 包含多个寄存器,用于控制中断的使能、失能、挂起等操作,以下是主要的 NVIC 寄存器及其地址和说明:
0xE000E100 | ISER(中断使能寄存器) | 用于使能相应的中断。 |
0xE000E180 | ICER(中断失能寄存器) | 用于失能相应的中断。 |
0xE000E200 | ISPR(中断挂起寄存器) | 用于设置相应中断的挂起状态。 |
0xE000E280 | ICPR(清除挂起中断的寄存器) | 用于清除相应中断的挂起状态。 |
0xE000E400 - 0xE000E41C | IPR0-7(中断优先级配置寄存器) | 用于配置中断的优先级。 |
(二)系统控制块 SCB 寄存器
系统控制块 SCB 包含多个寄存器,用于系统的控制和状态管理,以下是主要的 SCB 寄存器及其地址和说明:
0xE000ED00 | CPUID(CPU 标识寄存器) | 包含 CPU 的标识信息。 |
0xE000ED04 | ICSR(中断控制和状态寄存器) | 用于中断的控制和状态查询。 |
0xE000ED0C | AIRCR(应用中断和复位的寄存器) | 用于处理应用中断和复位操作。 |
0xE000ED10 | SCR(系统控制寄存器) | 用于系统的控制和配置。 |
0xE000ED14 | CCR(配置控制寄存器) | 用于配置系统的一些特性。 |
0xE000ED1C | SHPR2(System Handler Priority Register 2,系统处理优先级寄存器 2) | 用于设置系统处理的优先级。 |
0xE000ED20 | SHPR3(System Handler Priority Register 3,系统处理优先级寄存器 3) | 用于设置系统处理的优先级。 |
(三)SysTick 寄存器
SysTick 是系统滴答定时器,其相关寄存器用于控制和读取定时器的状态,以下是 SysTick 寄存器及其地址和说明:
0xE000E010 | SYST_CSR(SysTick 控制和状态寄存器) | 用于控制 SysTick 定时器的启动、停止、中断等功能,并查询其状态。 |
0xE000E014 | SYST_RVR(SysTick 重载寄存器) | 设置 SysTick 定时器的重载值,即定时周期。 |
0xE000E018 | SYST_CVR(SysTick 当前值寄存器) | 用于读取 SysTick 定时器的当前计数值。 |
0xE000E01C | SYST_CALIB(SysTick 校准寄存器) | 用于校准 SysTick 定时器。 |
七、Cortex-M0 启动流程
Cortex-M0 芯片的启动过程遵循特定的顺序,以下是其启动流程:
- 程序从 0x00000000 地址开始执行,这是系统启动的初始位置。
- M0 从程序 bin 文件的开始处第 2 个 word 运行 reset_handler 函数,该函数是启动过程中的关键函数。
- reset_handler 函数开始执行一些必要的初始化操作,包括 ramfunc 函数复制(将某些函数复制到 RAM 中以提高执行速度)、堆初始化(为动态内存分配做准备)、全局和静态变量初始化等,确保系统的基本运行环境准备就绪。
- 完成初始化后,跳转到 main 函数中,开始执行用户程序的主要逻辑。
八、中断向量表
中断向量表是存储中断服务程序地址的表格,在 Cortex-M0 中,中断向量表包含以下主要内容:
sp 指针(堆栈指针的初始值) |
resetHandler 地址(复位中断服务程序的地址) |
NMIHandler 地址(不可屏蔽中断服务程序的地址) |
hardfault 地址(硬件错误中断服务程序的地址) |
reserved(预留位置) |
systickHandler 地址(系统滴答中断服务程序的地址) |
......(其他中断服务程序的地址) |
九、大小端模式
Cortex-M0 支持大端模式和小端模式,大端模式是指数据的高位字节存储在低地址,小端模式则是数据的高位字节存储在高地址。不过一般芯片公司在设计时会选择小端模式,因为小端模式在一些情况下更符合程序的执行习惯和数据处理方式。
十、堆栈
在 Cortex-M 系列中,堆栈的增长方向具有特定的规律:
- 堆的增长方向:堆向上增长,即随着动态内存分配,堆的地址逐渐增大。
- 栈的增长方向:栈向下增长,如前面所述,栈顶地址随着数据的入栈而减小。
(一)压栈的寄存器
当发生中断或函数调用等情况时,需要将一些寄存器的值压入栈中保存,以便在恢复时能够还原现场,以下是常见的压栈寄存器:
xPSR(程序状态寄存器) |
PC(程序计数器) |
LR(链接寄存器) |
R12 |
R3 |
R2 |
R1 |
R0 |
十一、杂项指令集
Cortex-M 系列包含一些特殊的指令,用于实现特定的
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
一些八股模拟拷打Point,万一有点用呢