用户态访问I2C设备

显然内核里面有万能的驱动程序给我们用

看看内核文档 在\linux-4.8.14\Documentation\i2c下面的用户态访问I2C设备_第1张图片

这里有的dev-interface,这里面告诉了什么,我们来看看里面说了什么

用户态访问I2C设备_第2张图片

通常,I2C设备由设备驱动来控制,但是他也可以提供用户空间直接访问适配器上的设备,通过/dev接口。你需要加载I2C-DEV模块

有个i2c-tools 的工具包帮你写好了接口,在网上下好这个工具包

用户态访问I2C设备_第3张图片

进入之后,点击下载

用户态访问I2C设备_第4张图片

下下来之后我们来看一下


里面有个头文件

用户态访问I2C设备_第5张图片

人家给你封装好了很多接口,我们拿上图那个例子来看一看怎么实现的

用户态访问I2C设备_第6张图片

还不是用ioctl函数实现的。

那么这些ioctl对应的是什么文件呢,


对应的就是i2c-dev这个驱动程序,我们看看这个驱动程序做了什么事情,看看这个驱动的入口函数

用户态访问I2C设备_第7张图片

register_chrdev 首先注册一个字符设备,看看fops

用户态访问I2C设备_第8张图片

来看看open函数

用户态访问I2C设备_第9张图片

这里给你创建了i2c_client,i2c_client里面要有适配器啊,i2c_client要用适配器来发出i2c命令啊,根据你打开设备节点的次设备号,来得到适配器

再看看设备地址,是通过ioctl穿进去的,在我们ioctl里面有这么一行

用户态访问I2C设备_第10张图片

这里有个client->addr=arg。

我们来看一下简单的读函数

用户态访问I2C设备_第11张图片

他用的i2c_master_recv来帮你读,如果我们想用smbus那套代码,我们进入IOCTL里面,看看


有个这个参数,进入看一下,

用户态访问I2C设备_第12张图片

这里是对各种参数的判断,最后


最后调用的i2c_smbus_xfer来进行传输,里面内部实现占时不用关心


我们来写程序来实现,要拿出i2c-tool里面的头文件


如果你开发板下的/dev目录下没有i2c-x这些节点,那么请看你的内核配置


用户态访问I2C设备_第13张图片

是这个i2c-dev这个文件,然后是由CONFIG_I2C_CHARDEV来配置的,是这个宏

我们在内核里面搜索

用户态访问I2C设备_第14张图片

打开这个宏就行了


代码如下

#include
#include
#include
#include
#include
#include
#include "i2c-dev.h"


/*i2c_usr_test r addr
  *i2c_usr_test w addr val
*/
void print_usage(char *file)
{
printf("%s r addr\n",file);
printf("%s w addr val \n",file);
}


int main(int argc,char **argv)
{
    unsigned char addr,data;
int fd;
int dev_addr;


if((argc!=5)&&(argc !=6))
{
print_usage(argv[0]);
return 0;
}


fd=open(argv[1],O_RDWR);
if(fd<0)
{
printf("can't open %s\n",argv[1]);
return -1;
}


dev_addr=strtoul(argv[2],NULL,0);


if(ioctl(fd,I2C_SLAVE,dev_addr)<0)
{
printf("set addr error\n");
return -1;
}


if(strcmp(argv[3],"r")==0)
{
addr=strtoul(argv[4],NULL,0);
data=i2c_smbus_read_word_data(fd,addr);
printf("data : %c,%d,0x%x\n",data,data,data);
}
else if (strcmp(argv[3],"w")==0)
{
addr=strtoul(argv[4],NULL,0);
data=strtoul(argv[5],NULL,0);
i2c_smbus_write_byte_data(fd,addr,data);
}
else
{
print_usage(argv[0]);
return -1;
}
return 0;
}


运行结果如下


运行结果如上图


如果失败了,说明你这个设备地址已经被别的驱动程序使用了,程序证明如下



如上图

这是为了防止你破坏别人的驱动程序


你可能感兴趣的:(linux学习之路)