📝摘要:本文整理ARM‑Cortex系列内核基础概念,包含RISC与CISC对比、ARM通用内核寄存器、冯诺依曼架构、大小端、移位指令、中断异常向量表、Flash区别、交叉编译等核心知识点。
🔖标签:
#ARM#Cortex‑A#Cortex‑M#RISC#嵌入式
1. RISC与CISC指令集对比
CISC(复杂指令集计算机)
Complex Instruction Set Computer
特点
- 指令功能强大、一条指令可以完成复杂操作;
- CPU硬件电路复杂,芯片规模大;
- 成本高、体积大、功耗偏高;>
代表:x86 PC处理器(Intel、AMD)。
RISC(精简指令集计算机)
Reduced Instruction Set Computer,ARM属于典型RISC架构CPU
特点
- 指令功能简单、指令格式规整;
- 硬件电路简单,芯片实现简单;
- 成本低、体积小、功耗低,非常适合嵌入式设备。
ARM商业模式:ARM公司只设计CPU内核,不生产芯片,把内核IP授权给半导体厂商(ST、NXP、三星等),厂商封装外设生产出实际芯片。
2. ARM内核分类与产品选型
ARMv7、ARMv8是指令集版本;Cortex是内核系列名称。
- Cortex‑A(Application 应用系列) :跑Linux操作系统
- Cortex‑A5:早期智能设备
- Cortex‑A7:IMX6ULL、STM32MP157嵌入式Linux开发板
- Cortex‑A8:早期三星手机
- Cortex‑A9:Exynos4412开发板
- Cortex‑A725:现代移动端内核(玄戒O1)
- Cortex‑R(Real‑Time 实时系列):汽车电子,高实时性,不跑Linux。
- Cortex‑M(MCU单片机系列) :裸机RTOS,不运行完整Linux系统
- Cortex‑M3:STM32F103
- Cortex‑M4:STM32F407、STM32MP157(MP157既有A7又有M4双核)
区分:
- Cortex‑A:带MMU,可以运行Linux;
- Cortex‑M:没有MMU,只能裸机/RTOS单片机程序。
3. ARM32通用内核寄存器详解(Cortex‑A7 32位)
ARM32一共有16个通用寄存器 R0~R15。
| 寄存器 | 别名 | 功能说明 |
|---|---|---|
| R0‑R12 | 通用寄存器 | 用于临时存放运算数据,ALU算术逻辑单元运算数据源 |
| R13 | SP Stack Pointer | 栈指针寄存器,记录栈顶地址 |
| R14 | LR Link Register 链接寄存器 | 保存函数返回地址;函数调用时把返回地址存入LR |
| R15 | PC Program Counter程序计数器 | 指向下一条将要执行的指令地址,不是当前正在执行的指令 |
示例:
int i = 0xFFFFFFFF;
i += 1;
32位无符号数,0xFFFFFFFF + 1溢出,结果变为0,由ALU硬件完成算术运算。
CPSR / SPSR 程序状态寄存器
- CPSR:当前程序状态寄存器,保存当前CPU运行模式、中断屏蔽、运算标志位(零、负、进位、溢出)。
- SPSR:
Saved Program Status Register备份程序状态寄存器。发生异常的时候,保存旧的CPSR状态;异常返回时恢复。
ALU 算术逻辑单元:CPU内部硬件,专门完成加减、移位、逻辑与或非运算。
4. 栈操作规则:SP栈指针
ARM栈:满递减栈 FD(Full Descending),栈向低地址方向增长。
- 入栈:先SP自减,再存入数据;
- 出栈:先从SP指向位置取出数据,之后SP做自增。>
口诀:先进后出,后进先出。栈本质一块内存区域,SP寄存器标记栈顶位置。
5. 冯‑诺依曼体系架构
Von‑Neumann架构
核心特征:指令与数据存放在同一块存储器空间,共享同一条总线访问内存。
程序指令、变量数据都放在同一内存地址空间;CPU通过同一套总线读取指令或者读写数据。
对比哈佛架构:指令存储器、数据存储器物理分开,两套独立总线,典型代表STM32单片机。
6. 大小端存储模式
针对多字节数据在内存中的存放顺序 。以16位数据
0x1234举例:
-
小端 Little‑Endian:低地址存低字节,高地址存高字节。
0x00: 0x34
0x01: 0x12
x86、ARM默认小端模式。
-
大端 Big‑Endian:低地址存高字节,高地址存低字节;网络通信数据包普遍使用大端。
0x00: 0x12
0x01: 0x34
C语言判断大小端简易代码
#include <stdio.h>
int main(void)
{
unsigned short val = 0x1234;
unsigned char *p = (unsigned char *)&val;
if(*p == 0x34){
printf("小端模式\n");
}else{
printf("大端模式\n");
}
return 0;
}
7. 移位运算LSR / ASR / ROR
ARM汇编移位指令,C语言>>不等于硬件移位;汇编区分三种移位:
- LSR 逻辑右移 Logical Shift Right(针对无符号数)
最高位统一补0,完全不关心符号。
示例二进制:1011 0010,LSR右移1位
输入:1011 0010
输出:0101 1001,高位补0。 - **ASR 算术右移 Arithmetic Shift Right(针对有符号数)**最高位补符号位 ;负数高位补1,正数高位补0,保证符号不变。
示例:1011 0010(负数,符号位为1)ASR右移1位
输入:1011 0010
输出:1101 1001,最高位复制原来符号位1。 - ROR 循环右移 Rotate Right
把最低位移出来,直接放到最高位;循环轮转,数据不会丢失。
示例:1011 0010ROR右移1位
原始:1 0110010
移出最低位0,放到最高位:0 1011001
注意:C语言中
>>对于有符号数,编译器会选择算术右移;无符号数执行逻辑右移;没有直接支持循环右移运算符。
8. 异常/中断向量表
向量表本质:一块内存数组。
- 中断向量表 :数组内存存放中断服务函数入口地址。
- 异常向量表:数组存放跳转指令,发生异常CPU自动跳转到对应异常处理代码。
Cortex‑A7异常向量表偏移地址:
| 偏移地址 | 异常类型 |
|---|---|
| 0x00 | Reset 复位 |
| 0x04 | Undefined Instruction 未定义指令异常 |
| 0x08 | Software Interrupt软中断SWI |
| 0x0C | Prefetch Abort 预取指令终止 |
| 0x10 | Data Abort 数据访问终止 |
| 0x14 | Reserved 保留 |
| 0x18 | IRQ普通中断请求 |
| 0x1C | FIQ快速中断请求 |
CPU发生异常,硬件自动跳转到向量表对应偏移位置执行代码。Cortex‑A系列可以把向量表基地址设置到
0xFFFF0000或者0x20000000。
9. MMU内存管理单元
Memory Management Unit内存管理单元
- 作用:完成虚拟地址 → 物理地址转换,依靠页表完成映射;同时实现内存访问权限控制。
- 裸机开发:关闭MMU,程序直接操作物理地址;
- Linux操作系统:打开MMU,每个进程拥有独立4GB虚拟地址空间,不同进程虚拟地址相同映射不同物理内存。
没有MMU的内核Cortex‑M,不能运行标准Linux,只能跑RTOS。
10. 总线、NOR‑Flash与NAND‑Flash
AHB高级高速总线
Advanced High‑performance Bus,高速外设与内核之间通信总线。
单总线:内核和所有外设共用一组信号线;
多总线:区分高速AHB、低速APB,高速设备走AHB,提升整体系统性能。
NOR Flash
- 可以对任意字节直接寻址访问;具备独立地址总线+数据总线;
- 可以直接在NOR上运行程序(XIP原地执行);
- 成本较高,容量一般偏小。
NAND Flash
- 块设备,以块为单位读写(典型块大小512字节);
- 不能直接随机地址执行代码;必须把代码拷贝到内存再运行;
- 大容量、价格便宜;U盘、eMMC属于NAND类存储。
Flash属于非易失存储器,断电数据不会丢失;DDR内存是易失存储器,断电全部丢失。
11. 交叉编译
交叉编译:在A平台编译生成程序,编译出来的可执行文件,在另一个B硬件平台运行。
示例:PC上x86 Ubuntu环境,使用arm‑linux‑gnueabihf‑gcc编译器,编译ARM Cortex‑A7开发板运行的程序。
PC本地gcc编译出来只能跑在x86;交叉编译器输出ARM架构二进制。
简单示例交叉编译命令:
arm‑linux‑gnueabihf‑gcc demo.c ‑o demo_arm
把demo_arm拷贝到IMX6ULL开发板运行。
12. 英文缩写全称对照表
| 缩写 | 英文全称 | 中文释义 |
|---|---|---|
| RISC | Reduced Instruction Set Computer | 精简指令集计算机 |
| CISC | Complex Instruction Set Computer | 复杂指令集计算机 |
| PC | Program Counter | 程序计数器 |
| LR | Link Register | 链接寄存器(保存函数返回地址) |
| SP | Stack Pointer | 栈指针寄存器 |
| ALU | Arithmetic Logic Unit | 算术逻辑运算单元 |
| SPSR | Saved Program Status Register | 备份程序状态寄存器 |
| CPSR | Current Program Status Register | 当前程序状态寄存器 |
| MMU | Memory Management Unit | 内存管理单元 |
| AHB | Advanced High‑performance Bus | 高级高性能总线 |
| LSR | Logical Shift Right | 逻辑右移 |
| ASR | Arithmetic Shift Right | 算术右移 |
| ROR | Rotate Right | 循环右移 |
| IRQ | Interrupt Request | 普通中断请求 |
| FIQ | Fast Interrupt Request | 快速中断请求 |
| XIP | Execute In Place | 原地直接执行 |
💡补充知识点
- ARM32 Cortex‑A栈默认满递减FD,初始化SP必须指向栈内存末尾高地址;
- 大小端网络传输统一使用大端,PC小端设备发送网络数据包要做htons/htonl大小端转换;
- MMU页表是虚拟地址映射核心,Linux每个进程都拥有独立一套页表。