i2c eeprom driver
在linux/drivers/i2c/chips 下有eeprom.c driver, 本人想试着锻炼i2c driver编写能力。但是遇到问题了。 望高手赐教。
我的步骤
1. 在arch/arm/mach-s3c2410/mach-smdk2410.c
static struct i2c_board_info __initdata i2c_devices[] =
{
{
I2C_BOARD_INFO("rtc-s35390a", 0x30),
.platform_data = &s35390a,
},
{
I2C_BOARD_INFO("eeprom",0x50),
},
};
并且在smdk2410_init()函数后面调用
i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
添加i2c device信息
2. 在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
3. 在insmod eeprom.ko时
在eeprom.c 调用了
i2c_probe(adapter, &addr_data, eeprom_detect);
并且返回0,但是并没有运行 static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind), lsmod可知道模块已经加入。 为什么不会调用eeprom_detect函数?
问题1
为什么没有调用eeprom_detect函数?
问题2
每个i2cdevice都需要在arch/mach-s3c2410/下加入i2c_board_info信息结构吗?那样device变了一下都要重新编译内核的,挺麻烦的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
看看这个文档吧
Very useful. So thanks.
但是它只是详细介绍如何注册和注销device/driver。 并没有涉及到我上面的几个问题?
问题1:你期望的是在什么情况下会调用eeprom_detect?程序的执行调度很大程度上取决于你编写的代码,而即使是内核的调度点,你也可以控制的;
问题2:不需要编译内核,编译模块再加载就ok了。这个是静态的信息,所以,怎么写在于你程序中赋予它什么样的功能和作用。
问题1:你期望的是在什么情况下会调用eeprom_detect?程序的执行调度很大程度上取决于你编写的代码,而即使是内核的调度点,你也可以控制的;
模块一加载, 根据eeprom.c,它的流程应该是,
eeprom_init->i2c_add_driver->eeprom_attach_adapter->i2c_probe->eeprom_detect.
但是我这里不知道为什么不会调用eeprom_detect。
如果我加入多个地址,那么就会调用eeprom_detect。如:
static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
0x55, 0x56, 0x57, I2C_CLIENT_END };
问题2:不需要编译内核,编译模块再加载就ok了。这个是静态的信息,所以,怎么写在于你程序中赋予它什么样的功能和作用。
由于在arch/arm/mach-s3c2410/mach-smdk2410.c增加了代码(如下),那么应该要重新一次编译内核。
static struct i2c_board_info __initdata i2c_devices[] =
{
{
I2C_BOARD_INFO("rtc-s35390a", 0x30),
.platform_data = &s35390a,
},
{
I2C_BOARD_INFO("eeprom",0x50),
},
};
如果不需要重新编译内核,除非上面代码不用添加进去。如果这样,那么i2c_probe(adapter, &addr_data, eeprom_detect)又如何找到设备呢?我想版主意思是编译eeprom.ko不需要重新编译内核,是不?
还有另外一个问题:
要增加i2c 和spi设备,必须在系统启动前就加入设备信息吗?
如spi要在arch/mach-**/mach-**.c 加入spi_board_info 然后就调用spi_register_board_info
如i2c要在arch/mach-**/mach-**.c 加入i2c_board_info 然后就调用i2c_register_board_info
如果这样,那么增加一个i2c/spi设备,就需要重新编译更新一起内核,是这样的吗?
第一个问题,你加一些调试打印信息,看一下执行流程中,为什么没有到达你需要调用的函数;
第二个问题,其实你完全没有必要重新编译内核,除非内核中有很多地方都引用到了你的这个静态结构信息,模块加载就足以实现了。
后面的问题:
在什么时候加入信息,关键在于你对这个程序的理解。它需要什么时候被调用?其他模块是否会引用到它?内核启动的时候是不是会配置它?这些搞明白了就知道了,如果只是一个独立的模块,没有其他的依赖关系,那加载点就可以随心所欲了。
Thanks a lot.
你设备的地址是0x50吗?
I2C核心会根据你提供的这个地址去呼叫你的设备,如果收到设备返回的ACK,这是才会调用eeprom_detect函数来向sys子系统注册接口。
尝试一下不同的地址,记得I2C核心吧设备地址做偏移。
对, 我加多一个地址,就会调用那个函数。如:
在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51,I2C_CLIENT_END };
为什么0x50不可以呢? 这个0x50地址是如何得来的?
配合电路图,你看器件手册上是怎么说的,一般I2C设备根据外部一两个引脚的高低电平选择不同的地址,避免和总线上其它设备地址冲突。
怀疑你的地址是0X51,可以试试把0X50去掉,只要0x51来验证一下。