当前位置:首页 > 工业控制 > 工业控制
[导读]工业主板(如 i.MX6ULL、RK3568、Amlogic A311D 方案)的外设往往不像树莓派那样"默认全开"——CAN、RS485、SPI ADC、I2C 温湿度、GPIO 按键,每款底板的引脚定义都不一样,内核 defconfig 开好了驱动也只是"编进去了",真正要让 /dev/ 下出设备,还得改设备树(DTS)+ 保证驱动加载。下面以 i.MX6ULL 工业板(原厂 DTS 只开了 UART1/ETH,要加 UART3-RS485 + CAN0 + SPI ADC)为主线。

工业主板(如 i.MX6ULL、RK3568、Amlogic A311D 方案)的外设往往不像树莓派那样"默认全开"——CAN、RS485、SPI ADC、I2C 温湿度、GPIO 按键,每款底板的引脚定义都不一样,内核 defconfig 开好了驱动也只是"编进去了",真正要让 /dev/ 下出设备,还得改设备树(DTS)+ 保证驱动加载。下面以 i.MX6ULL 工业板(原厂 DTS 只开了 UART1/ETH,要加 UART3-RS485 + CAN0 + SPI ADC)为主线。

一、设备树改什么:pinctrl + 节点 + status

设备树不是改驱动代码,而是告诉内核"哪个外设挂哪根引脚、用什么时钟、地址多少"。三件事:

1. pinctrl:引脚复用 + 电气属性

i.MX 系列用 iomuxc 节点,每个外设建一个 pinctrl_xxx 子节点,含引脚号(寄存器偏移)、复用功能(ALT 模式)、上下拉、驱动强度。

/* imx6ull-14x14-evk.dts 片段:加 UART3-RS485 + CAN0 */

&iomuxc {

pinctrl_uart3_rs485: uart3rs485grp {

fsl,pins = <

MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX  0x1b0b1  /* TX, ALT1, 47k上拉 */

MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX  0x1b0b1  /* RX */

MX6UL_PAD_UART2_CTS_B__GPIO1_IO14      0x1b0b1  /* RTS 复用 GPIO 控方向 */

>;

};

pinctrl_flexcan1: can0grp {

fsl,pins = <

MX6UL_PAD_UART4_TX_DATA__FLEXCAN1_TX   0x1b0b0

MX6UL_PAD_UART4_RX_DATA__FLEXCAN1_RX   0x1b0b0

>;

};

};

0x1b0b1 是电气属性(PKE=使能保持、PUE=上拉、PUS=47k、SPEED=100MHz、DSE=驱动强度),参照 IMX6ULLRM 的 SW_PAD_CTL 寄存器填。

2. 外设节点:挂 pinctrl + 参数

&uart3 {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_uart3_rs485>;

linux,rs485-enabled-at-boot-time;   /* 开机即 RS485 模式 */

rts-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;

status = "okay";

};

&can1 {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_flexcan1>;

xceiver-supply = <®_can_3v3>;    /* 3.3V 收发器供电 */

status = "okay";

};

⚠ status = "disabled" 是出厂默认值,不改 "okay" 驱动 probe 不到,这是新手最常见的坑。

3. 编译 & 替换

# 在内核源码根目录

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs

# 拷到板子(TFTP 或 scp)

scp arch/arm/boot/dts/imx6ull-14x14-evk.dtb root@192.168.1.100:/boot/

reboot

# bootloader 加载新 dtb 后,dmesg | grep -E "uart|can" 看 probed 没

二、驱动加载:builtin vs module

驱动两种形态,工业板按需选:

① builtin(Y)= 编进 uImage/zImage

• DTS status="okay" 后内核启动时自动 probe()

• 适合必用外设(CAN、ETH、UART)

• 改 DTS 后重编 dtb + 重启即可,不用动驱动

② module(M)= 编成 .ko,modprobe 加载

• 适合现场可换的外设(SPI ADC 模组、4G 模组、不同型号 RTC)

• 好处:不用重烧内核,换 KO 就行;坏处:开机要 systemd 或 rc.local 里 modprobe

# 内核 menuconfig 把 SPIDEV 改 M

make ARCH=arm menuconfig

# Device Drivers → SPI → User mode SPI →spidev

make modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

# 拷 KO 到板子

scp drivers/spi/spidev.ko root@192.168.1.100:/lib/modules/$(uname -r)/kernel/drivers/spi/

ssh root@192.168.1.100 "depmod -a && modprobe spidev"

# 看 /dev/spidev32766.0 是否出来

DTS 里 SPI 节点要配 spidev 兼容:

&ecspi1 {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_ecspi1>;

status = "okay";

adc_dev@0 {

compatible = "rohm,dh2228fv";   /* spidev 通用兼容 */

reg =;

spi-max-frequency =;

};

};

三、现场适配:DTS Overlay 救急

工业主板经常"同 CPU 底板换三款"(A 款带 RS485、B 款带 CANopen、C 款带 4G),全重编 DTB 麻烦,用 DTS Overlay(fdtoverlay 命令把 .dtbo 贴到主 DTB 上):

/* overlay: 只加 RS485 RTS 反相(某款底板 RTS 低有效) */

/dts-v1/;

/plugin/;

&uart3 {

rts-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;  /* 改极性 */

};

# 板端合成

fdtoverlay -i /boot/imx6ull.dtb -o /boot/imx6ull-custom.dtb /boot/rs485-rts.dtbo

# uboot 里改 fdt_file=imx6ull-custom.dtb

RK3568 工业板更方便,U-Boot 阶段通过 fdt set 命令改节点状态,不用重编译。

四、三个翻车高发点

• pinctrl 冲突:同一个引脚在 pinctrl_uart3 和 pinctrl_gpio 里都被占了,内核启动时 pinctrl_probe 报 pin already requested,后面那个外设 probe 失败。改 DTS 前先 cat /sys/kernel/debug/pinctrl/pinctrl-handles 看占用

• CAN 没 xceiver-supply:flexcan probe 成功但 ip link set can0 up 时报 No such device,是因为收发器供电没配,3.3V 那路 regulator 没 status="okay"

• RS485 没配 RTS GPIO:linux,rs485-enabled-at-boot-time 开了但 RTS 悬空,发数据时 DE/RE 没拉,对端收不到。必须 rts-gpios 指到具体 GPIO,且 pinctrl 里这个 GPIO 也要配(不能只配 TX/RX)

调试窍门:dmesg | grep "failed to get pinctrl" 是 DTS 第一排查点;ls /dev/ 看不到设备 → 查 status 是不是还是 disabled;modprobe 报错 Unknown symbol → 先 depmod -a 再加载。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

设备树(Device Tree, DTB)是嵌入式Linux系统中描述硬件的“骨架”。一个错误的status、一个拼错的compatible,就可能导致外设驱动无法加载或系统崩溃。本文总结十个在ARM/Linux设备树编...

关键字: 嵌入式Linux 设备树

在嵌入式Linux开发中,设备树(Device Tree)已成为描述硬件的标准。它让内核与硬件解耦,实现“一份内核,适配万千板卡”。本文将跳过繁杂的理论,直击设备树节点编写与内核驱动匹配的核心流程。

关键字: 嵌入式Linux 设备树 Device Tree

在嵌入式Linux开发中,设备树(Device Tree)已成为硬件描述与内核解耦的核心机制。传统静态设备树在编译时固化硬件信息,难以适应多变的硬件配置需求。而动态设备树配置技术通过设备树叠加(Overlay)机制,允许...

关键字: 嵌入式Linux 设备树

在嵌入式Linux开发中,设备树(Device Tree)已成为硬件抽象的核心机制,其通过动态描述硬件资源,使内核能够灵活适配不同硬件平台。本文聚焦GPIO与中断资源的设备树映射技术,结合实际案例解析其配置方法与优化策略...

关键字: 嵌入式Linux 设备树 GPIO

随着嵌入式系统的广泛应用,触摸屏作为人机交互的重要接口,其驱动开发变得愈发重要。本文将详细介绍在嵌入式Linux环境下,触摸屏驱动的开发流程,从设备树的配置到校准算法的实现,为读者提供一个全面的开发指南。

关键字: 嵌入式Linux 触摸屏 校准算法 设备树

系统采用的是最普通的USB摄像头,主芯片为中星微ZC0301P。这种摄象头的一个特点是可以实现硬件JPEG编码。其驱动程序的编写重点包括下面的内容:提供基本的I/O 操作接口函数open、read、write、close...

关键字: s3c2410 spca5xx 驱动加载
关闭