189 8069 5689

linuxi2c的命令 linux读i2c总线命令

linux下怎么直接使用iic接口

利用Linux中IIC设备子系统移植IIC设备驱动

创新互联专注于网站建设|网站维护|优化|托管以及网络推广,积累了大量的网站设计与制作经验,为许多企业提供了网站定制设计服务,案例作品覆盖成都会所设计等行业。能根据企业所处的行业与销售的产品,结合品牌形象的塑造,量身制作品质网站。

背景描述

IIC总线在嵌入式系统中应用十分广泛,常见的有eeprom,rtc。一般的处理器会包含IIC的控制器,用来完成IIC时序的控制;另外一方面,由于IIC的时序简单,使用GPIO口来模拟时序也是常见的做法。面对不同的IIC控制器,各种各样的芯片以及linux源码,如何更快做好IIC设备驱动。

问题描述

在我们的方案中,我们会用到eeprom,rtc以及tw2865。由于Hi3520的IIC控制器设计有问题,无法正常使用。而IIC控制器的SDA和SCL管脚正好是和两个GPIO管脚复用的。Hisi将控制gpio来实现IIC的时序,从而对IIC设备进行操作。这种设计方式简单明了,但使用IIC子系统,可以更方便的移植和维护其他的设备驱动。

问题分析

Hisi对于gpio口,rtc芯片以及tw2865的处理方式如下:将gpio口做成一个模块化的驱动,该驱动模拟IIC时序,并向外提供一些函数接口,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。对于具体的rtc芯片,将其注册为一个misc设备,并利用gpio模块导出的函数进行rtc芯片的配置操作。

其实对于linux-2.6.24\drivers\i2c目录下代码,我们可以加以利用。

Linux的IIC字结构分为三个组成部分:

IIC核心

IIC核心提供了IIC总线驱动和设备驱动的注册、注销方法,IICalgorithm上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码。

IIC总线驱动

IIC总线驱动是对IIC硬件体系结构中适配器端的实现。

IIC设备驱动

IIC设备驱动是对IIC硬件体系总设备端的实现。

我们查看下该目录下的makefile和kconfig:

obj-$(CONFIG_I2C_BOARDINFO) +=i2c-boardinfo.o

obj-$(CONFIG_I2C) += i2c-core.o

obj-$(CONFIG_I2C_CHARDEV) +=i2c-dev.o

obj-y +=busses/ chips/ algos/

i2c-core.c就是IIC核心,buses中的文件是主流处理器中IIC总线的总线驱动,而chips中的文件就是常用芯片的驱动,algos中的文件实现了一些总线适配器的algorithm,其中就包括我们要用到的i2c-algo-bit.c文件。

我们首先利用i2c-gpio.c和i2c-algo-bit.c做好总线驱动。

在i2c-gpio.c中,module_initi2c_gpio_initplatform_driver_probe(i2c_gpio_driver,i2c_gpio_probe);

将其注册为platform虚拟总线的驱动。

在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,

定义了如下三个结构体:

structi2c_gpio_platform_data *pdata;//平台相关的gpio的设置

structi2c_algo_bit_data *bit_data;//包含algorithm的具体函数,setor

get SDA和SCL

structi2c_adapter *adap;//适配器

i2c_gpio_probe主要做了下面几件事:

填充bit_data结构的各个函数指针,关联到具体的操作SDA和SCl函数。

填充adap结构,adap-algo_data= bit_data;

pdata= pdev-dev.platform_data;

bit_data-data= pdata;

pdev-dev-driver_data= adap;

在i2c-core中注册适配器类型。

inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)

在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中

adap-algo= i2c_bit_algo;

将i2c_bit_algo与adap关联上。

static const structi2c_algorithm i2c_bit_algo = {

.master_xfer = bit_xfer,

.functionality = bit_func,

};

其中,master_xfer函数指针就是IIC传输函数指针。

I2c-algo-bit.c还实现了IIC开始条件,结束条件的模拟,发送字节,接收字节以及应答位的处理。

i2c-gpio.c中的i2c_gpio_setsda_val等函数是与具体平台gpio相关的。

修改对应arch-hi3520v100目录下的gpio.h中的各个函数,这些函数是通过操作寄存器来控制gpio的方向和值。

在对应mach-hi3520v100中的platform-devices.c中添加如下:

static structi2c_gpio_platform_data pdata = {

.sda_pin = 10,

.sda_is_open_drain = 1,

.scl_pin = 11,

.scl_is_open_drain = 1,

.udelay = 4, /* ~100 kHz */

};

static struct platform_devicehisilicon_i2c_gpio_device = {

.name = "i2c-gpio",

.id = -1,

.dev.platform_data = pdata,

};

static struct platform_device*hisilicon_plat_devs[] __initdata = {

hisilicon_i2c_gpio_device,

};

int __inithisilicon_register_platform_devices(void)

{

platform_add_devices(hisilicon_plat_devs,ARRAY_SIZE (hisilicon_plat_devs));

return 0;

}

通过platform添加devices和driver,使得pdev-dev.platform_data=pdata

综合上面的过程,我们完成了adapter的注册,并将用gpio口模拟的algorithm与adapter完成了关联。

这样,在rtc-x1205.c中,x1205_attach函数利用i2c核心完成client和adap的关联。

在x1205_probe函数中填充i2c_client结构体,并调用i2c_attach_client通知iic核心。

接着注册rtc驱动。

最后我们要读取时间,就需要构造i2c_msg结构体,如下所示:

struct i2c_msg msgs[] = {

{ client-addr, 0, 2,dt_addr }, /* setup read ptr */

{ client-addr, I2C_M_RD,8, buf }, /* read date */

};

/* read date registers */

if((i2c_transfer(client-adapter, msgs[0], 2)) != 2) {

dev_err(client-dev,"%s: read error\n", __FUNCTION__);

return -EIO;

}

dt_addr是寄存器的地址,I2C_M_RD表示iicread。

用linux 调用内核中的统一I2C驱动 i2c总是 busy,求大神支招,谢谢! 程序很短

最近我也遇到这个问题了,纠结了一天,在网友的支持下解决了,这个天嵌的版本中,i2c和他的摄像头驱动(OV9650驱动)相冲突,你在编译内核之前,将摄像头的驱动全部去掉,这样子重新编译之后,i2c就可以正常测试使用了。

linux 4.11的i2c怎么写

假设手上有一块从淘宝上买来的开发板,我要在开发板的I2C总线上增加一个从设备(如at24c08),那么我要怎样写这个“I2C设备驱动”,让

应用程序可以访问at24c08呢?

先来看一个最简单的i2c设备驱动:

static struct i2c_board_info at24cxx_info = { //所支持的i2c设备的列表

I2C_BOARD_INFO("at24c08", 0x50), //一项代表一个支持的设备,它的名字叫做“at24c08”,器件地址是0x50

};

static struct i2c_client *at24cxx_client;

static int at24cxx_dev_init(void)

{

struct i2c_adapter *i2c_adap; //分配一个适配器的指针

i2c_adap = i2c_get_adapter(0); //调用core层的函数,获得一个i2c总线。这里我们已经知道新增的器件挂接在编号为0的i2c总线上

at24cxx_client = i2c_new_device(i2c_adap, at24cxx_info); // 把i2c适配器和新增的I2C器件关联起来,这个用了i2c总线0,地址是0x50。这就组成了一个客户端

at24cxx_client i2c_put_adapter(i2c_adap);

return 0;

}

static void at24cxx_dev_exit(void)

{

i2c_unregister_device(at24cxx_client);

}

module_init(at24cxx_dev_init);

module_exit(at24cxx_dev_exit);


网站名称:linuxi2c的命令 linux读i2c总线命令
网站网址:http://cdxtjz.cn/article/hppoip.html

其他资讯