如何在 Linux 上模拟 I2C 设备?
How can I emulate an I2C device on Linux?
我有一个正在开发的自定义 SOM(基于 iMX6)板,它将 运行 Ubuntu,并且有几个 I2C 设备连接到一个 iMX6 I2C“适配器”。鉴于硬件尚不可用,我想编写软件来访问和控制上述 I2C 设备,最好是在我的 Ubuntu 笔记本电脑上模拟它们;我在想这样的设置可能对软件测试也很有用。
我一直在玩 i2cdetect 看看我的笔记本电脑上有什么,我发现了一些特别有趣的东西;考虑这些命令和响应:
$ sudo i2cdetect -l
i2c-3 i2c i915 gmbus dpd I2C adapter
i2c-1 i2c i915 gmbus dpc I2C adapter
i2c-6 i2c DPDDC-C I2C adapter
i2c-4 i2c DPDDC-A I2C adapter
i2c-2 i2c i915 gmbus dpb I2C adapter
i2c-0 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-5 i2c DPDDC-B I2C adapter
$ sudo i2cdetect -y -r 4
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70: 70 71 72 73 74 75 76 77
我的理解是,对于 table 中每个具有编号的单元格,总线上都存在一个以该编号作为其地址的设备;例如,第一个数字 0x03 表示有一个 I2C 地址为 0x03 的设备。 i2c-4 适配器似乎不太可能真的连接了 117 个设备! (FWIW 大多数其他适配器没有设备,只有两个在每条总线上显示少量设备;这些似乎是“真正的”I2C 总线。)但回到 i2c-4 - 是某种模拟(或模拟)适配器上有模拟设备吗?我决定看看我可以从其中一个可疑设备 i2cdump 数据,并发现了这样的东西:
$ sudo i2cdump -y 4 0x3 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 02 02 04 04 06 06 08 08 0a 0a 0c 0c 0e 0e ..??????????????
10: 10 10 12 12 14 14 16 16 18 18 1a 1a 1c 1c 1e 1e ????????????????
20: 20 20 22 22 24 24 26 26 28 28 2a 2a 2c 2c 2e 2e ""$$&&((**,,..
30: 30 30 32 32 34 34 36 36 38 38 3a 3a 3c 3c 3e 3e 0022446688::<<>>
40: 40 40 42 42 44 44 46 46 48 48 4a 4a 4c 4c 4e 4e @@BBDDFFHHJJLLNN
50: 50 50 52 52 54 54 56 56 58 58 5a 5a 5c 5c 5e 5e PPRRTTVVXXZZ\^^
60: 60 60 62 62 64 64 66 66 68 68 6a 6a 6c 6c 6e 6e ``bbddffhhjjllnn
70: 70 70 72 72 74 74 76 76 78 78 7a 7a 7c 7c 7e 7e pprrttvvxxzz||~~
80: 80 80 82 82 84 84 86 86 88 88 8a 8a 8c 8c 8e 8e ????????????????
90: 90 90 92 92 94 94 96 96 98 98 9a 9a 9c 9c 9e 9e ????????????????
a0: a0 a0 a2 a2 a4 a4 a6 a6 a8 a8 aa aa ac ac ae ae ????????????????
b0: b0 b0 b2 b2 b4 b4 b6 b6 b8 b8 ba ba bc bc be be ????????????????
c0: c0 c0 c2 c2 c4 c4 c6 c6 c8 c8 ca ca cc cc ce ce ????????????????
d0: d0 d0 d2 d2 d4 d4 d6 d6 d8 d8 da da dc dc de de ????????????????
e0: e0 e0 e2 e2 e4 e4 e6 e6 e8 e8 ea ea ec ec ee ee ????????????????
f0: f0 f0 f2 f2 f4 f4 f6 f6 f8 f8 fa fa fc fc fe fe ????????????????
这适用于设备地址 0x03 到 0x07;在此之上,十六进制数据被替换为 XX!无论如何,我猜这个 table 在“设备”上显示了 256 字节的数据。
我尝试 read/write/read 一个字节,但它不起作用:
$ sudo i2cget -y 4 0x3 0xff
0xfe
$ sudo i2cset -y 4 0x3 0xff 0x27
$ sudo i2cget -y 4 0x3 0xff
0xfe
以所有这些为背景,这是我的问题:
- i2c-4真的是一个模拟的I2C适配器吗,它的用途是什么?
- 我是否正确使用了 i2cget 和 i2cset,如果没有,我哪里出错了? (当然,这是假设 i2c-4 地址 0x3 按我的预期工作)
- 如果没有,有没有办法模拟 I2C 设备(可能还有适配器),以便我可以编写能够 read/write 的软件?
当然,问题3是这里的重点...
谢谢!
回答此问题以防其他人有 same/similar 问题。
秘诀就是用i2c-stub
,听说过,但没弄清楚是什么东西。这就是我要找的所有内容:
# Set up fake device
$ sudo modprobe i2c-dev
$ sudo modprobe i2c-stub chip_addr=0x03
$ i2cdetect -l
...
i2c-7 unknown SMBus stub driver N/A <<--- Here it is!
# Read data
$ sudo i2cdump -y -r 0-7 7 0x03 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 00 00 00 00 00 00 .?......
# Write data
$ sudo i2cset -y 7 0x03 0x01 0x27
# Read data again
$ sudo i2cdump -y -r 0-7 7 0x03 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 27 00 00 00 00 00 00 .?......
我有一个正在开发的自定义 SOM(基于 iMX6)板,它将 运行 Ubuntu,并且有几个 I2C 设备连接到一个 iMX6 I2C“适配器”。鉴于硬件尚不可用,我想编写软件来访问和控制上述 I2C 设备,最好是在我的 Ubuntu 笔记本电脑上模拟它们;我在想这样的设置可能对软件测试也很有用。
我一直在玩 i2cdetect 看看我的笔记本电脑上有什么,我发现了一些特别有趣的东西;考虑这些命令和响应:
$ sudo i2cdetect -l
i2c-3 i2c i915 gmbus dpd I2C adapter
i2c-1 i2c i915 gmbus dpc I2C adapter
i2c-6 i2c DPDDC-C I2C adapter
i2c-4 i2c DPDDC-A I2C adapter
i2c-2 i2c i915 gmbus dpb I2C adapter
i2c-0 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-5 i2c DPDDC-B I2C adapter
$ sudo i2cdetect -y -r 4
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70: 70 71 72 73 74 75 76 77
我的理解是,对于 table 中每个具有编号的单元格,总线上都存在一个以该编号作为其地址的设备;例如,第一个数字 0x03 表示有一个 I2C 地址为 0x03 的设备。 i2c-4 适配器似乎不太可能真的连接了 117 个设备! (FWIW 大多数其他适配器没有设备,只有两个在每条总线上显示少量设备;这些似乎是“真正的”I2C 总线。)但回到 i2c-4 - 是某种模拟(或模拟)适配器上有模拟设备吗?我决定看看我可以从其中一个可疑设备 i2cdump 数据,并发现了这样的东西:
$ sudo i2cdump -y 4 0x3 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 02 02 04 04 06 06 08 08 0a 0a 0c 0c 0e 0e ..??????????????
10: 10 10 12 12 14 14 16 16 18 18 1a 1a 1c 1c 1e 1e ????????????????
20: 20 20 22 22 24 24 26 26 28 28 2a 2a 2c 2c 2e 2e ""$$&&((**,,..
30: 30 30 32 32 34 34 36 36 38 38 3a 3a 3c 3c 3e 3e 0022446688::<<>>
40: 40 40 42 42 44 44 46 46 48 48 4a 4a 4c 4c 4e 4e @@BBDDFFHHJJLLNN
50: 50 50 52 52 54 54 56 56 58 58 5a 5a 5c 5c 5e 5e PPRRTTVVXXZZ\^^
60: 60 60 62 62 64 64 66 66 68 68 6a 6a 6c 6c 6e 6e ``bbddffhhjjllnn
70: 70 70 72 72 74 74 76 76 78 78 7a 7a 7c 7c 7e 7e pprrttvvxxzz||~~
80: 80 80 82 82 84 84 86 86 88 88 8a 8a 8c 8c 8e 8e ????????????????
90: 90 90 92 92 94 94 96 96 98 98 9a 9a 9c 9c 9e 9e ????????????????
a0: a0 a0 a2 a2 a4 a4 a6 a6 a8 a8 aa aa ac ac ae ae ????????????????
b0: b0 b0 b2 b2 b4 b4 b6 b6 b8 b8 ba ba bc bc be be ????????????????
c0: c0 c0 c2 c2 c4 c4 c6 c6 c8 c8 ca ca cc cc ce ce ????????????????
d0: d0 d0 d2 d2 d4 d4 d6 d6 d8 d8 da da dc dc de de ????????????????
e0: e0 e0 e2 e2 e4 e4 e6 e6 e8 e8 ea ea ec ec ee ee ????????????????
f0: f0 f0 f2 f2 f4 f4 f6 f6 f8 f8 fa fa fc fc fe fe ????????????????
这适用于设备地址 0x03 到 0x07;在此之上,十六进制数据被替换为 XX!无论如何,我猜这个 table 在“设备”上显示了 256 字节的数据。
我尝试 read/write/read 一个字节,但它不起作用:
$ sudo i2cget -y 4 0x3 0xff
0xfe
$ sudo i2cset -y 4 0x3 0xff 0x27
$ sudo i2cget -y 4 0x3 0xff
0xfe
以所有这些为背景,这是我的问题:
- i2c-4真的是一个模拟的I2C适配器吗,它的用途是什么?
- 我是否正确使用了 i2cget 和 i2cset,如果没有,我哪里出错了? (当然,这是假设 i2c-4 地址 0x3 按我的预期工作)
- 如果没有,有没有办法模拟 I2C 设备(可能还有适配器),以便我可以编写能够 read/write 的软件?
当然,问题3是这里的重点...
谢谢!
回答此问题以防其他人有 same/similar 问题。
秘诀就是用i2c-stub
,听说过,但没弄清楚是什么东西。这就是我要找的所有内容:
# Set up fake device
$ sudo modprobe i2c-dev
$ sudo modprobe i2c-stub chip_addr=0x03
$ i2cdetect -l
...
i2c-7 unknown SMBus stub driver N/A <<--- Here it is!
# Read data
$ sudo i2cdump -y -r 0-7 7 0x03 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 00 00 00 00 00 00 00 .?......
# Write data
$ sudo i2cset -y 7 0x03 0x01 0x27
# Read data again
$ sudo i2cdump -y -r 0-7 7 0x03 b
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 00 27 00 00 00 00 00 00 .?......