本文主要记录如何在 Rockchip RK3506 上接入并驱动 ADIS16505 IMU 模块。
Linux 有 IIO 子系统(工业输入输出),用于接入一些工业传感器,其中就包括 IMU。Analog ADIS16505 是一款使用较多的 MEMS IMU 模组,其驱动早已进入内核。
下面直接介绍相关适配工作,适配的 SOC 是 Rockchip RK3506,内核6.1,使用的模块是 ADIS16505-2。
参考资料:
1. 驱动适配
内核 CONFIG 修改:
1
2
3
|
+CONFIG_ADIS16475=m
+CONFIG_IIO_ADIS_LIB_BUFFER=y
+CONFIG_IIO_ADIS_LIB=y
|
然后编译出来 adis_lib.ko 和 adis16475.ko 拷贝到开发板,添加到 /lib/modules/$(uname -r)/kernel/drivers/iio/imu 下。
DTS 修改,在对应 spi 节点下添加 imu@0 节点(ADIS16505 最大只支持 2M 时钟,所以一般无法和其他外设共享 SPI 总线,建议单独一个 SPI 与之连接):
1
2
3
4
5
6
7
8
9
10
11
|
+ imu@0 {
+ compatible = "adi,adis16505-2";
+ reset-gpios = <&gpio1 RK_PC7 GPIO_ACTIVE_LOW>;
+ reg = <0>;
+ spi-cpha;
+ spi-cpol;
+ spi-max-frequency = <2000000>;
+ interrupts = <RK_PB5 IRQ_TYPE_EDGE_RISING>;
+ interrupt-parent = <&gpio0>;
+ status = "okay";
+ };
|
pinctrl 配置复位和终端引脚:
1
2
3
4
5
6
7
8
9
|
+ &pinctrl {
+ adis16505 {
+ imu_pins: imu-pins {
+ rockchip,pins =
+ <1 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+}
|
编译,烧写 boot 镜像。
启动后,会自动加载 adis 内核模块驱动,检查 lsmod | grep adis 会输出。
2. 读取验证
数据检查,安装 apt install libiio-utils ,然后用 sudo iio_info 检查,一般输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
sudo iio_info
Library version: 0.23 (git tag: v0.23)
Compiled with backends: local xml ip usb
IIO context created with local backend.
Backend version: 0.23 (git tag: v0.23)
Backend description string: Linux rk3506-iot 6.1.99 #18 SMP PREEMPT Sun Sep 28 16:51:31 CST 2025 armv7l
IIO context has 2 attributes:
local,kernel: 6.1.99
uri: local:
IIO context has 2 devices:
iio:device0: adis16505-2 (buffer capable)
8 channels found:
anglvel_x: (input, index: 0, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: 822982
attr 2: scale value: 0.000000006
anglvel_y: (input, index: 1, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: 632205
attr 2: scale value: 0.000000006
anglvel_z: (input, index: 2, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: -574057
attr 2: scale value: 0.000000006
accel_x: (input, index: 3, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: -182676799
attr 2: scale value: 0.000000037
accel_y: (input, index: 4, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: 73639656
attr 2: scale value: 0.000000037
accel_z: (input, index: 5, format: be:S32/32>>0)
3 channel-specific attributes found:
attr 0: calibbias value: 0
attr 1: raw value: -172736170
attr 2: scale value: 0.000000037
temp0: (input, index: 6, format: be:S16/16>>0)
2 channel-specific attributes found:
attr 0: raw value: 307
attr 1: scale value: 100
timestamp: (input, index: 7, format: le:S64/64>>0)
4 device-specific attributes found:
attr 0: current_timestamp_clock value: monotonic
attr 1: filter_low_pass_3db_frequency value: 720
attr 2: sampling_frequency value: 400.000000
attr 3: waiting_for_supplier value: 0
3 buffer-specific attributes found:
attr 0: data_available value: 0
attr 1: direction value: in
attr 2: watermark value: 1
6 debug attributes found:
debug attr 0: firmware_date value: 08-19-2021
debug attr 1: firmware_revision value: 1.7
debug attr 2: flash_count value: 55
debug attr 3: product_id value: 16505
debug attr 4: serial_number value: 0x2aa7
debug attr 5: direct_reg_access value: 0x0
Current trigger: trigger0(adis16505-2-dev0)
trigger0: adis16505-2-dev0
0 channels found:
No trigger on this device
|
如果有 error 或问题,则需要检查 DTS 引脚与实际的接线,接线有问题会导致出现问题。
这里需要注意 anglvel 和 accel 的 scale 字段,会跟手册的对不上,这个稍后解释。
读取实际数据,可以交叉编译内核 tools/iio/iio_generic_buffer 程序,使用 sudo iio_generic_buffer -n adis16505-2 -a -c -1 来连续可读所有数据,包括 时间戳:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
sudo iio_generic_buffer -n adis16505-2 -a -c -1
iio device number being used is 0
iio trigger number being used is 0
Enabling all channels
Enabling: in_accel_y_en
Enabling: in_temp0_en
Enabling: in_anglvel_z_en
Enabling: in_accel_x_en
Enabling: in_timestamp_en
Enabling: in_anglvel_y_en
Enabling: in_accel_z_en
Enabling: in_anglvel_x_en
/sys/bus/iio/devices/iio:device0 adis16505-2-dev0
0.003762 0.003326 -0.000192 -6.759874 2.724417 -6.391016 30600.000000 1759115389553132535
0.001698 0.002608 -0.001356 -6.764592 2.726806 -6.392885 30600.000000 1759115389555627474
0.000364 0.004624 -0.000209 -6.756444 2.718365 -6.381812 30600.000000 1759115389558121829
-0.000038 0.003894 -0.000131 -6.760957 2.724637 -6.373475 30600.000000 1759115389560619101
-0.000031 0.004665 -0.001059 -6.754562 2.714244 -6.378930 30800.000000 1759115389563114623
0.001390 0.003611 -0.001513 -6.760931 2.723385 -6.377503 31000.000000 1759115389565610144
0.002020 0.003198 -0.000661 -6.759657 2.719233 -6.383900 31000.000000 1759115389568120833
0.002179 0.002808 -0.004133 -6.762529 2.723939 -6.387537 31000.000000 1759115389570598855
0.001080 0.004518 -0.003293 -6.761709 2.727158 -6.387032 30700.000000 1759115389573096710
0.000033 0.002241 -0.002442 -6.756791 2.720568 -6.381608 30700.000000 1759115389575591065
0.000519 0.003776 -0.003139 -6.759673 2.720824 -6.381290 30700.000000 1759115389578086587
0.000121 0.003285 -0.004375 -6.761266 2.715935 -6.379437 30600.000000 1759115389580582108
-0.000275 0.003437 -0.003296 -6.761114 2.716521 -6.379723 30600.000000 1759115389583077047
0.002979 0.004323 -0.002205 -6.760320 2.717569 -6.381045 30600.000000 1759115389585569360
0.003052 0.003355 -0.003360 -6.764820 2.720145 -6.388940 30500.000000 1759115389588067799
0.001705 0.003426 -0.002130 -6.761583 2.715266 -6.392511 30500.000000 1759115389590562446
0.002971 0.003035 -0.003745 -6.760653 2.715627 -6.385410 30500.000000 1759115389593058259
0.001787 0.003784 -0.002825 -6.763578 2.716290 -6.383574 30600.000000 1759115389595552614
0.000679 0.003716 -0.004219 -6.761706 2.714494 -6.381908 30600.000000 1759115389598048428
0.001852 0.001673 -0.002511 -6.764761 2.713016 -6.385989 30600.000000 1759115389600543949
0.001230 0.003286 -0.003984 -6.759422 2.706651 -6.386874 30600.000000 1759115389603039471
0.001944 0.003745 -0.001667 -6.764474 2.714547 -6.382912 30500.000000 1759115389605535285
|
驱动默认使用 realtime,可以通过修改 /sys/bus/iio/devices/iio:deviceX/current_timestamp_clock 来修改时间戳,可选 monotonic 使用 MONO 时间,来避免系统时间调整导致的跳跃。
3. 注意事项
由于内核中不支持浮点数,所以内核驱动在 sysfs 中展示的浮点字段,都存在精度损失(内核打印浮点只保留1e-9的精度,无法满足这款IMU的比例系数),也就意味着,不能直接使用驱动提供的 sysfs 中的 scale 字段来求解物理值,而是直接使用芯片手册中的比例换算,在用户空间解算物理值,否则会有严重的精度丢失。针对 IIO 驱动,只使用 buffer 提供的原始值,和手册的比例系数进行换算,是最为稳妥的方式。
同时驱动在 /sys/kernel/debug/iio/iio\:deviceX/ 目录下提供一些额外信息:
1
2
|
ls /sys/kernel/debug/iio/iio\:device1/
direct_reg_access firmware_date firmware_revision flash_count product_id serial_number
|
这些字段可以通过参考资料2了解具体含义,比较有用的是 direct_reg_access 这个文件,可以通过它来实现直接的底层寄存器读写:
1
2
3
4
5
6
7
8
9
|
# 读取 0x60
echo 0x60 > direct_reg_access
cat 0x60
=> 0x2c1
# 写入 0x60
echo 0x60 0x2c1 > direct_reg_access
cat 0x60
=> 0x2c1
|
另外如频率设置、滤波设置等,可以参考参考治疗,直接修改 sysfs 下文件即可。