前言

本篇是ARM嵌入式学习路线的第一天笔记,从最基础的嵌入式系统概念出发,逐层深入到计算机体系结构、指令集架构、ARM内核组成、存储器模型、栈与函数调用机制、总线结构等核心入门知识,把零散的知识点串联成完整的知识框架,适合零基础入门ARM嵌入式的同学参考。


一、嵌入式系统基础认知

1. 什么是嵌入式系统

嵌入式系统是以应用为中心,以计算机技术为基础,软硬件可裁剪的专用计算机系统,会根据具体的用户需求(功耗、体积、环境、稳定性、可靠性)做定制化设计,和日常使用的通用计算机有本质区别。

从分层结构上看,嵌入式系统从上到下分为三层:

  • 应用层(APP):面向用户的具体功能程序
  • 操作系统层(SYS):管理硬件资源、调度任务的系统软件
  • 硬件系统:底层的物理硬件实体

2. 计算机系统的基本组成

完整的计算机系统 = 硬件系统 + 软件系统

  • 软件系统又分为:应用软件(面向具体功能)、系统软件(管理硬件、提供运行环境)

经典冯诺依曼架构的硬件系统由五大核心部件组成:

  • 运算器:负责数据运算
  • 控制器:负责控制指令执行流程
  • 存储器:负责数据存储
  • 输入设备:向计算机输入信息
  • 输出设备:向外输出信息

3. 常见处理器概念辨析

很多初学者容易混淆各类处理器的概念,这里做一个清晰的区分:

处理器类型全称核心定位
CPU中央处理单元通用型强的核心处理器,负责通用计算与控制
GPU图形处理单元擅长并行图形渲染与大规模并行计算
FPU浮点运算单元专门处理高精度浮点运算
NPU神经网络处理器专门加速AI神经网络推理与运算

在嵌入式领域,还有几个核心概念:

  • MPU(微处理器):偏向通用处理,性能强,需要搭配外部存储器、外设等使用
  • MCU(微控制器):偏向控制,高度集成,芯片内集成了存储器、外设等,俗称单片机
  • 单片机:单片微型计算机系统,是MCU的通俗叫法
  • DSP(数字信号处理器):为高强度数学运算、信号处理设计的专用芯片
  • SOC(片上系统):是一种集成设计理念,把MPU、MCU、DSP、外设控制器等全部集成在同一块芯片上,像一个功能完整的“微型城市”——MPU是市政府、MCU是警察局、DSP是研究所、调制解调器是机场,所有功能模块在同一块芯片上协同工作。

二、指令集架构:CISC 与 RISC

1. 两大架构对比

目前主流的指令集架构分为两大类,对应不同的设计思路:

  • CISC(复杂指令集计算机):指令数量多、功能复杂,单条指令可以完成复杂操作,代表是X86架构(X64是X86的64位扩展)
  • RISC(精简指令集计算机):指令数量少、格式规整,单条指令功能简单,通过组合指令完成复杂任务,代表是ARM架构

设计上有一个经典的“二八定律”:20%的指令承担了80%的工作,RISC架构就是把最常用的20%指令做得精简高效,剩下的功能通过指令组合实现,以此获得更高的执行效率和更低的功耗。

常见的RISC架构除了ARM,还有MIPS、RISC-V等。

2. ARM指令集与内核版本

  • ARM指令集版本演进:V1 → V4 → V9,其中经典的版本有V4、V5、V7、V9
  • ARM内核产品线演进:早期的ARM1~ARM11,之后发展为Cortex三大系列:
    • Cortex-A系列:面向应用处理器,性能强,运行操作系统,对应MPU场景
    • Cortex-R系列:面向实时控制,高实时性,用于工业控制等场景
    • Cortex-M系列:面向微控制器,低成本低功耗,对应MCU场景

三、ARM内核核心硬件组成

ARM内核内部由多个功能单元协同工作,每个单元各司其职,共同支撑程序的运行:

1. 通用寄存器组

ARM32架构内核有16个通用寄存器R0~R15,是程序运行的核心“工作台”:

  • R0~R12:通用数据寄存器,用于存放运算数据、函数传参、临时变量
  • R13(SP,栈指针):永远指向当前栈的栈顶,管理栈空间
  • R14(LR,链接寄存器):保存函数调用、异常处理的返回地址,也就是“记住回家的路”
  • R15(PC,程序计数器):指向CPU当前正在取指的指令地址,决定程序的执行流向

2. Cache高速缓存

Cache是介于CPU和内存之间的高速缓存,解决CPU运算速度远快于内存读写速度的问题:

  • I-Cache(指令缓存):缓存即将执行的指令
  • D-Cache(数据缓存):缓存运算用到的数据
  • 作用:大幅减少CPU访问内存的次数,提升程序运行速度

3. ALU算术逻辑单元

ALU是CPU的“运算大脑”,负责完成所有的加减乘除算术运算、与或非逻辑运算、移位运算等,运算结果会自动更新程序状态寄存器的标志位。

4. MMU内存管理单元

MMU是内存管理单元,核心作用是实现虚拟地址到物理地址的映射

  • 关闭MMU:CPU直接访问物理内存地址
  • 开启MMU:CPU访问虚拟地址,由MMU翻译成物理地址
  • 额外功能:内存权限管理、内存保护,是操作系统实现多进程内存隔离的硬件基础

5. 程序状态寄存器

  • CPSR(当前程序状态寄存器):全模式共享,实时记录CPU的运算标志位、中断开关、指令集状态、当前工作模式
  • SPSR(备份程序状态寄存器):每个异常模式独有一个,异常发生时自动备份CPSR的值,异常返回时恢复状态

6. 外设寄存器

内核通过外设寄存器控制片上外设,比如GPIO(通用输入输出)、PWM(脉冲宽度调制)、UART(串口)、定时器等,每个外设对应一组寄存器,通过读写寄存器实现对外设的控制。


四、ARM总线架构

总线是CPU和存储器、外设之间传输数据的“高速公路”,ARM系统中分为三类核心总线:

  1. 数据总线:32根,负责在各个部件之间传输数据,宽度决定了一次能传输的数据量
  2. 地址总线:32根,负责传输内存/外设的地址,32位地址总线可寻址范围是 0x00000000 ~ 0xFFFFFFFF,共4GB地址空间
  3. 控制总线:传输控制信号,比如读写控制、中断信号等

按照总线速度和用途,又分为两大类:

  • AHB:先进高速总线,用于连接高速部件,比如内存、DMA、高速外设
  • APB:先进外设总线,用于连接低速外设,比如GPIO、UART、定时器等

五、存储器体系:RAM 与 ROM

存储器是嵌入式系统的核心存储部件,分为两大类,特点完全不同:

1. RAM(随机访问存储器)

  • 特点:可被处理器直接寻址、读写速度快、单位存储成本高、断电后数据丢失(易失性)
  • 典型代表:SRAM、DRAM
  • 作用:运行程序时存放代码、变量、栈、堆等临时数据

2. ROM(只读存储器)

  • 特点:一般不能被处理器直接寻址、单位存储成本低、断电后数据不丢失(非易失性)、读写速度慢
  • 典型代表:Nor Flash、Nand Flash
  • 作用:存放固件、程序镜像、永久保存的数据

3. 虚拟内存空间布局(32位系统)

开启MMU后,CPU看到的是虚拟内存空间,32位系统地址范围从0x000000000xFFFFFFFF,从低地址到高地址大致分为:

  • 代码段:存放程序的可执行指令
  • 数据段:存放已初始化的全局变量、静态变量
  • BSS段:存放未初始化的全局变量,启动时自动清0
  • 堆区:动态分配的内存,由低地址向高地址增长
  • 栈区:存放函数局部变量、栈帧,由高地址向低地址增长
  • 操作系统内核区:高地址区域,存放内核代码和数据

六、栈与函数调用机制

栈是ARM程序运行的核心机制,函数调用的整个过程都围绕栈和三个特殊寄存器展开。

1. 栈的基本概念

栈是内存中一块“后进先出”的存储区域,每个函数运行时都会在栈上分配一块专属空间,叫做栈帧,用来存放函数的形参、局部变量、临时数据。

  • ARM默认采用满递减栈:栈底在高地址,栈顶向低地址方向增长
  • SP寄存器永远指向当前栈的栈顶

2. 函数调用的完整过程(结合栈帧)

main调用fun1为例,整个过程中SP、LR、PC三个寄存器协同工作:

阶段1:调用前,运行在main函数
  • SP指向main函数栈帧的栈顶,栈里存放main的局部变量a=100b=200
  • PC顺着main的代码一步步执行,走到调用fun1的指令处
阶段2:执行BL跳转指令(函数调用)

BL是带返回的跳转指令,硬件自动完成两件事:

  1. 把调用指令的下一条指令地址存入LR寄存器,记下“返回地址”
  2. 把fun1的入口地址写入PC,CPU跳转到fun1执行
阶段3:进入fun1函数执行
  • SP移动位置,为fun1分配新的栈帧,存放fun1的形参a、b和局部变量sum
  • PC指向fun1内部正在执行的指令
  • LR仍然保存着返回main的地址
阶段4:函数返回

fun1执行return时,本质是把LR的值写回PC,CPU跳回main函数继续执行;同时SP往回移动,回收fun1的栈帧。

3. 三级流水线

ARM内核采用三级流水线架构,指令执行分为三个阶段并行执行:

  1. 取指:从内存中读取指令
  2. 译码:解析指令的功能
  3. 执行:执行指令运算

三级流水线同时工作,同一时刻有三条指令分别处于取指、译码、执行阶段,大幅提升CPU的执行效率。这也是为什么PC值不等于当前执行指令地址,而是当前指令地址+8的原因。


七、GCC编译基本流程

C语言代码要变成可执行程序,需要经过GCC编译器的四步处理:

  1. 预处理gcc -E main.c -o main.i
    • 处理头文件、宏定义、条件编译,生成预处理后的.i文件
  2. 编译gcc -S main.i -o main.s
    • 把C代码翻译成ARM汇编代码,生成.s汇编文件
  3. 汇编gcc -c main.s -o main.o
    • 把汇编代码翻译成机器码,生成.o目标文件
  4. 链接gcc main.o -o main.out
    • 把多个目标文件、库文件链接在一起,生成最终的可执行程序

学习总结

第一天的学习是ARM嵌入式的基础入门,核心是建立完整的体系认知:

  1. 从嵌入式概念出发,理解SOC的集成设计思想
  2. 分清CISC和RISC的区别,了解ARM的产品线定位
  3. 掌握ARM内核的核心组成,尤其是特殊寄存器的功能
  4. 理解存储器分类和内存空间布局
  5. 吃透栈帧机制和函数调用过程,这是后续汇编、异常处理的基础
  6. 了解总线结构和编译流程,建立从代码到硬件执行的完整认知
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐