1. STM32MP平台与Linux驱动体系概览

STM32MP1 与 STM32MP2 是 ST 面向嵌入式 Linux 场景推出的异构多核微处理器系列。理解这套平台,关键不是先背寄存器,而是先建立一张“硬件—内核—驱动—应用”的整体地图:谁负责实时控制,谁负责操作系统与外设管理,驱动代码又挂在内核的哪一层。只有把这张地图建立起来,后续的字符设备、平台设备、设备树、总线与子系统学习才不会变成零散知识点的堆叠。

一、硬件架构:双核异构是理解一切的起点

以 STM32MP157 为例,芯片内部同时存在两个 Cortex-A7 核(可组成 SMP 双核 Linux 运行环境)和一个 Cortex-M4 核。A7 侧运行 Linux,负责内存管理、文件系统、网络、图形与复杂外设;M4 侧通常运行裸机或 RTOS 固件,承担电机控制、采样闭环、硬实时中断等任务。两者不是主从替代关系,而是分工协作:A7 提供生态与算力,M4 提供确定性与低延迟。

两核之间通过共享内存与 IPCC 邮箱中断通信。典型做法是:在设备树中保留一段 no-map 的 reserved-memory 作为共享缓冲区,A7 侧用 rpmsg 字符设备或 remoteproc 框架加载 M4 固件,M4 侧用 OpenAMP 收发消息。这样,Linux 应用可以通过标准文件接口向 M4 下发控制参数,M4 把采集结果回传,形成“Linux 管策略、M4 管实时”的结构。

STM32MP2 在此基础上进一步强化:Cortex-A35 双核替代 A7,加入 NPU、M33 实时核与更丰富的高速接口,但异构协作模型与驱动分层思想保持一致。因此本章以 MP1 为主线建立概念,MP2 的差异在后续章节按外设展开。

二、Linux 内核驱动模型分层

Linux 不是“一个驱动对应一个外设”的扁平结构,而是分层模型。最上层是用户空间:应用通过 /dev、/sys、/proc 访问设备。其下是内核中的子系统层,例如 tty、input、iio、net、mmc、drm;子系统向上提供统一接口,向下定义驱动需要实现的 ops 集合。再往下是核心层与总线层:platform、i2c、spi、usb 等总线负责设备与驱动的匹配。最底层才是具体 SoC 的控制器驱动,例如 STM32 的 USART、I2C、SPI、DMA 控制器驱动。

设备树(Device Tree)是这条链路的“配置描述层”。它不写代码逻辑,只描述“哪个地址、哪个中断、哪个时钟、哪个引脚、挂在哪个总线”。驱动通过 of_match_table 与设备树节点匹配,匹配成功后 probe() 被调用,完成寄存器映射、时钟使能、中断注册与子系统注册。因此,一个外设能否工作,往往取决于三件事是否同时正确:设备树节点、驱动匹配表、子系统注册路径。

STM32MP 异构平台与 Linux 驱动分层关系 SoC 硬件侧 Cortex-A7 ×2(SMP) 运行 Linux 内核 MMU / 缓存 / 虚拟内存 Cortex-M4 / M33 裸机或 RTOS 固件 硬实时 / 低延迟中断 共享内存 + IPCC 邮箱 rpmsg / OpenAMP 通道 外设控制器 USART / I2C / SPI / DMA GPIO / TIM / ADC / ETH 中断控制器 GIC / EXTI Linux 内核驱动分层 用户空间接口层 /dev · /sys · /proc · ioctl 子系统层 tty · input · iio · net · mmc · drm 总线与核心层 platform · i2c · spi · usb 匹配 SoC 控制器驱动 probe() · 寄存器 · 时钟 · 中断 设备树描述层 compatible · reg · interrupts clocks · pinctrl · status of_match_table 匹配驱动 外设平台集成目标 设备树可描述 引脚 / 时钟 / 中断可配 驱动可匹配 probe 成功、无资源冲突 子系统可注册 生成 /dev 或 /sys 节点 应用可访问 读写 / ioctl / 事件上报 A7 与 M4 协同 策略与实时分工 匹配

三、从“能启动”到“能集成”的关键判断

很多初学者把驱动开发理解为“写一个模块然后 insmod”。在 STM32MP 平台上,更常见的路径是:先确认设备树节点是否存在且 status = "okay",再确认内核配置中对应驱动是否编译进内核或模块,然后看 dmesg 中 probe 是否成功。若 probe 失败,常见原因包括:时钟未使能、pinctrl 引脚冲突、中断号错误、reg 地址与 reserved-memory 重叠、依赖的 regulator 未就绪。这些都不是“代码写错”,而是平台集成信息不完整。

因此,学习路径应当按“先结构、后接口、再调试”推进:先理解 A7/M4 分工与内核分层,再掌握设备树与 platform 驱动匹配,然后进入字符设备、GPIO、I2C、SPI、IIO、DMA 等具体外设,最后回到 rpmsg/remoteproc 完成异构协同。每一层都要能回答三个问题:输入是什么、内核发生了什么、结果如何验证。

本章的定位是“建立地图”,不要求立刻写出完整驱动。建议在阅读后续章节时,始终把具体外设放回本图的四层结构中:它属于哪个子系统、挂在哪个总线、设备树节点叫什么、probe 成功后生成什么用户接口。这样,零散的外设知识才会收敛成一套可复用的平台集成方法。

四、学习路径与阶段目标

第一阶段:能读懂 STM32MP157 的设备树,找到 UART、I2C、SPI 节点,理解 compatible、reg、interrupts、clocks、pinctrl 的含义。第二阶段:能编写并加载一个 platform 驱动,通过 of_match_table 匹配设备树节点,在 probe 中完成寄存器映射与字符设备注册。第三阶段:能针对具体外设选择正确子系统,例如用 IIO 做 ADC 采集、用 input 做按键、用 tty 做串口。第四阶段:能通过 rpmsg 让 A7 应用与 M4 固件交换数据,完成“Linux 策略 + 实时控制”的闭环。