3. 硬件平台选型与资源映射:ARM Cortex-A 处理器的实战选择
做工业网关,选硬件平台是第一道坎。说实话,市面上能跑 Linux 的 ARM 芯片太多了,但真正适合工控现场的,翻来覆去就那么几款。我个人习惯先看三点:外设是否齐全、供货是否稳定、社区支持是否成熟。这章我就把 i.MX6/8、AM335x、STM32MP1 这三款主流平台掰开揉碎讲清楚,再带你走一遍外设接口映射和中断控制器的配置思路。
3.1 主流 ARM Cortex-A 处理器选型对比
先看一张总览表,后面我再逐个细说。
| 处理器 | 核心架构 | 主频 | 典型 RAM | 工控优势 | 我的评价 |
|---|---|---|---|---|---|
| NXP i.MX6 | Cortex-A9 单/双/四核 | 800MHz - 1.2GHz | 512MB - 2GB DDR3 | 生态极好,资料多 | 老将,稳如磐石 |
| NXP i.MX8 | Cortex-A53/A72 异构 | 1.2GHz - 1.8GHz | 1GB - 4GB DDR4 | 性能强,带 GPU/NPU | 适合边缘计算 |
| TI AM335x | Cortex-A8 单核 | 600MHz - 1GHz | 256MB - 512MB DDR3 | PRU 协处理器,实时性好 | 工控经典,性价比高 |
| STM32MP1 | Cortex-A7 + M4 异构 | 650MHz - 800MHz | 256MB - 1GB DDR3 | 双核异构,低功耗 | 新秀,生态在追赶 |
3.1.1 i.MX6 系列:工控老兵
i.MX6 是我用得最多的平台。为什么?因为它的 BSP 最成熟,Yocto 和 Buildroot 支持都非常好。我在一个电力网关项目里用过 i.MX6 Dual Lite,跑了三年没出过问题。
它的外设接口很全:6 路 UART、2 路 CAN、2 路千兆以太网。对于大多数工业协议网关来说,这个配置绰绰有余。唯一的短板是 GPU 性能一般,但工控场景不需要花哨的界面,够用。
3.1.2 i.MX8 系列:边缘计算利器
i.MX8 系列是 i.MX6 的升级版。它用了 Cortex-A53 和 A72 的异构架构,性能提升明显。我记得有个客户要做机器视觉质检,需要同时跑 OpenCV 和多个协议栈,i.MX8M Plus 就非常合适。
但要注意,i.MX8 的功耗比 i.MX6 高不少,散热要做好。另外它的 BSP 相对复杂,第一次接触可能需要花点时间熟悉。
3.1.3 AM335x 系列:工控常青树
TI 的 AM335x 系列,尤其是 AM3358/AM3359,在工业领域地位很高。它的亮点是 PRU(可编程实时单元)。PRU 可以独立处理高速 I/O 任务,比如 EtherCAT 从站、高速脉冲采集等。
我曾经在一个运动控制网关里用 AM3359 的 PRU 做伺服驱动器的实时通信,效果非常好。主 CPU 跑 Linux 处理协议转换,PRU 负责实时控制,分工明确。
3.1.4 STM32MP1 系列:双核异构新选择
STM32MP1 是 ST 推出的双核异构处理器,一个 Cortex-A7 跑 Linux,一个 Cortex-M4 做实时控制。它的优势是 低功耗和 STM32 生态。如果你之前用过 STM32 单片机,上手会很快。
不过它的 Linux 生态还在完善中,有些驱动需要自己移植。我建议用在中等复杂度的网关项目上,比如采集几十个传感器数据,然后通过 MQTT 上传云端。
3.2 外设接口映射:从芯片引脚到 Linux 设备
选好芯片后,下一步就是外设接口映射。说白了,就是把芯片的物理引脚和 Linux 内核里的设备驱动对应起来。这部分我踩过不少坑,下面重点说几个关键接口。
3.2.1 UART 接口映射
UART 是工控网关最常用的接口,用来接 Modbus RTU、PLC、串口屏等。Linux 下 UART 设备通常映射为 /dev/ttyS0、/dev/ttyS1 等。
以 i.MX6 为例,它的 UART 引脚复用关系如下:
// 设备树中 UART2 的配置示例
&uart2 {
pinctrl-names = "default";
pinctrl-0 = &pinctrl_uart2;
status = "okay";
};
pinctrl_uart2: uart2grp {
fsl,pins = <
MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
>;
};
这里要注意 电气特性。工控现场经常有长距离通信,我建议在 UART 引脚外加 RS-485 收发器,比如 SP3485。设备树里不需要改,硬件上接好就行。
3.2.2 SPI 与 I2C 接口映射
SPI 和 I2C 主要用于板级通信,比如接 ADC、DAC、传感器、LCD 等。
- SPI:速度快,适合大数据量传输。Linux 下映射为
/dev/spidev0.0。注意 SPI 的片选信号(CS)要正确配置,否则设备无法选中。 - I2C:引脚少,适合低速设备。映射为
/dev/i2c-0。I2C 地址冲突是常见问题,建议用i2cdetect工具扫描总线。
我习惯在设备树里把 SPI 和 I2C 的引脚功能固定下来,避免和其他外设冲突。比如:
// SPI1 设备树配置
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = &pinctrl_ecspi1;
status = "okay";
spidev@0 {
compatible = "spidev";
reg = <0>;
spi-max-frequency = <20000000>;
};
};
3.2.3 CAN 接口映射
CAN 总线在工业现场非常普遍,尤其是汽车和工厂自动化。Linux 下 CAN 设备映射为 can0、can1,通过 SocketCAN 接口操作。
以 STM32MP1 为例,它的 CAN 控制器需要外接 CAN 收发器,比如 TJA1050。设备树配置如下:
// CAN1 设备树配置
&can1 {
pinctrl-names = "default";
pinctrl-0 = &pinctrl_can1;
status = "okay";
};
pinctrl_can1: can1grp {
pins1 {
pinmux = <STM32_PINMUX('A', 11, AF9)>; // CAN1_RX
bias-pull-up;
};
pins2 {
pinmux = <STM32_PINMUX('A', 12, AF9)>; // CAN1_TX
drive-open-drain;
};
};
candump can0 抓包,用 cansend can0 123#DEADBEEF 发送测试帧。如果收不到数据,先检查终端电阻(120Ω)是否接好。
3.2.4 Ethernet 接口映射
千兆以太网是工业网关的标配。Linux 下映射为 eth0、eth1。i.MX6 和 AM335x 都内置了 MAC 控制器,需要外接 PHY 芯片,比如 KSZ9031。
设备树里要指定 PHY 的地址和复位引脚:
// 以太网设备树配置
&fec1 {
pinctrl-names = "default";
pinctrl-0 = &pinctrl_enet1;
phy-mode = "rgmii";
phy-handle = &phy0;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
reg = <0>;
reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
};
};
};
嗯,这里要注意 PHY 的复位时序。有些 PHY 芯片复位后需要等待一段时间才能正常工作,我一般加一个 50ms 的延时。
3.3 GPIO 与中断控制器
GPIO 是工控网关的“手脚”,用来控制继电器、读取按钮状态、驱动 LED 等。Linux 下 GPIO 通过 /sys/class/gpio 或 libgpiod 操作。
中断控制器(GIC)负责把外设的中断信号路由到 CPU。ARM Cortex-A 系列通常使用 GIC-400 或 GIC-500。
3.3.1 GPIO 映射与操作
以 i.MX6 为例,GPIO 的编号计算方式:gpio_number = bank * 32 + pin。比如 GPIO1_IO16 就是 1 * 32 + 16 = 48。
设备树里配置 GPIO 为输出:
// GPIO 输出配置
gpio-leds {
compatible = "gpio-leds";
status = "okay";
led-red {
label = "red-led";
gpios = <&gpio1 16 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
用户空间操作:
# 导出 GPIO48
echo 48 > /sys/class/gpio/export
# 设置为输出
echo out > /sys/class/gpio/gpio48/direction
# 输出高电平
echo 1 > /sys/class/gpio/gpio48/value
3.3.2 中断控制器配置
中断控制器负责管理所有外设的中断。Linux 设备树里需要指定中断类型和触发方式。
以按键中断为例:
// 按键中断配置
gpio-keys {
compatible = "gpio-keys";
status = "okay";
button-reset {
label = "reset-button";
gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
gpio-key,wakeup;
interrupt-parent = <&intc>;
interrupts = <0 67 IRQ_TYPE_EDGE_FALLING>;
};
};
这里 interrupt-parent 指向中断控制器节点,interrupts 指定中断号和触发方式。IRQ_TYPE_EDGE_FALLING 表示下降沿触发,适合按键消抖。
3.4 知识结构图:硬件平台选型与资源映射
下面这张图总结了本章的核心知识点,从处理器选型到外设映射,再到中断管理,一目了然。
3.5 本章小结
硬件平台选型没有绝对的好坏,关键看项目需求。我个人总结了几条经验:
- 追求稳定:选 i.MX6 或 AM335x,生态成熟,资料多。
- 追求性能:选 i.MX8,适合边缘计算和视频处理。
- 追求低功耗:选 STM32MP1,双核异构灵活。
- 外设映射:设备树是核心,一定要仔细核对引脚复用。
- GPIO 和中断:工控现场必须加隔离,中断触发方式要选对。