免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2681 | 回复: 2
打印 上一主题 下一主题

[驱动] 掛driver的問題 (i2c device driver) [复制链接]

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-03-14 16:13 |只看该作者 |倒序浏览
本帖最后由 ymes9106 于 2015-03-14 16:29 编辑

大家好
現在在學習寫簡單的驅動並加入嵌入式系統 (linux kernal 3.3)
在開發版上接了一顆i2c device (OLED addr: 0x3c)

寫了一個i2c device driver掛上去,
但不知為何它就是無法跑到 probe 函式 (這樣子是不是代表掛載不成功?)
menuconfig也確認過, 有載入模組

從user space使用 i2c-tools查看  
該裝置是有連線的, 也可以寫值到暫存器, 所以硬體方面的問題先排除

以下是此 device的driver code
第一步註冊board_info
第二步註冊device driver
小弟第一次寫driver, 實在不知道問題點出在哪, 能麻煩指導一下嗎..謝謝
//-----------------------------------------------------
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>

int i2c_oled_test1= 0;
int i2c_oled_test2= 0;
static struct i2c_board_info ssd1306_info[] = {
{
    .type = "ssd1306_i2c",
    .addr = 0x3c,                             // oled addr
},
};

static const struct i2c_device_id ssd1306_i2c_id[] = {
        {"ssd1306_i2c", 0},
};

static int ssd1306_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    i2c_oled_test2 = 1;                     // 從其他地方呼叫此全域變數, 用來確認是否真的有跑進來此函式
    return 0;
}

static int __devexit ssd1306_i2c_remove(struct i2c_client *client)
{
    return 0;
}

static struct i2c_driver ssd1306_i2c_driver = {
    .driver = {
        .name = "ssd1306_i2c_driver",
        .owner = THIS_MODULE,
    },
    .probe = ssd1306_i2c_probe,
    .remove = __devexit_p(ssd1306_i2c_remove),
    .id_table = ssd1306_i2c_id,
};

static int __init i2c_oled_init(void)
{
    i2c_oled_test1 = 1;                                                                                      // 從其他地方呼叫此全域變數, 用來確認是否真的有跑進來此函式
    i2c_register_board_info(1, ssd1306_info, ARRAY_SIZE(ssd1306_info));            // 註冊board info, 使用bus num=1的 i2c總線
    return i2c_add_driver(&ssd1306_i2c_driver);                                                  // 註冊driver
}

static void __exit i2c_oled_exit(void)
{
    i2c_del_driver(&ssd1306_i2c_driver);
}

module_init(i2c_oled_init);
module_exit(i2c_oled_exit);

MODULE_DESCRIPTION("OLED(ssd1306) i2c device driver");
MODULE_AUTHOR("Bruce");
MODULE_LICENSE("GPL");
//-----------------------------------------------

最後的結果為:
i2c_oled_test1 = 1,   i2c_oled_test2 = 0

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
2 [报告]
发表于 2015-03-16 09:20 |只看该作者
痾...樓上有什麼想法嗎???
我還是沒解決這個問題...

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
3 [报告]
发表于 2015-03-16 11:49 |只看该作者
後來找到解決方法了...提供一下, 讓以後的人遇到類似的也能解決
在module_init函式中 只註冊board_info似乎不夠, kernal還是抓不到這個device
如果你確切知道你的device addr以及它是掛在哪一個bus上
可以使用 i2c_new_device() 方式告知kernal
如此一來就能正常probe了

init函式如下, 有需要的人可以參考
static int __init i2c_driver_ssd1306_init(void)
{
    struct i2c_client *client;
    struct i2c_adapter *adapter;
    int ret, i2c_bus_number = 1;

    ret = i2c_register_board_info(i2c_bus_number, i2c_ssd1306_info, ARRAY_SIZE(i2c_ssd1306_info));
    if (ret)    return -EINVAL;
   
    adapter = i2c_get_adapter(i2c_bus_number);
    if (!adapter)    return -EINVAL;
      
    client = i2c_new_device(adapter, &i2c_ssd1306_info[0]);
    if (!client)    return -EINVAL;

    return i2c_add_driver(&i2c_driver_ssd1306);
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP