3. STM32MP硬件资源与引脚规划
STM32MP1系列(以STM32MP157为例)是一颗异构多核处理器:两个Cortex-A7核运行Linux,一个Cortex-M4核可运行裸机或RTOS实时任务。做数据采集与边缘服务时,第一步不是写代码,而是把"哪些外设归A7、哪些归M4、哪些引脚引出到扩展接口"规划清楚。因为STM32MP1的引脚复用(Alternate Function)极其密集,一个物理引脚往往同时挂着GPIO、I2C、SPI、UART、定时器、SAI等十几种功能,一旦设备树里分配冲突,Linux启动阶段就会报pin conflict,外设直接不可用。
一、先盘点外设资源,再谈引脚
STM32MP157的外设资源大致可分为四类,规划时应按"总线归属"来分组:
- 低速控制类:GPIO(约98个可用引脚)、I2C(I2C1/2/4/5/6)、UART/USART(UART4/5/7/8、USART1/2/3/6)、SPI(SPI1/2/4/5)。这类外设适合接传感器、EEPROM、显示屏、调试串口。
- 模拟采集类:ADC1、ADC2(12位,最多20个外部通道),以及内部温度传感器、VREFINT。ADC挂在APB总线上,采样率与时钟分频直接相关。
- 现场总线类:FDCAN1、FDCAN2(支持CAN FD),用于工业设备互联。
- 高速网络类:Ethernet MAC(GMAC,支持RGMII/RMII),配合外部PHY实现千兆/百兆以太网,是边缘服务上云的主通道。
关键点在于:外设不是"想用就能用",而是"引脚先分配、时钟再使能、设备树最后描述"。三者顺序错了,调试会非常痛苦。
二、引脚复用与设备树配置
STM32MP1的引脚复用通过pinctrl子系统管理。设备树里每个外设节点通过pinctrl-0引用一组引脚配置,而引脚配置定义在&pinctrl节点下。下面是一个典型的I2C4接温湿度传感器的配置示例:
&i2c4 {
pinctrl-names = "default", "sleep";
pinctrl-0 = &i2c4_pins_a;
pinctrl-1 = &i2c4_pins_sleep_a;
status = "okay";
clock-frequency = <100000>;
sht30: sht30@44 {
compatible = "sensirion,sht30";
reg = <0x44>;
};
};
&pinctrl {
i2c4_pins_a: i2c4-0 {
pins {
pinmux = <STM32_PINMUX('D', 6, AF4)>, /* I2C4_SCL */
<STM32_PINMUX('D', 7, AF4)>; /* I2C4_SDA */
bias-disable;
drive-open-drain;
slew-rate = <0>;
};
};
};
这里STM32_PINMUX('D', 6, AF4)的含义是:PD6引脚,选择复用功能AF4(即I2C4_SCL)。drive-open-drain是I2C必须的开漏输出,bias-disable表示不启用内部上下拉——因为I2C总线通常已有外部4.7kΩ上拉。如果漏掉开漏配置,I2C波形会拉不高,表现为总线一直忙或读不到ACK。
pin PD6 already requested by ...。排查方法是搜索设备树中所有引用该引脚的节点,确认没有两个外设同时占用同一pinmux。三、扩展接口选型与传感器连接方案
规划扩展接口时,建议按"信号类型+速率+距离"三个维度选型。下表给出一个面向数据采集的扩展接口分配示例(以STM32MP157开发板常见的40pin排针为参考):
| 接口 | 典型用途 | 速率/参数 | 注意事项 |
|---|---|---|---|
| I2C4 | SHT30温湿度、OLED | 100kHz/400kHz | 需外部上拉,地址冲突需改ADDR引脚 |
| SPI1 | ADS1256高精度ADC | 最高约10MHz | CS独立,MISO注意电平匹配 |
| UART4 | RS485/Modbus | 115200bps | 需外接MAX485收发器 |
| FDCAN1 | 工业CAN节点 | 500kbps | 需120Ω终端电阻 |
| ADC1_IN5 | 4-20mA/0-3.3V模拟量 | 12位 | 前端需分压/运放调理 |
| GMAC | 以太网上云 | 1000Mbps | 需PHY与RJ45,注意RGMII延时 |
传感器连接方案的核心是"电气匹配+协议匹配"。例如接4-20mA工业变送器时,不能直接进ADC,需先用250Ω精密电阻把电流转成1-5V,再经运放跟随器缓冲后送入ADC通道;而接SHT30这类数字传感器,只需I2C两根线加电源即可,但要注意SHT30的供电是2.4-5.5V,而STM32MP1的IO是3.3V,若传感器用5V供电,SDA/SCL需电平转换。
四、A7与M4的资源划分
异构核的资源划分是STM32MP1特有的规划难点。原则是:需要Linux网络栈、文件系统、复杂协议栈的走A7;需要硬实时、微秒级响应的走M4。例如:
- A7侧:以太网、文件存储、MQTT上云、Web服务、I2C传感器轮询。
- M4侧:CAN报文实时收发、ADC高速采样、PWM控制、紧急IO响应。
两核之间通过OpenAMP/rpmsg通信,共享内存区域需在设备树中预留(reserved-memory节点),并确保M4的固件加载地址与A7的保留区不重叠。如果M4要直接控制某个外设(如FDCAN1),则该外设在Linux设备树中应设为status = "disabled",避免两核争抢。
最后强调一个易错点:STM32MP1的ADC参考电压默认接VDDA(3.3V),若采集信号超过3.3V,必须在前端分压或限幅,否则会损坏引脚。同时ADC的采样时间参数(st,adc-channels与vref-supply)需在设备树中正确声明,否则Linux的IIO子系统读出的原始值无法换算为电压。规划阶段把这些参数和引脚一次性定好,后续采集服务的开发才能稳定推进。