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排针为参考):

接口典型用途速率/参数注意事项
I2C4SHT30温湿度、OLED100kHz/400kHz需外部上拉,地址冲突需改ADDR引脚
SPI1ADS1256高精度ADC最高约10MHzCS独立,MISO注意电平匹配
UART4RS485/Modbus115200bps需外接MAX485收发器
FDCAN1工业CAN节点500kbps需120Ω终端电阻
ADC1_IN54-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",避免两核争抢。

STM32MP157 外设资源与引脚规划关系图 Cortex-A7 (Linux) GMAC 以太网 I2C4 传感器 SPI1 高精度ADC UART4 Modbus MQTT / Web / 文件系统 / 边缘计算 Cortex-M4 (RTOS/裸机) FDCAN1 实时收发 ADC1 高速采样 PWM 控制输出 GPIO 紧急响应 微秒级实时任务 / 硬中断处理 rpmsg 共享内存 引脚复用层 (pinctrl) — 设备树统一描述 PD6 → AF4 (I2C4_SCL) PD7 → AF4 (I2C4_SDA) PA11 → AF9 (FDCAN1_RX) PA12 → AF9 (FDCAN1_TX) 扩展接口 / 传感器连接 I2C 排针 SPI 排针 RS485 收发器 CAN 收发器 RJ45

最后强调一个易错点:STM32MP1的ADC参考电压默认接VDDA(3.3V),若采集信号超过3.3V,必须在前端分压或限幅,否则会损坏引脚。同时ADC的采样时间参数(st,adc-channels与vref-supply)需在设备树中正确声明,否则Linux的IIO子系统读出的原始值无法换算为电压。规划阶段把这些参数和引脚一次性定好,后续采集服务的开发才能稳定推进。