I2C Loopback Slave

1.启用内核的 I2C Slave 功能和 EEPROM 模拟驱动,我是直接修改 .config

1
2
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y

(我的i2c-0为主机,i2c-1为从机)

2.手动添加从机模拟设备节点

#####(刚开始检测不到设备就是这里出了问题)#####

1
echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-1/new_device

这会把 EEPROM 从机挂在 I2C-1上,地址是 0x50(常见 EEPROM 地址)。

但是这里依然会把这个地址为 0x50 的 EEPROM 模拟器挂载上,可以看:出现了1-0050

1
2
root@ATK-IMX6U:~# ls /sys/bus/i2c/devices/i2c-1
1-001a 1-003c 1-0050 delete_device i2c-dev name new_device of_node power subsystem uevent

按道理说现在就应该进行读写了,但是我执行 i2cdetect -y 1 并没有看到检测到一个模拟设备

1
2
3
4
5
6
7
8
9
10
root@ATK-IMX6U:~# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

那么说明问题出在 i2c-slave-eeprom.c 这个文件的 probe 函数里,添加打印信息后也没有从dmesg里看到,可见i2c_slave_eeprom_probe函数压根没有运行,进入文件找到如下

1
2
3
4
5
6
7
8
9
10
11
static const struct i2c_device_id i2c_slave_eeprom_id[] = { 
{ "slave-24c02", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, 0) },
{ "slave-24c02ro", I2C_SLAVE_DEVICE_MAGIC(2048 / 8, I2C_SLAVE_FLAG_RO) },
{ "slave-24c32", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ "slave-24c32ro", I2C_SLAVE_DEVICE_MAGIC(32768 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
{ "slave-24c64", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ "slave-24c64ro", I2C_SLAVE_DEVICE_MAGIC(65536 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
{ "slave-24c512", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16) },
{ "slave-24c512ro", I2C_SLAVE_DEVICE_MAGIC(524288 / 8, I2C_SLAVE_FLAG_ADDR16 | I2C_SLAVE_FLAG_RO) },
{ }
};

看到ID表里哪有eeprom?当然不会匹配,所以将挂载命令换成:(将eeprom换成slave-24c02)

1
echo slave-24c02 0x50 > /sys/bus/i2c/devices/i2c-1/new_device

执行完成之后,i2c_slave_eeprom_probe运行。

3.查看设备是否正常

利用跳线连接后,可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@ATK-IMX6U:~# i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
root@ATK-IMX6U:~# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

UU:表示该地址已经被一个内核驱动占用(在这个 case 中就是 i2c-slave-eeprom 驱动)。
50:上也有一个从设备 0x50,但它没有被内核占用(没有被注册为驱动)。

4.测试写入字节

1
2
3
4
5
6
7
root@ATK-IMX6U:~# i2cset -y 0 0x50 0x00 0x01 0x02  0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 i
最后i是参数:
c (byte, no value)
b (byte data, default)
w (word data)
i (I2C block data)
s (SMBus block data)

然后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@ATK-IMX6U:~# i2cdump -y 0 0x50
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 01 02 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 ff ???????????????.
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
40: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
60: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................

写入成功。


I2C Loopback Slave
http://example.com/2025/05/12/I2C Loopback Slave/
作者
Encrow
发布于
2025年5月12日
许可协议