AT24Cxx(EEPROM)子系统

  • Post author:
  • Post category:其他



1.配置内核

打开I2C功能:



打开杂项设备,该选项打开后,EEPROM也就打开了。


2. 修改代码

修改文件: linux/arch/arm/mach-s3c2440/mach-smdk2440.c

增加如下代码片段:


  1. #include <linux/i2c/at24.h>

  2. static

    struct at24_platform_data at24c02 = {

  3. .byte_len   = SZ_2K / 8,
  4. .page_size  = 8,
  5. .flags      = 0,
  6. };

  7. static

    struct i2c_board_info __initdata smdk_i2c_devices[] = {


  8. /* more devices can be added using expansion connectors */
  9. {
  10. I2C_BOARD_INFO(

    “24c02”, 0x50),
  11. .platform_data = &at24c02,
  12. },
  13. };

在smdk2440_machine_init函数中增加如下:

  1. i2c_register_board_info(0, smdk_i2c_devices, ARRAY_SIZE(smdk_i2c_devices));


注意:上面许多参数是根据at24c02的参数来设置的,at24c02使用8位地址,内存大小2K比特位,也就是256K字节,页大小为8字节。

最后,需要注意,手册中at24c02的设备地址是0b 1 0 1 0 0 0 0 R/W, 其最低位是读写标志位,

但是在Linux中,I2C设备地址的最高位为0,而低七位地址就是手册中去掉R/W的剩余7位。因此,地址为0b 01010000(0x50)


3. 测试代码

系统启动后,如果一切正常。会在/sys文件系统下展示出该设备,如下:

[root@yj4230-0050]#pwd

/sys/devices/platform/s3c2440-i2c/i2c-0/0-0050

[root@yj4230-0050]#ls

bus        eeprom     name      subsystem

driver     modalias  power      uevent

[root@yj4230-0050]#cat name

24c02

其中eeprom即为驱动导出的bin属性,通过读写eeprom即可访问设备,如下:

[root@yj4230-0050]#cat eeprom

i2ci2c-0: master_xfer[0] W, addr=0x50, len=1

i2ci2c-0: master_xfer[1] R, addr=0x50, len=128

i2ci2c-0: master_xfer[0] W, addr=0x50, len=1

i2ci2c-0: master_xfer[1] R, addr=0x50, len=128

接着,编写代码进行测试,如下:


  1. #include <stdio.h>

  2. #include <string.h>

  3. #include <unistd.h>

  4. #include <sys/ioctl.h>

  5. #include <stdlib.h>

  6. #include <fcntl.h>

  7. #include <sys/io.h>

  8. int main(

    int argc,

    char **argv)


  9. {

  10. int ret, fd, i, j;

  11. char read_data[256];

  12. char write_data[256];

  13. char offset;
  14. fd = open(

    “/sys/devices/platform/s3c2440-i2c/i2c-0/0-0050/eeprom”, O_RDWR);

  15. if(fd < 0){
  16. printf(

    “Open at24c02 fail\n”);

  17. return -1;
  18. }
  19. ret = read(fd, &offset, 1);

  20. if(ret < 0){
  21. printf(

    “Read error\n”);

  22. return -1;
  23. }

    else

    if(ret < 1){

  24. perror(

    “Incomplete read\n”);
  25. printf(

    “%d\n”, ret);

  26. return -1;
  27. }

  28. for(i = 0; i < 256; i++)
  29. write_data[i] = offset+ 1 + i;
  30. lseek(fd, 0 , SEEK_SET);

    //It’s a must, or something wierd will happen
  31. ret = write(fd, write_data, 256);

  32. if(ret < 0){
  33. printf(

    “Write error\n”);

  34. return -1;
  35. }
  36. lseek(fd, 0 , SEEK_SET);

    //It’s a must, or something wierd will happen
  37. ret = read(fd, read_data, 256);

  38. if(ret < 0){
  39. printf(

    “Read error\n”);

  40. return -1;
  41. }

    else

    if(ret < 256){

  42. perror(

    “Incomplete read\n”);
  43. printf(

    “%d\n”, ret);

  44. return -1;
  45. }

  46. for(i = 0; i < 256; i++){

  47. if(i %16 == 0)
  48. printf(

    “\n”);
  49. printf(

    ” %03d “, read_data[i]);
  50. }
  51. printf(

    “\n”);
  52. }

代码结果如下: