news 2026/6/4 17:17:25

单片机架构与内核概念辨析-基于M3/M4内核分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
单片机架构与内核概念辨析-基于M3/M4内核分析

单片机内核

什么是内核?这是一个很抽象的问题。有时会听到 ARMv7-M、ARMv7-A 架构,又听过 Cortex-M3、Cortex-M4 内核——它们分别是什么?本文以 M3/M4 内核为切入点,介绍内核与架构的基本概念。

本文以文字为主,尽量简单描述。

M3/M4 内核

先看下面这张M3/M4 内核框图(这里先不用纠结“内核”到底是什么意思)。看到这张图,你可能会产生两个疑问:

  1. 为什么 M3 和 M4 的内核框图可以共用同一张图?
  2. 图中为什么没有外设?

问题一:为什么 M3/M4 共用同一张框图?

查阅 M3 和 M4 的内核手册会发现,它们的内容几乎完全一样——无论是内核寄存器(R0~R15),还是特殊功能寄存器(xPSR、CONTROL 等)。这是因为它们都隶属于ARMv7-M 架构,因此寄存器、流水线设计等均相同(流水线细节不了解也没关系)。

有兴趣的话可以对比core_cm3.hcore_cm4.h两个文件,你会发现它们基本一致。甚至内核中最核心的“内核外设”(区别于芯片厂商添加的片上外设)——如 NVIC、SysTick、MPU、SCB 以及调试相关的 ITM、DWT、IPI——也完全相同,连地址都一样。

这种一致性正是“同属 ARMv7-M 架构”的体现。ARMv7-M 架构规定了内核的流水线设计,并强制包含 NVIC、SysTick 等单元(图中已标出),同时包含可选的 MPU 和调试单元(M3/M4 都实现了)。这些单元的统一地址也是 ARMv7-M 规范的一部分。

那么,不同之处在哪里?M4 包含浮点运算单元(FPU),而 M3 没有。这是两者最大的差异。为什么一个有 FPU、一个没有,却都属于 ARMv7-M?因为 ARMv7-M 架构允许在系统控制空间(SCS)的地址范围内添加不同的内核单元来实现功能扩展。FPU 的存在与否并未跳出 ARMv7-M 的框架,但有了 FPU 就可以执行浮点运算指令。

至此,第一个问题已解答:M3/M4 共用同一框图,因为它们差异不大且同属 ARMv7-M。但需要注意,ARMv7-M 并不只包含 M3/M4——例如 M7 内核还增加了 Cache。更准确的理解是:M3/M4/M7 都是 ARMv7-M 架构的具体实现子集

问题二:为什么框图中没有外设?

如果对 STM32 有较深入的理解,不难知道:所谓外设,对内核而言就是挂载在地址总线上的一些寄存器。内核通过地址总线访问它们,再通过数据总线读写数据。外设这部分完全由芯片厂商自由设计——这就是为什么即使都是 M3/M4 内核,不同芯片的外设差异却很大。

尽管外设不同,但内核访问它们的方式完全一样(如 LDR、STR 指令),只是寄存器的值设置不同,导致外设的工作模式不同。因此,外设不属于内核的一部分,但地址/数据总线属于内核设计的一部分。

小结:什么是内核?什么是架构?

基于以上分析,可以这样理解:

  • 内核:执行指令所需的硬件支持。
  • 架构:一种内核设计蓝图。

因此:

  • ARMv7-M提供整体设计框架;
  • Cortex-M3 / M4 / M7是该框架的具体实现;
  • STM32F407VET6则是这个具体实现再加上厂商配套的外围设施。

内核寄存器和内核外设

上一小节说到内核是一种具体实现,其中这个具体实现中相同的部分主要是内核寄存器和内核外设,所以我们这里主要介绍以下M4内核,相信读者到这里为止对内核,架构,具体芯片应该有了一定的了解了。

在地址划分中有一块称为“私有外设总线”(PPB)的区域,与内核框图中底部的 PPB 对应,通过专用总线访问。这部分与普通外设不同,包含的单元与内核工作模式紧密相关,我称之为内核外设

本文重点介绍三个核心部分:NVIC、SCB、SysTick。其他部分触类旁通,可自行探索。在此之前,先介绍内核寄存器。

推荐参考《M3/M4 内核权威指南》,讲解非常详细,大多数问题都能从中找到答案。

内核通用寄存器

  • R0~R12:通用目的寄存器,主要用于数据计算和缓存。
  • R13(SP):堆栈指针寄存器。程序运行时自动切换主栈指针(MSP)和进程栈指针(PSP)。
  • R14(LR):连接寄存器,通常保存程序返回地址。
  • R15(PC):程序计数器,始终指向下一条要执行的指令。

R0~R12没有太多特别之处,主要用于缓存临时变量。函数调用时部分寄存器用于传递参数。

SP(栈指针)在物理上只有一个寄存器,但对应两个逻辑指针(MSP 和 PSP),具体使用哪个由特殊寄存器 CONTROL 决定。中断中使用 MSP,裸机程序中也使用 MSP,而在 RTOS 环境下任务运行时使用 PSP。掌握这些基本够用。

LR(连接寄存器)的使用可分为三种场景:

  1. 中断打断了主程序
  2. 中断嵌套
  3. 函数调用

前两种属于中断场景:

  • 中断发生时会自动将xPSR, PC, LR, R12, R3, R2, R1, R0压入当前栈。
  • 中断函数执行结束后,LR 通常保存一个特殊值(称为特殊值1),执行BX LR即可自动恢复现场,继续执行主程序。
  • 若发生中断嵌套,硬件同样自动压栈,LR 保存另一个特殊值(特殊值2),执行BX LR恢复上一层中断现场。

在这两种中断场景中,LR 存放的是特殊值,真正的返回地址来自压栈的 PC 值。

函数调用场景:

  • 硬件不会自动压栈,需要软件手动压栈(通常保存 R4~R11,或根据需求额外保存)。
  • 此时 LR 保存的是真正的返回地址(上一级函数中下一条指令的地址),最后通过BX LR跳转回去。

PC始终指向下一条要执行的指令。

内核特殊寄存器

1. xPSR(组合程序状态寄存器)

32 位寄存器,反映 CPU 的运算状态和当前异常编号,由三个子寄存器组成:

  • APSR(位 [31:27]):包含 N(负)、Z(零)、C(进位/借位)、V(溢出)、Q(饱和标志,仅 M4/M7 等支持 DSP 的内核有)。
  • EPSR(位 [24]):T(Thumb 位),必须为 1。若清零,执行指令会触发 HardFault(Cortex-M 只支持 Thumb 指令集)。
  • IPSR(位 [8:0]):Exception Number,记录当前正在执行的异常/中断编号(0 表示主程序,16 以上为外部中断)。
2. PRIMASK(优先级屏蔽寄存器)
  • 位数:1 位
  • 含义:“全局中断开关”
  • 作用:置 1 时屏蔽所有可配置优先级的中断,只有 NMI 和 HardFault 能抢占。
  • 常用场景:进入临界区(Critical Section)时调用__disable_irq()将其置 1。
3. FAULTMASK(异常屏蔽寄存器)
  • 位数:1 位
  • 含义:“更高级别的屏蔽”
  • 作用:比 PRIMASK 更强。置 1 时甚至能屏蔽 HardFault,只有 NMI 可以抢占。
  • 常用场景:极少数极其关键的系统错误处理代码。
4. BASEPRI(基本优先级屏蔽寄存器)
  • 位数:8 位(实际有效位数由芯片厂商决定,通常为高 3 或 4 位)
  • 含义:“优先级阈值过滤”
  • 作用:设定一个阈值。例如设为0x50,所有优先级数值大于等于0x50(即优先级较低)的中断都会被屏蔽,而优先级高于0x50的中断仍可触发。
  • 常用场景:RTOS(如 FreeRTOS)用于中断嵌套管理,既能保护内核任务,又不像 PRIMASK 那样一刀切。
5. CONTROL(控制寄存器)

决定 CPU 的“身份”和“装备”:

  • nPRIV(位 [0]):0 = 特权级,1 = 用户级(非特权,限制访问某些特殊寄存器)。
  • SPSEL(位 [1]):0 = 使用主栈指针(MSP),1 = 使用进程栈指针(PSP)。
  • FPCA(位 [2])(仅带 FPU 的内核):表示当前是否使用浮点单元。若为 1,中断入栈时会额外压入浮点寄存器。

这些寄存器没有内存地址,只能通过MRS(读)和MSR(写)指令访问。

内核外设

寄存器部分较为枯燥,此处仅列出各内核外设的寄存器结构(直接从core_cm4.h复制)。如需深入了解,可借助 AI 工具或查阅手册。(其实这个代码在使用cubemx创建的工程中就会生成的,也可直接在评论区@我。这个手册网上还是比较好找的)

1. SCB 寄存器
typedefstruct{__IMuint32_tCPUID;/*!< Offset: 0x000 (R/ ) CPUID Base Register */__IOMuint32_tICSR;/*!< Offset: 0x004 (R/W) Interrupt Control and State Register */__IOMuint32_tVTOR;/*!< Offset: 0x008 (R/W) Vector Table Offset Register */__IOMuint32_tAIRCR;/*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */__IOMuint32_tSCR;/*!< Offset: 0x010 (R/W) System Control Register */__IOMuint32_tCCR;/*!< Offset: 0x014 (R/W) Configuration Control Register */__IOMuint8_tSHP[12U];/*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */__IOMuint32_tSHCSR;/*!< Offset: 0x024 (R/W) System Handler Control and State Register */__IOMuint32_tCFSR;/*!< Offset: 0x028 (R/W) Configurable Fault Status Register */__IOMuint32_tHFSR;/*!< Offset: 0x02C (R/W) HardFault Status Register */__IOMuint32_tDFSR;/*!< Offset: 0x030 (R/W) Debug Fault Status Register */__IOMuint32_tMMFAR;/*!< Offset: 0x034 (R/W) MemManage Fault Address Register */__IOMuint32_tBFAR;/*!< Offset: 0x038 (R/W) BusFault Address Register */__IOMuint32_tAFSR;/*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */__IMuint32_tPFR[2U];/*!< Offset: 0x040 (R/ ) Processor Feature Register */__IMuint32_tDFR;/*!< Offset: 0x048 (R/ ) Debug Feature Register */__IMuint32_tADR;/*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */__IMuint32_tMMFR[4U];/*!< Offset: 0x050 (R/ ) Memory Model Feature Register */__IMuint32_tISAR[5U];/*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */uint32_tRESERVED0[5U];__IOMuint32_tCPACR;/*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */}SCB_Type;
2. NVIC 单元寄存器
typedefstruct{__IOMuint32_tISER[8U];/*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */uint32_tRESERVED0[24U];__IOMuint32_tICER[8U];/*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */uint32_tRESERVED1[24U];__IOMuint32_tISPR[8U];/*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */uint32_tRESERVED2[24U];__IOMuint32_tICPR[8U];/*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */uint32_tRESERVED3[24U];__IOMuint32_tIABR[8U];/*!< Offset: 0x200 (R/W) Interrupt Active bit Register */uint32_tRESERVED4[56U];__IOMuint8_tIP[240U];/*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */uint32_tRESERVED5[644U];__OMuint32_tSTIR;/*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */}NVIC_Type;
3. SysTick 单元寄存器
typedefstruct{__IOMuint32_tCTRL;/*!< Offset: 0x000 (R/W) SysTick Control and Status Register */__IOMuint32_tLOAD;/*!< Offset: 0x004 (R/W) SysTick Reload Value Register */__IOMuint32_tVAL;/*!< Offset: 0x008 (R/W) SysTick Current Value Register */__IMuint32_tCALIB;/*!< Offset: 0x00C (R/ ) SysTick Calibration Register */}SysTick_Type;

声明:本文内容为作者原创笔记。在写作过程中使用了 AI 辅助工具进行语言润色和排版优化,但所有技术观点、分析及结论均来自作者本人。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 17:14:13

基于Arduino的R5-D4机器人制作:从步进电机控制到莫尔斯电码LED

1. 项目概述与核心价值如果你是一个《星球大战》的粉丝&#xff0c;或者对机器人、嵌入式编程感兴趣&#xff0c;那么亲手制作一个能眨眼、会转头的R5-D4机器人模型&#xff0c;绝对是一件充满乐趣和成就感的事情。R5-D4是星战宇宙中一个相对低调但辨识度很高的宇航技工机器人&…

作者头像 李华
网站建设 2026/6/4 17:13:05

AI工具与POS/ERP深度对接全解析,中小商户收款自动化落地最后一公里

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;AI工具与智能收款整合 人工智能正深度重构支付基础设施&#xff0c;将自然语言理解、实时风险建模与自动化决策能力注入传统收款流程。智能收款不再仅是资金到账的终点&#xff0c;而是以AI为中枢的动态服务闭…

作者头像 李华
网站建设 2026/6/4 17:10:48

APatch内核模块开发深度解析:从系统级Hook到内核Patch实现原理

APatch内核模块开发深度解析&#xff1a;从系统级Hook到内核Patch实现原理 【免费下载链接】APatch The patching of Android kernel and Android system 项目地址: https://gitcode.com/gh_mirrors/ap/APatch APatch作为Android系统内核级修改工具&#xff0c;通过其独…

作者头像 李华