树莓派4接ADIS16507-1时spi_bcm2835符号版本不匹配问题
问题现象
树莓派4外接ADIS16507-1 IMU传感器时,系统IIO总线无法枚举到对应设备,先后两次编译内核驱动分别遇到不同报错,具体排查过程和对应解决方法如下:
第一次尝试:编译ADI定制内核全模块加载失败
现象
按照厂商指引编译适配ADIS16475系列IIO传感器的定制内核,刷入写入2021-10-30-raspios-bullseye-armhf-lite.img版本系统的SD卡后,/sys/bus/iio/devices/路径下无预期的iio:device0节点。
系统启动后dmesg输出大量模块符号版本不匹配报错,spi_bcm2835、rfkill、uio、llc等所有模块均无法通过modprobe/insmod加载,执行sudo modprobe spi-bcm2835返回错误:
modprobe: ERROR: could not insert 'spi_bcm2835': Invalid argument
核查运行内核版本号为5.10.63-v7l+,与编译时使用的内核源码版本号完全一致。
根因
该报错并非内核主版本号不匹配导致,本质是编译内核后未将配套编译生成的内核模块完整同步到SD卡的根文件系统,内核运行时加载模块会校验符号CRC值,系统内存储的旧模块/其他版本模块与当前运行内核符号校验值不匹配,就会触发所有模块加载失败。
解决方法
编译完定制内核后,除了刷写kernel镜像、dtb设备树等启动分区文件外,必须执行模块安装命令,将编译生成的所有模块同步写入SD卡根分区的/lib/modules/<对应内核版本>目录,确保模块与运行内核完全同源,即可解决符号校验报错问题。
第二次尝试:官方内核编译ADIS16475驱动SPI匹配失败
现象
放弃ADI定制内核,改用官方树莓派系统方案:刷入最新版Raspberry Pi Lite OS,更新系统后对齐运行内核版本与官方内核仓库版本为5.15.50-v7l+,按照官方内核编译教程开启以下配置项:
CONFIG_SPI_MASTER=y CONFIG_IIO=y CONFIG_ADIS16475=m CONFIG_IIO_KFIFO_BUF=y CONFIG_SPI_BCM2835=y
编译安装完成后执行sudo modprobe adis16475加载驱动,dmesg输出全系列ADI IMU器件的spi_device_id缺失报错,覆盖adis16470、adis16475全系列、adis16477全系列、adis16465全系列、adis16467全系列、adis16500、adis16505全系列、adis16507全系列型号。
根因
5.15版本主线内核内置的adis16475驱动代码未合并ADIS16507等后续发布型号的SPI设备ID表项,SPI核心匹配设备时无法将ADIS16507-1设备与adis16475驱动绑定,因此无法生成IIO设备节点。
解决方法
- 修改内核源码中
drivers/iio/imu/adis16475.c文件:找到spi_device_id定义数组,补充所有报错中列出的器件ID,包括目标器件{ "adis16507-1", 0 };同时在驱动的of_match_table设备树匹配表中同步补充对应compatible属性项。 - 重新编译内核和驱动模块,执行模块安装后重启设备。
- 确认硬件接线正确:ADIS16507-1 SPI引脚接树莓派SPI0对应引脚,CS引脚接GPIO8,传感器使用3.3V供电;在
/boot/config.txt中开启SPI功能,添加对应设备树overlay配置,指定设备compatible属性为adi,adis16507-1,SPI通信频率设置为1MHz及以下(传感器初始化阶段最高支持1MHz通信速率)。 - 重启后再次查看
/sys/bus/iio/devices/路径即可看到IIO设备节点,可通过读取节点下的name属性确认设备型号匹配。
若完成上述操作后仍无法识别设备,可先使用spidev_test工具验证SPI硬件链路通信是否正常,排除接线虚接、电平不匹配等硬件问题。
内容的提问来源于stack exchange,提问作者Dimi

