需要移植AT24C512的驱动,做了一下几种实验:
1.利用内核自带的驱动,内核driver/misc下面的at.c就包含了ATMEL系列的EEPROM的驱动,只需要在BROAD_INFO改下名字。然后要选中menuconfig下的misc下的eeprom选项,最后重新烧录后,就能在板子/sys/bus/i2c/device/0-0050/下看到eeprom节点,对他进行读写就可以了。但是这不是我想要的
2.移植了i2c-tools-3.1.0.tar.bz2,原以为这个能很方便的操作I2C器件,结果令我大失所望,i2cset一个值,i2cget出来的却不对,不知是何缘故,故放弃了。
3.看来还是要写驱动了,我将板子上的AT24C512换成了AT24C02,取消第一项中打开的项目,重新烧录内核。 在i2c_prob函数中添加了测试代码,即写一个寄存器,然后读它的值,insmod at24c02.ko后发现能正确读写了。
4.将AT24C02换成AT24C512,修改刚刚OK的驱动为AT24C512,修改内核BROAD_INFO,烧录,再insmod at24c512.KO 却不能正确读写了。原来关键是AT24C02的内部地址是1字节的,而AT24C512的内部地址是2字节的,就是在发送地址这块出问题了,所以不能正确读取数据。
下面是读写AT24C02的正确方法:
static int i2c_read_bytes(struct i2c_client *client, unsigned char *buf, int len)
{
struct i2c_msg msgs[2];
int ret=-1;
//发送写地址
msgs[0].flags=!I2C_M_RD;//写消息
msgs[0].addr=client->addr;
msgs[0].len=1;
msgs[0].buf=&buf[0];
//接收数据
msgs[1].flags=I2C_M_RD;//读消息
msgs[1].addr=client->addr;
msgs[1].len=len-1;
msgs[1].buf=&buf[1];
ret=i2c_transfer(client->adapter,msgs, 2);
return ret;
}
static int i2c_write_bytes(struct i2c_client *client,unsigned char *data,int len)
{
struct i2c_msg msg;
int ret=-1;
msg.flags=!I2C_M_RD;
msg.addr=client->addr;
msg.len=len;
msg.buf=data;
ret=i2c_transfer(client->adapter,&msg, 1);
return ret;
}
至于如何解决AT24C512的读写问题,进行中..............