i2c eeprom driver

发布于 2022-09-23 13:50:50 字数 1274 浏览 26 评论 0

在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

你在看孤独的风景 2022-09-30 13:50:50

看看这个文档吧

十二 2022-09-30 13:50:50

Very useful. So thanks.

但是它只是详细介绍如何注册和注销device/driver。 并没有涉及到我上面的几个问题?

淡淡離愁欲言轉身 2022-09-30 13:50:50

问题1:你期望的是在什么情况下会调用eeprom_detect?程序的执行调度很大程度上取决于你编写的代码,而即使是内核的调度点,你也可以控制的;
问题2:不需要编译内核,编译模块再加载就ok了。这个是静态的信息,所以,怎么写在于你程序中赋予它什么样的功能和作用。

如痴如狂 2022-09-30 13:50:50

问题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设备,就需要重新编译更新一起内核,是这样的吗?

娜些时光,永不杰束 2022-09-30 13:50:50

第一个问题,你加一些调试打印信息,看一下执行流程中,为什么没有到达你需要调用的函数;
第二个问题,其实你完全没有必要重新编译内核,除非内核中有很多地方都引用到了你的这个静态结构信息,模块加载就足以实现了。

后面的问题:
在什么时候加入信息,关键在于你对这个程序的理解。它需要什么时候被调用?其他模块是否会引用到它?内核启动的时候是不是会配置它?这些搞明白了就知道了,如果只是一个独立的模块,没有其他的依赖关系,那加载点就可以随心所欲了。

小梨窩很甜 2022-09-30 13:50:50

Thanks a lot.

不打扰别人 2022-09-30 13:50:50

原帖由 studyboy_3w 于 2008-12-30 15:31 发表
在linux/drivers/i2c/chips 下有eeprom.c driver, 本人想试着锻炼i2c driver编写能力。但是遇到问题了。 望高手赐教。
我的步骤
1. 在arch/arm/mach-s3c2410/mach-smdk2410.c
static struct i2c_board_info ...

你设备的地址是0x50吗?
I2C核心会根据你提供的这个地址去呼叫你的设备,如果收到设备返回的ACK,这是才会调用eeprom_detect函数来向sys子系统注册接口。

尝试一下不同的地址,记得I2C核心吧设备地址做偏移。

看透却不说透 2022-09-30 13:50:50

对, 我加多一个地址,就会调用那个函数。如:
在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51,I2C_CLIENT_END };

为什么0x50不可以呢? 这个0x50地址是如何得来的?

成熟稳重的好男人 2022-09-30 13:50:50

原帖由 studyboy_3w 于 2009-1-6 08:37 发表
对, 我加多一个地址,就会调用那个函数。如:
在eeprom.c上修改
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51,I2C_CLIENT_END };

为什么0x50不可以呢? 这个0x50地址是如 ...

配合电路图,你看器件手册上是怎么说的,一般I2C设备根据外部一两个引脚的高低电平选择不同的地址,避免和总线上其它设备地址冲突。

怀疑你的地址是0X51,可以试试把0X50去掉,只要0x51来验证一下。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文