一、嵌入式系统基本硬件结构图
复位:让芯片内寄存器恢复到默认状态;
| 名称 | 全称 | 核心特点 | 速度 | 成本 | 典型用途 |
|---|---|---|---|---|---|
| SRAM | Static RAM 静态随机存储器 | 无需刷新,触发器保存数据,电路复杂 | 最快 | 高 | CPU Cache 高速缓存 |
| DRAM | Dynamic RAM 动态随机存储器 | 电容存储,必须周期性刷新,单元简单 | 中等 | 较低 | 早期主存 |
| SDRAM | Synchronous DRAM 同步动态 RAM | 与 CPU 时钟同步,仅上升沿传输数据 | 较快 | 中等 | 老嵌入式、老式 PC 内存 |
| DDRn | Double‑Data‑Rate SDRAM | 时钟上升沿、下降沿双向传输,速率翻倍 | 快 | 中等 | 现代 PC、开发板主内存 |
| 名称 | 全称 | 擦写特性 | 擦写方式 | 典型用途 |
|---|---|---|---|---|
| ROM | Read‑Only Memory 只读存储器 | 出厂固化,不可改写 | 掩膜出厂固化 | 大批量固定固件产品 |
| PROM | Programmable ROM 可编程 ROM | 仅可一次性烧写,烧完不可修改 | 专用烧写器一次性写入 | 早期小批量产品 |
| EPROM | Erasable PROM 可擦除 PROM | 可重复烧录 | 紫外线照射芯片窗口擦除 | 老旧芯片,现已淘汰 |
| EEPROM | Electrically‑EPROM 电可擦除 ROM | 支持按字节擦除修改 | 电信号,字节粒度擦写 | 保存少量配置参数 |
| Flash | Flash ROM 闪存 | 按块 / 页擦除,不能单字节擦写 | 按块擦除 | 存储程序代码、U 盘、SSD |
此外还有 NOR Flash:由或非门组成,可线性访问(和内存一样),CPU 可以直接运行其中的代码。
NAND Flash:由与非门组成,不能直接运行代码;会产生坏块,需要软件做坏块管理、ECC 校验纠错。
二、CPU
1.ALU(运算器)
进行加减乘除,与或非,比较大小,移位等操作;
2.通用寄存器
| 寄存器 | 作用 |
|---|---|
| R0 ~ R3 | 传参 / 返回值:调用函数时,前 4 个参数放这里;函数返回值放 R0 |
| R4 ~ R11 | 局部变量:函数内部临时存数据,用完要恢复 |
| R12 | IP(Intra-Procedure Call),过程调用临时寄存器,函数跳转时用 |
此处需注意,只有 R0~R3 寄存器供传参和返回值使用,所以当函数参数超过 4 个时,需要用到栈。
这是AAPCS(ARM 过程调用标准)的核心规则,调用函数时,最右边的参数先入栈,最左边的后入栈。例如调用func(a, b, c, d, e, f)(6 个参数)时,f 会先入栈,此栈为满递减栈。
3.特殊功能寄存器
| 寄存器 | 别名 | 作用 |
|---|---|---|
| PC | R15 | 程序计数器,存下一条要执行的指令地址 |
| LR | R14 | 链接寄存器,bl调用函数时自动存返回地址 |
| SP | R13 | 栈指针,指向栈顶位置,管 push/pop |
(1)CPSR(当前程序状态寄存器)
作用:记录 CPU 当前运行状态,相当于一个“状态仪表盘”。
关键标志位:N/Z/C/V:ALU 运算结果的标志(负 / 零 / 进位 / 溢出),blt、beq等条件跳转就是看这些位。
M[4:0]:CPU 当前工作模式(用户 / 管理 / 中断等)。
I/F:中断使能开关。
T:Thumb 指令集状态。
(2)SPSR(保存的程序状态寄存器)
发生异常 / 中断时,自动把 CPSR 备份到 SPSR。
异常返回时(MOVS pc,lr),再从 SPSR 恢复 CPSR,CPU 回到原来的模式和状态。
每种异常模式有自己的 SPSR,用户模式没有 SPSR。
默认情况:硬件禁止同类型嵌套,进入 IRQ 时,硬件自动把 CPSR 的 I 位置 1(关 IRQ),所以默认情况下 IRQ 处理中不会再响应新的 IRQ,自然不存在嵌套问题。
4.存储和地址管理
(1)MMU(内存管理单元)
CPU 和内存之间的“地址翻译官”,负责把程序使用的虚拟地址翻译成实际内存的物理地址。
作用:内存保护,防止一个程序非法访问其他程序的内存。
虚拟内存:可以用比实际物理内存更大的地址空间。
跑 Linux 等操作系统必须开 MMU;裸机程序可以不用。
(2)I-Cache(指令高速缓存)
专门缓存指令的高速存储器。CPU 取指令时先看 I-Cache 里有没有,有就直接用(快),没有才去慢速内存读。属于 SRAM,速度极快但容量小。
(3)D-Cache(数据高速缓存)
专门缓存数据的高速存储器。CPU 读写变量、内存数据时先经过 D-Cache。和 I-Cache 分开设计,取指和读写数据可以同时进行,互不冲突。
Cache 的意义:CPU 速度远快于内存,加一层 Cache 减少等待时间,提升整体性能。
三、SOC(片上系统)
把 CPU、内存控制器、各种外设控制器、总线等全部集成在一颗芯片里。
1.AHB 总线(高速总线)
连接高速、高带宽设备。频率高、支持突发传输(burst)、带宽大。CPU 直接连在 AHB 上。
2.挂在 AHB 上的外设
(1) 存储控制器
管理外部内存(SDRAM/DDR)和 Flash 的读写。CPU 要读写内存时,通过 AHB 把请求发给存储控制器,再由它去操作实际的内存芯片。因为内存读写频繁、数据量大,所以必须挂高速总线。
(2)LCD 控制器
驱动液晶屏显示。不断从内存读取帧缓冲(framebuffer)数据,刷屏到 LCD。一帧图像数据量很大(比如 800×480×2 字节 = 768KB),每秒刷 60 帧,带宽需求高,所以挂 AHB。
3.APB 总线(低速外设总线)
连接低速、低带宽外设。频率低、协议简单、功耗低、不支持突发传输。通过桥接器挂在 AHB 下面,CPU 不能直接访问 APB 设备,要经过 AHB→APB 桥。
4.挂在 APB 上的外设
(1)GPIO 控制器
控制芯片引脚,最基础的外设。可以配置引脚为输入(读按键状态)或输出(点亮 LED)。速度慢、数据量极小,挂 APB。
(2)UART 控制器
就是串口,最常用的调试和通信接口。你烧程序、看 printf 打印信息都靠它。波特率一般 115200,速度很慢,挂 APB。
(3)IIC 控制器(I²C)
两线式串行总线(SCL 时钟 + SDA 数据)。用来连接低速外设:EEPROM、温度传感器、触摸屏、RTC 实时时钟等。标准速度 100kbps,快速 400kbps,很慢,挂 APB。
(4)定时器控制器
提供定时、计数功能。产生固定时间中断(操作系统时钟节拍)、PWM 输出(控制电机、调光)、输入捕获(测脉冲宽度)。只需要配置寄存器,数据量极小,挂 APB。
四、ARM编程模型
1.处理器的工作模式
ARM有7个基本工作模式:
User:非特权模式,大部分任务执行在这种模式
FIQ:当一个高优先级(fast)中断产生时将会进入这种模式
IRQ:当一个低优先级(normal)中断产生时将会进入这种模式
Supervisor:当复位或软中断指令执行时将会进入这种模式
Abort:当存取异常时将会进入这种模式
Undef:当执行未定义指令时会进入这种模式
System:使用和User模式相同寄存器集的特权模式
Cortex-A特有模式:
Monitor:是为了安全而扩展出的用于执行安全监控代码的模式;也是一种特权模式
2.Cortex-A寄存器组织概要
带三角这个表示这个模式的这个寄存器是独立存在的。
3.异常处理
异常发生时,CPU 强制把 PC 跳到固定地址,每个异常占 4 字节(一条指令):(异常向量表)
| 地址 | 异常类型 | 触发场景 |
|---|---|---|
| 0x00 | Reset 复位 | 上电或复位键 |
| 0x04 | Undefined Instruction 未定义指令 | CPU 遇到不认识的指令 |
| 0x08 | Software Interrupt 软中断 | 执行swi/svc指令 |
| 0x0C | Prefetch Abort 预取指中止 | 取指令时地址非法 |
| 0x10 | Data Abort 数据中止 | 读写数据时地址非法 |
| 0x14 | Reserved 保留 | 未使用 |
| 0x18 | IRQ 外部中断 | 外设触发普通中断 |
| 0x1C | FIQ 快速中断 | 外设触发快速中断 |
当异常产生时,ARMcore:
(1)拷贝CPSR到SPSR_<mode>
(2)设置适当的 CPSR位:改变处理器状态进入ARM态;改变处理器模式进入相应的异常模式;设置中断禁止位禁止相应中断 (如果需要)
(3)保存返回地址到LR_<mode>
(4)设置PC为相应的异常向量
返回时,异常处理需要:
(1)从 SPSR_<mode>恢复CPSR
(2)从LR_<mode>恢复PC
(3)Note:这些操作只能在ARM态执行.
五、ARM汇编语言程序设计
我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一上电
SP 指针还没初始化,C 环境还没准备好,所以肯定不能运行 C 代码,必须先用汇编语言设置好 C 环境,比如初始化 DDR、设置 SP指针等等,当汇编把 C 环境设置好了以后才可以运行 C 代码。所以 Cortex-A 一开始肯定是汇编代码。
1.基本结构
注意:在汇编语言中";"为注释的意思,在汇编语言中只能单行注释,不能多行注释。
2.数据处理指令
算术指令:ADD,ADC,SUB,SBC,RSB,RSC
逻辑指令:AND,ORR,EOR,BIC
比较指令:CMP,CMN,TST,TEQ
数据搬移:MOV,MVN
3.条件码
4.练习
(1)实现多条件判断
给cmp后面加上gt表示只有在上一条比较结果为大于时才执行。
(2)实现64位数据计算
ARM 是32 位架构,单个寄存器最多存 32 位,要处理64位数据必须将两个寄存器拼起来用
(3)实现1-100求和
这里和之前的用的不一样是因为b是无条件跳转,相当于c语言中的goto,bl是带连接跳转
| 对比项 | bl | blt |
|---|---|---|
| 是否修改 LR | 把bl下一条指令的地址存入LR | ❌ 不修改 |
| 跳转条件 | 无条件,一定跳 | 有条件,小于才跳 |
| 用途 | 函数调用(调用完要回来) | 循环 / 分支判断(goto) |
| 返回方式 | mov pc, lr回家 | 不需要返回,跳走就完事 |
| 指令类型 | 带链接跳转 | 普通条件跳转 |
5.异常向量表
当 ARM 芯片发生异常(比如复位、外部中断、遇到不认识的指令)时,CPU 需要知道 "该跳转到哪个地址去执行处理程序"。异常向量表(Exception Vector Table)就是这张 "跳转地址表",它固定位于内存的最低地址处,每个表项占 4 个字节,存放一条跳转指令。
当某种异常发生时,CPU 自动跳转到向量表中对应的偏移地址,执行那里的跳转指令,进入对应的异常处理程序。
5.1异常向量表
5.2 各异常类型说明
复位(Reset):系统上电或复位时触发,优先级最高。CPU 从 0x00 地址取指令,通常是初始化栈、初始化外设、跳转到主程序。
未定义指令(Undefined Instruction):CPU 遇到无法识别的指令时触发,用于模拟协处理器指令或处理非法指令。
软件中断(SWI/SVC):由程序主动执行swi指令触发,常用于用户模式请求操作系统服务,是用户态进入内核态的标准方式。
预取指中止(Prefetch Abort):CPU 从非法地址取指令时触发,说明指令总线访问出错。
数据中止(Data Abort):CPU 从非法地址读写数据时触发,说明数据总线访问出错。
外部中断请求(IRQ):外部设备通过中断控制器向 CPU 发出中断请求,是最常用的中断类型,用于外设通知 CPU "数据准备好了" 或 "有事件发生"。
快速中断请求(FIQ):优先级高于 IRQ,专门用于对响应时间要求极高的场景(如高速数据传输),FIQ 模式有更多的私有寄存器,可以减少现场保存的开销。
5.3 进入模式与优先级
- 进入模式:异常发生后,CPU 自动切换到对应的 ARM 工作模式(SVC、UND、ABT、IRQ、FIQ),不同模式有不同的私有寄存器,保证异常处理不破坏被中断程序的现场。
- 优先级:当多个异常同时发生时,CPU 按优先级从高到低依次处理。复位(优先级 1)最高,任何异常都无法打断复位。
5.4 向量表的位置
在 ARM720T 及 ARM9/10 系列器件上,向量表可以位于两个位置:
- 地址
0x00000000(低端地址) - 地址
0xFFFF0000(高端地址)
具体使用哪个位置,由系统配置决定。通常片内 Boot ROM 位于低端地址,启动后可以通过重映射(remap)将向量表移到高速 RAM 区域,以提升中断响应速度。