在Linux内核模块中操作I2C设备

转载 2013年12月04日 14:07:22


近期公司项目较为空闲,抽空做了一些学习性质的研发内容,其中涉及到在Linux内核模块中使用I2C对外部器件进行控制的操作。虽然在Linux中操作使用I2C设备并不复杂,但本人接触Linux内核驱动开发时间并不算长,此次学习中也算较为系统的了解了Linux中对I2C设备的操控方式,谨在此做下记录。

通过Linux内核文档中关于操作I2C设备的文章后不难看出Linux中注册使用I2C设备一般通过四种方法1

  1. 通过总线号声明设备
  2. 立即探测设备
  3. 通过Probe探测相应设备
  4. 在用户空间立即探测

简单来说,第一种方式一般应用在嵌入式设备中。因为对于嵌入式设备来说,外围器件基本都是固定的,只需提供有限几款器件的支持即可。使用这种方式的时候,需要在板级配置文件中定义并设置 i2c_board_info 这个结构体的内容。其中需要配置设备名称和设备地址,此外设备中断和私有数据结构也可以选择设置。然后使用 i2c_register_board_info 这个接口对设置的设备进行注册使用。需要注意的是这种方法注册的设备是在注册I2C总线驱动时进行驱动适配的。

第二种方法可以通过给定的I2C适配器以及相应的I2C板级结构体,自行通过 i2c_new_device 接口进行添加注册所需的设备。这种方法灵活性要较第一种方法大,可以很方便的在模块中使用。

第三种方法是 2.6 内核之前的做法,使用 detect 方法去探测总线上的设备驱动。因为探测机制的原因,会导致一些副作用的发生,所以不建议使用,除非真的没有别的办法。

第四种方法是在Linux的控制台上,在用户空间通过sysfs,使用 /sys/bus/i2c/devices/i2c-3/new_device 节点进行设备的添加注册。

从上面可以看出,如果需要在Linux内核中以模块的方式对I2C设备进行驱动控制的话,第二种方法是比较推荐的。通过测试,在module的init中使用

1
2
3
4
5
struct i2c_adapter *i2c_adap;
struct i2c_client *i2c_client;
i2c_adap = i2c_get_adapter(1);
i2c_client = i2c_new_device(i2c_adap, &i2c_device);
i2c_put_adapter(i2c_adap);
即可成功注册I2C设备。其中:
1
2
3
static struct i2c_board_info ft5306_i2c_device = {
    I2C_BOARD_INFO("test_i2c", 0x11),
};
以上,对于如何在模块中注册使用I2C设备简单做了描述。那么如何在另外的模块中对已经注册的I2C设备进行反注册呢?由于内核中操作I2C设备都是通过 i2c_client 结构进行,所以问题可以抽象为如何在内核中获取指定设备的 i2c_client 结构指针。通过查阅内核API,也找到了一个方法可以达到这样的目的,如下:
1
2
3
4
5
6
7
8
struct i2c_client *i2c_client;
struct device *i2c_dev;

i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, "1-0011");
if(i2c_dev)
    i2c_client  =  container_of(i2c_dev, struct i2c_client, dev);
if(i2c_client)
    i2c_unregister_device(i2c_client);
该反注册例子的内容就是对前面注册的 0x11 地址的设备进行反注册。注意bus_find_device_by_name 函数中第三项参数,该参数是需要查找的设备在总线上注册的名称。”1”代表着1号适配器,”0011”是16位的I2C地址。如此便可方便的在内核模块中对I2C设备进行挂载和解挂了。

Footnotes:

1 参考Linux内核目录下的Documentation/i2c/instantiating-devices

相关文章推荐

在内核里写i2c client 驱动的两种方式

前文介绍了利用/dev/i2c-0在应用层完成对i2c设备的操作,但很多时候我们还是习惯为i2c设备在内核层编写驱动程序。目前内核支持两种编写i2c驱动程序的方式。下面分别介绍这两种方式的实现。这里分...

Linux I2C设备驱动编写(一)

在Linux驱动中I2C系统中主要包含以下几个成员: I2C adapter 即I2C适配器 I2C driver 某个I2C设备的设备驱动,可以以driver理解。 I2C client 某个I2...
  • airk000
  • airk000
  • 2014年03月16日 23:24
  • 31242

实例解析linux内核I2C体系结构

一、概述 谈到在linux系统下编写I2C驱动,目前主要有两种方式,一种是把I2C设备当作一个普通的字符设备来处理,另一种是利用linux I2C驱动体系结构来完成。下面比较下这两种驱动。 ...

(最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)

(最新内核3.4)Linux 设备树加载I2C client adapter 的流程(内核3.4 高通)

温湿度传感器si7020-a20 linux驱动编写

温湿度传感器在工业当中运用的比较广泛,通常用于检测设备所处环境的温度和湿度,温度过高,设备就有可能自动关机来保证设备不被烧坏。    我所采用的温湿度传感器是si7020-a20的芯片,I2C接口,地...

Linux平台RTL8188CUS驱动移植及测试

Linux平台RTL8188CUS驱动移植及测试 一 内核配置以及驱动编译: 1.配置内核wireless选项 进入内核目录,make menuconfig , [*] Networ...

将设备驱动程序模块源码添加到Linux内核模块源码中

1、将设备驱动程序模块globalmem添加到内核源码中,存放路径是kernel/drivers/mydriver/globalmem; 2、globalmem模块包含源码文件:globalmem....

编写你的第一个Linux内核模块(目前校对到杂项设备)

想要开始黑掉核?没有线索不知道如何开始?让我们向你展示如何做…   内核编程通常被视为黑魔法。在Arthur C Clarke的意义上说,它可能是。Linux内核与用户空间有很大的不同:抛开漫不经心的...

57 linux内核的i2c设备驱动模型

为了实现设备驱动的可移植性及可重用性,在linux内核的驱动模型里, device_driver设备驱动只需实现驱动方法和使用device设备提供的硬件资源(如用到的io口,中断号等). bus总线用...
  • jklinux
  • jklinux
  • 2017年07月01日 23:19
  • 540
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在Linux内核模块中操作I2C设备
举报原因:
原因补充:

(最多只允许输入30个字)