导航:首页 > 操作系统 > linuxi2c测试

linuxi2c测试

发布时间:2022-09-27 00:07:47

⑴ 用linux 调用内核中的统一I2C驱动 i2c总是 busy,求大神支招

希望能帮到你。
没这样用过,以前都是直接对/sys/bus/i2c/devices/0-0050/eeprom操作。
代码里有两次写,一次读,是在哪一次出错?

⑵ 请教i2c驱动测试 Linux交流区 ARM9之家论坛

这是IIC驱动中ioctl()的处理函数(源代码在drivers/i2c/i2c-dev.c)

static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long
arg)

{
struct i2c_client *client = (struct i2c_client *)file->private_data;
unsigned long funcs;

dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x,
arg=0x%02lx\n",
cmd, arg);

switch ( cmd ) {
case I2C_SLAVE:
case I2C_SLAVE_FORCE:
/* NOTE: devices set up to work with "new style" drivers
* can't use I2C_SLAVE, even when the device node is not
* bound to a driver. Only I2C_SLAVE_FORCE will work.
*
* Setting the PEC flag here won't affect kernel drivers,
* which will be using the i2c_client node registered with
* the driver model core. Likewise, when that client has
* the PEC flag already set, the i2c-dev driver won't see
* (or use) this setting.
*/
if ((arg > 0x3ff) ||
(((client->flags & I2C_M_TEN) == 0) && arg >
0x7f))
return -EINVAL;
if (cmd == I2C_SLAVE &&
i2cdev_check_addr(client->adapter, arg))
return -EBUSY;
/* REVISIT: address could become busy later */
client->addr = arg;
return 0;

⑶ 如何使用linux内核自带的gpio模拟i2c驱动

单独编译?在不同的平台下 GPIO的驱动是不同的 不过大致是相似的 可以根据不同的平台修改下

⑷ 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中,mole_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 = 1<<0,

.sda_is_open_drain = 1,

.scl_pin = 1<<1,

.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驱动支持Sub Address的两种方法

【目的】
AS3527有一个模拟部分,称作AFE,其与数字部分通过i2c通信,此处AFE部分有很多寄存器供外界操作访问,如果想要访问这些寄存器,就要用到Sub Address,所以,要实现让i2c 驱动支持Sub Address的模式。
i2C本身的架构中,没有支持sub address,所以,我们只能想办法,让其I2C支持(方法1)或者用smbus的架构(方法2).
【方法】
方法1:
在i2c的message中传递一个2个字节的buffer,分别存放Sub Address和data
比如,对于读操作,就可以这么实现:
int afe_read_reg(int addr, u8 *pdata)
{
u8 msgbuf[2];
struct i2c_msg msg =
{
.addr = save_client->addr | ( << 8),
.flags = I2C_M_RD ,
.len = 2,
.buf = msgbuf,
};
msgbuf[0] = addr; //存放Sub Address,此处的Addr是寄存器地址,也就是Sub Address
msgbuf[1] = 0; //初始化
if (i2c_transfer(save_client->adapter, &msg, 1) < 0) {
dev_warn(&save_client->dev,
"can't read from afe /n");
return -ENOMEM;
}
*pdata = msgbuf[1];
return 0;
}
方法2:
使用SMBUS的框架,其支持Sub Address
在i2c读操作中,直接调用SMBUS架构中的函数i2c_smbus_read_byte_data:
int afe_read_reg(int addr, u8 *pdata)
{
int ret;
ret = i2c_smbus_read_byte_data(save_client, addr);
if (ret < 0)
return ret;
else {
*pdata = (u8)ret;
return 0;
}
}
然后函数调用顺序是
i2c_smbus_read_byte_data -> i2c_smbus_xfer ->
adapter->algo->smbus_xfer 或 i2c_smbus_xfer_emulated
(1)此处如果你自己的I2C驱动中没有实现
adapter->algo->smbus_xfer
那么就会去调用i2c_smbus_xfer_emulated,其会把I2C的读一个字节的操作,
分成2个message,然后
i2c_smbus_xfer_emulated -> i2c_transfer -> adap->algo->master_xfer(adap,msgs,num)
去调用底层自己的i2c传输的函数master_xfer去实现两个message的传输。
此处要注意的是,如果你的i2C的控制器和i2c设备,支持将此I2C的读一个字节操作分两个message传输,
那么此处此方法也是可以的。
而你的底层的master_xfer函数,只要负责将对应的message发送出去也就可以实现对应的功能了。
否则,就像我此处遇到的,我这里的AFE的i2c控制器,不支持读操作分成两次message,只支持一个I2C message的传输,
所以,只能是在底层特殊处理,将2个message自己整理成一个message,或者是用下面的办法。
(2)自己实现了adapter->algo->smbus_xfer
自己仿照i2c_smbus_xfer_emulated,在具体实现的时候,对于读和写都只是发送一个message,然后让底层代码
adap->algo->master_xfer去处理这个message,实现对应的读和写。
【注意】
1.以上,不论是1还是2,都是在实现了自己I2C驱动底层message传输的基本函数之后,才可以工作的。
而对于这个基本函数,即adap->algo->master_xfer,
都是要在实现的时候,注意上层传递过来的buffer的第一个字节是sub address,第二个字节才是要用于写入或读取的buffer。
2.对于方法2(2),在模拟i2c_smbus_xfer_emulated实现自己的xfer函数的时候,
不能直接调用i2c_transfer,因为i2c_transfer里面,去获得adapter->bus_lock,而i2c_smbus_xfer中,调用adapter->algo->smbus_xfer之前,已经进行了对于adapter->bus_lock锁定,而因此会形成死锁的的,办法是不要再去获得锁,而直接调用adapter->algo->master_xfer即可。

⑹ LinuxI2C总线外接设备写入问题

"/dev/i2c/0"
在内核里面实现了读取的操作了?有没模块注册了字符驱动。
内核打印的信息

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

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

⑻ linux i2c驱动 什么时候调用 detect

1、使用linux系统i2c体系,包括设备驱动,总线驱动,一般总线驱动已经写好了,需要你写一个设备驱动 2、使用gpio模拟i2c协议 3、望采纳 4、谢谢

⑼ 如何测试IIC通讯成功

一是看数据传输成功没有啊 ,还有是示波器看波形,波形正确了就证明成功了啊。

⑽ i2c 在Linux下编程,测试i2c模块是否能正常通信

如果你用的IC自己带I2C模块那肯定有一个寄存器可以给你写地址进去
然后传输中 会自动判断地址是否匹配

如果你是IO口模拟I2C传输
那就要主机先发送地址
从机用if判断 主机那边发过来的地址数据 是不是 我这边想收到的地址数据

阅读全文

与linuxi2c测试相关的资料

热点内容
找漫画看应该下载什么app 浏览:180
如何在vps上搭建自己的代理服务器 浏览:744
nginxphp端口 浏览:403
内脏pdf 浏览:152
怎么看云服务器架构 浏览:85
我的世界国际服为什么登不进服务器 浏览:996
微盟程序员老婆 浏览:930
intellij创建java 浏览:110
java连接odbc 浏览:38
启动修复无法修复电脑命令提示符 浏览:359
手机编程是什么 浏览:98
山东移动程序员 浏览:163
苏州java程序员培训学校 浏览:479
单片机液晶驱动 浏览:855
魔拆app里能拆到什么 浏览:132
新预算法的立法理念 浏览:144
wdcpphp的路径 浏览:135
单片机p0口电阻 浏览:926
浏览器中调短信文件夹 浏览:594
五菱宏光空调压缩机 浏览:70