一、嵌入式系统基本概念
嵌入式系统是以应用为中心、以计算机技术为基础,软硬件可裁剪,适用于对功能、体积、环境、稳定性、可靠性等方面有特定要求的专用计算机系统。
一个完整的计算机系统可以分为:
应用层 APP
↓
操作系统 SYS
↓
硬件系统
硬件系统主要包括:
运算器
控制器
存储器
输入设备
输出设备
其中:
-
运算器:完成各种算术运算和逻辑运算。
-
控制器:控制计算机各个部件协调工作。
-
存储器:保存程序和数据。
-
输入设备:向计算机输入数据。
-
输出设备:输出计算机处理后的结果。
二、常见处理器类型
根据不同应用场景,常见的处理器有:
1. CPU
CPU(Central Processing Unit)------中央处理单元
是通用型处理器,主要负责执行程序和完成各种计算任务。
2. GPU
GPU(Graphics Processing Unit)------图形处理单元
主要用于图形、图像以及大量并行计算任务。
3. FPU
FPU(Float Processing Unit)------浮点处理单元
主要用于进行浮点数相关的计算。
4. NPU
NPU(Neural Processing Unit)------神经网络处理单元
主要面向人工智能、神经网络等计算任务。
5. MPU
MPU(Micro Processing Unit)------微处理器
属于通用处理器,主要用于较复杂的计算和处理任务。
6. MCU
MCU(Micro Control Unit)------微控制器
也就是我们通常所说的单片机。
特点是:
-
集成度高
-
面向控制
-
通常集成 CPU、存储器、GPIO、定时器、UART、PWM 等外设
例如我们之前学习的:
STC89C52
就属于 MCU。
7. DSP
DSP(Digital Signal Processing)------数字信号处理
主要面向数字信号处理,例如音频、通信、图像等领域。
8. SoC
SoC(System On Chip)------片上系统
可以理解为:
将一个完整系统的多个功能模块集成到一块芯片中。
例如一块 SoC 中可能包含:
SoC
├── CPU / ARM Core
├── GPU
├── RAM接口
├── GPIO
├── PWM
├── UART
├── Timer
├── 存储控制器
└── 其他外设
SoC 就像一座城市,其中 CPU、GPU、RAM、GPIO、UART 等分别承担不同的功能。
三、RAM 与 ROM
1. RAM
RAM(Random Access Memory)------随机存取存储器
主要特点:
-
可以随机访问
-
单位存储空间价格相对较高
-
易失性存储器
-
读写速度较高
RAM 断电后,保存的数据通常会丢失。
2. ROM
ROM(Read-Only Memory)------只读存储器
特点:
-
一般不支持直接随机写入
-
单位存储空间价格较低
-
非易失性存储器
-
读写速度相对较低
ROM 中的数据掉电后仍然可以保存。
四、ARM体系结构
ARM 是一种非常重要的处理器架构。
X86
ARM
MIPS
RISC-V
这些都属于不同的处理器架构体系。
1. CISC
CISC(Complex Instruction Set Computer)
即:
复杂指令集计算机
特点是:
-
指令数量较多
-
指令功能较复杂
-
一条指令可以完成相对复杂的操作
X86
作为 CISC 的典型代表。
2. RISC
RISC(Reduced Instruction Set Computer)
即:
精简指令集计算机
特点是:
-
指令相对精简
-
指令格式比较规范
-
便于流水线执行
ARM 属于 RISC 类型的处理器架构。
五、ARM内核与Cortex系列
ARM 内核根据不同应用场景形成不同的 Cortex 系列。
ARM
│
├── Cortex-A
│ └── app(应用)
│
├── Cortex-R
│ └── real-time(实时)
│
└── Cortex-M
└── MCU(微控制器)
Cortex-A
主要面向:
Application
应用
适合运行比较复杂的操作系统和应用程序。
Cortex-R
主要面向:
Real-time
实时系统
强调实时处理能力。
Cortex-M
主要面向:
MCU
微控制器
常用于嵌入式控制系统。
六、ARM Core基本组成
ARM Core 内部包含多个重要组成部分。
通用寄存器
│
├── ALU
├── Cache
├── MMU
└── CPSR
1. 通用寄存器
ARM 中有多个通用寄存器:
R0
R1
R2
...
R12
R13
R14
R15
其中:
R13 ------ SP
R13 = SP
SP 即:
Stack Pointer ------ 栈指针
用于指向当前栈的位置。
R14 ------ LR
R14 = LR
LR 即:
Link Register ------ 链接寄存器
主要用于保存函数调用或者异常处理过程中需要返回的位置。
R15 ------ PC
R15 = PC
PC 即:
Program Counter ------ 程序计数器
用于表示程序当前执行的位置。
七、ALU
ALU(Arithmetic Logic Unit)------算术逻辑单元
主要负责:
算术运算
+
-
×
÷
逻辑运算
AND
OR
NOT
XOR
例如:
int a = 100;
int b = 200;
int sum = a + b;
其中:
100 + 200
这样的运算最终需要由处理器中的运算单元完成。
八、Cache高速缓存
Cache------高速缓存
Cache 位于处理器和主存之间,用于提高处理器访问数据的效率。
-
iCache:指令 Cache
-
dCache:数据 Cache
基本思想:
CPU
↓
Cache
↓
RAM
CPU 访问速度通常高于 RAM,因此通过 Cache 保存经常使用的数据和指令,可以减少处理器访问主存的次数。
九、MMU
MMU(Memory Management Unit)------内存管理单元
主要负责内存地址相关的管理。
物理内存空间
↓
MMU
↓
虚拟内存空间
因此可以简单理解为:
MMU 用于完成虚拟地址与物理地址之间的内存管理。
关闭 MMU
↓
物理内存空间
打开 MMU
↓
虚拟内存空间
十、ARM中的CPSR和SPSR
1. CPSR
CPSR(Current Program Status Register)
即:
当前程序状态寄存器
用于保存当前程序的状态信息。
2. SPSR
SPSR(Saved Program Status Register)
即:
保存程序状态寄存器
主要用于异常处理过程中保存原来的程序状态。
可以简单理解为:
发生异常
↓
保存当前状态
↓
进入异常处理
↓
恢复原来的状态
十一、ARM中的SP、LR、PC
这三个寄存器是学习 ARM 时非常重要的内容。
| 寄存器 | 名称 | 作用 |
|---|---|---|
| R13 | SP | 栈指针 |
| R14 | LR | 链接寄存器 |
| R15 | PC | 程序计数器 |
记忆方法:
R13 → SP → Stack Pointer
R14 → LR → Link Register
R15 → PC → Program Counter
十二、函数调用与栈
程序运行过程中,经常会进行函数调用。
例如:
int fun1(int a, int b)
{
int sum = 0;
sum = a + b;
return sum;
}
int main()
{
int a = 100;
int b = 200;
int sum;
sum = fun1(a, b);
}
当 main() 调用 fun1() 时,需要使用栈保存函数调用过程中需要的信息。
栈顶
│
│ fun1 栈帧
│
│
│ main 栈帧
│
栈底
每调用一个函数,都可能建立对应的栈帧(Stack Frame)。
例如:
main()
↓
调用 fun1()
↓
建立 fun1 栈帧
↓
执行 fun1()
↓
return
↓
回到 main()
十三、函数调用中的SP和PC
R13(sp)
R15(pc)
其中:
SP
↓
指向当前栈的位置
PC
↓
指向当前程序执行的位置
因此在分析 ARM 程序执行过程时,可以重点观察:
PC:程序执行到了哪里?
SP:当前栈在哪里?
LR:函数执行完以后返回哪里?
十四、ARM地址空间与总线
三类总线:
数据总线
地址总线
控制总线
其中:
1. 数据总线
用于传输数据。
例如:
RAM → CPU
CPU → RAM
2. 地址总线
用于确定访问哪个地址。
例如:
0x00000000
↓
地址
3. 控制总线
用于传输控制信息,例如读、写等控制信号。
因此计算机系统可以简单表示为:
CPU
│
┌─────────┼─────────┐
↓ ↓ ↓
数据总线 地址总线 控制总线
│ │ │
└─────────┼─────────┘
↓
RAM / 外设
十五、RAM虚拟内存空间
开启 MMU 后,可以使用虚拟内存空间。
课堂图中对 RAM 虚拟内存空间进行了划分,例如:
高地址
┌──────────────┐
│ 操作系统 │
├──────────────┤
│ 栈区 │
├──────────────┤
│ 堆区 │
├──────────────┤
│ 未初始化区 │
├──────────────┤
│ 数据段 │
├──────────────┤
│ 代码段 │
└──────────────┘
低地址
其中重点理解:
代码段
保存程序代码。
数据段
保存已经初始化的全局变量、静态变量等数据。
未初始化区
用于保存未初始化的数据。
堆区
用于动态分配的内存。
栈区
用于函数调用、局部变量等。
十六、C语言程序的编译过程
编译过程:
main.c
↓
预处理
↓
main.i
↓
编译
↓
main.s
↓
汇编
↓
main.o
↓
链接
↓
main.out
1. 预处理
gcc -E main.c -o main.i
主要完成:
-
头文件展开
-
宏替换
-
条件编译等
2. 编译
gcc -S main.i -o main.s
将 C 语言代码转换为汇编代码。
3. 汇编
gcc -c main.s -o main.o
将汇编代码转换成目标文件。
4. 链接
gcc main.o -o main.out
将目标文件以及相关库进行链接,最终生成可执行程序。
十七、三段流水线
课堂最后介绍了三级流水线。
基本分为:
取指 → 译码 → 执行
即:
第一阶段:预取/取指
第二阶段:译码
第三阶段:执行
多条指令可以同时处于不同阶段。
例如:
指令1:取指 → 译码 → 执行
指令2: 取指 → 译码 → 执行
指令3: 取指 → 译码 → 执行
形成流水线以后,可以提高处理器指令执行的效率。
十八、AHB和APB
ARM 系统中的总线:
AHB
AHB(Advanced High-performance Bus)
即高级高性能总线。
主要用于连接系统中对性能要求较高的模块。
APB
APB(Advanced Peripheral Bus)
即高级外设总线。
主要用于连接一些低速外设。
可以简单理解为:
高速/高性能模块
↓
AHB
↓
系统内部
低速外设
↓
APB
↓
GPIO、UART等外设