参考链接:
https://blog.youkuaiyun.com/jklinux/article/details/78688711
https://blog.youkuaiyun.com/fengsheng301/article/details/20858931?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-4&spm=1001.2101.3001.4242
https://www.cnblogs.com/lian-meng/p/10818192.html
module
模块信息: AT24C08
接口: I2C
容量:8K bit(1K byte)
芯片特性
The AT24C01A/02/04/08A/16A provides 1024/2048/4096/8192/16384 bits of serial
electrically erasable and programmable read-only memory (EEPROM) organized
as 128/256/512/1024/2048 words of 8 bits each.
Memory Organization
AT24C08A, 8K SERIAL EEPROM: Internally organized with 64 pages of 16 bytes each,
the 8K requires a 10-bit data word address for random word addressing.
设备地址(0x5x)
The 1K, 2K, 4K, 8K and 16K EEPROM devices all require an 8-bit device address
word following a start condition to enable the chip for a read or write operation
(refer to Figure 7).
The next 3 bits are the A2, A1 and A0 device address bits for the 1K/2K EEPROM.
These 3 bits must compare to their corresponding hard-wired input pins.
The 8K EEPROM only uses the A2 device address bit with the next 2 bits being
for memory page addressing. The A2 bit must compare to its corresponding
hard-wired input pin. The A1 and A0 pins are no connect.
The eighth bit of the device address is the read/write operation select bit. A read
operation is initiated if this bit is high and a write operation is initiated if this bit is low.
Upon a compare of the device address, the EEPROM will output a zero. If a compare
is not made, the chip will return to a standby state.
Pin Configuration
软件配置
CONFIG_EEPROM_AT24
&i2c0 {
status = "okay";
clock-frequency = <400000>;
eeprom@50 {
compatible = "at,24c08";
reg = <0x50>;
};
};
kernel/drivers/misc/eeprom/at24.c
static const struct i2c_device_id at24_ids[] = {
/* needs 8 addresses as A0-A2 are ignored */
{ "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
/* old variants can't be handled with this generic entry! */
{ "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
{ "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
/* spd is a 24c02 in memory DIMMs */
{ "spd", AT24_DEVICE_MAGIC(2048 / 8,
AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
{ "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
/* 24rf08 quirk is handled at i2c-core */
{ "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
{ "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
{ "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
{ "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
{ "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
{ "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
{ "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
{ "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },
{ "at24", 0 },
{ /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(i2c, at24_ids);
static struct i2c_driver at24_driver = {
.driver = {
.name = "at24",
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
},
.probe = at24_probe,
.remove = at24_remove,
.id_table = at24_ids,
};
模块读写
[root@rk3399:/]# find / -name "at24"
/sys/bus/i2c/drivers/at24
[root@rk3399:/]# echo "hello my world" > /sys/bus/i2c/devices/1-0050/eeprom
[root@rk3399:/]# cat /sys/bus/i2c/devices/1-0050/eeprom
hello my world
测试读写
测试读写所有存储单元:
编写测试文件test
[root@rk3399:/]# vi test
0000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
1000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
2000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
3000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
4000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
5000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
6000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
7000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
8000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
9000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
0000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
[root@rk3399:/]# ls -alh test
-rw-r--r-- 1 root root 1.1K Jan 1 00:12 test
将test文件中的内容写到eeprom中
[root@rk3399:/]# cat test > /sys/bus/i2c/devices/1-0050/eeprom
cat: write error: File too large
读取eeprom中的内容
[root@rk3399:/]# cat /sys/bus/i2c/devices/1-0050/eeprom
0000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
1000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
2000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
3000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
4000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
5000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
6000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
7000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
8000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
9000000000111111111100000000001111111111000000000011111111110000000000111111111100000000001111111111
00000000001111
一个0或者1占用的空间是一个字节,一共读到的0和1的个数是1014个,每一行的回车符号应该也是占用一个字节,一共10个,所以加起来刚好1024个字节。
再次测试,删掉回车以后,可以读到的刚好是1024个0和1。
读写方法
清空eeprom:
dd if=/dev/zero of=/sys/devices/platform/ff110000.i2c/i2c-1/1-0050/eeprom bs=1024 count=1
写入eeprom:
dd if=./test of=/sys/devices/platform/ff110000.i2c/i2c-1/1-0050/eeprom
cat test > /sys/bus/i2c/devices/1-0050/eeprom
读取eeprom:
i2cdump -y -f 1 0x50
hexdump -Cv /sys/devices/platform/ff110000.i2c/i2c-1/1-0050/eeprom
cat /sys/bus/i2c/devices/1-0050/eeprom