Linux驱动之i2c用户态调用_第1页
Linux驱动之i2c用户态调用_第2页
Linux驱动之i2c用户态调用_第3页
Linux驱动之i2c用户态调用_第4页
Linux驱动之i2c用户态调用_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-.z.概述I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL.正因为这样,它方便了工程人员的布线.用户态实现设备驱动在Linu*核代码文件i2c-dev.c中实现了I2C适配器设备文件的功能,针对每个适配器生成一个主设备号为89的设备节点〔次设备号为0-255〕,I2c-dev.c并没有针对特定的设备而设计,只是提供了通用的read(),write(),和ioctl()等文件操作接口,在用户空间的应用层就可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或存放器,并控制I2C设备的工作方式。i2c适配器的设备节点是/dev/i2c-*,其中*是数字。由于适配器编号是动态分配的〔和注册次序有关〕,所以想了解哪一个适配器对应什么编号,可以查看/sys/class/i2c-dev/目录下的文件容。用户态调用3.1、i2c-dev用户空间操作i2c,需要包含以下头文件。翻开适配器对应的设备节点i2c-dev为翻开的线程建立一个i2c_client,但是这个i2c_client并不加到i2c_adapter的client链表当中。他是一个虚拟的临时client,当用户翻开设备节点时,它自动产生,当用户关闭设备节点时,它自动被释放。3.2、ioctl()查看include/linu*/i2c-dev.h文件,可以看到i2c支持的IOCTL命令*defineI2C_RETRIES0*0701/*设置收不到ACK时的重试次数*/*defineI2C_TIMEOUT0*0702/*设置超时时限的jiffies*/*defineI2C_SLAVE0*0703/*设置从机地址*/*defineI2C_SLAVE_FORCE0*0706/*强制设置从机地址*/*defineI2C_TENBIT0*0704/*选择地址位长:=0for7bit,!=0for10bit*/*defineI2C_FUNCS0*0705/*获取适配器支持的功能*/*defineI2C_RDWR0*0707/*binedR/Wtransfer(oneSTOPonly)*/*defineI2C_PEC0*0708/*!=0tousePECwithSMBus*/*defineI2C_SMBUS0*0720/*SMBustransfer*/例如:1、设置重试次数:ioctl(fd,I2C_RETRIES,m);设置适配器收不到ACK时重试的次数为m。默认的重试次数为12、设置超时ioctl(fd,I2C_TIMEOUT,m);

设置SMBus的超时时间为m,单位为jiffies。3、设置从机地址ioctl(fd,I2C_SLAVE,addr);

ioctl(fd,I2C_SLAVE_FORCE,addr);

在调用read()和write()函数之前必须设置从机地址。这两行都可以设置从机的地址,区别是第二行无论核中是否已有驱动在使用这个地址都会成功,第一行则只在该地址空闲的情况下成功。由于i2c-dev创立的i2c_client不参加i2c_adapter的client列表,所以不能防止其它线程使用同一地址,也不能防止驱动模块占用同一地址。4、设置地址模式ioctl(file,I2C_TENBIT,select)

如果select不等于0选择10bit地址模式,如果等于0选择7bit模式,默认7位模式。3.3数据包i2c发送或者接收一次数据都以数据包(structi2c_msg)封装addr是设备从地址。flags是通信标志,发送数据为0,接收数据为I2C_M_RD。len是数据长度buf是传输数据3.4、承受数据设备驱动中我们通常调用/driver/i2c/i2c-core.c定义的接口i2c_master_recv来接收一次数据。通过i2c_transfer调用数据包。inti2c_master_recv(structi2c_client*client,char*buf,intcount)

{

structi2c_adapter*adap=client->adapter;//获取adapter信息structi2c_msgmsg;//定义一个临时的数据包intret;msg.addr=client->addr;//将从机地址写入数据包msg.flags=client->flags&I2C_M_TEN;//将从机标志并入数据包msg.flags|=I2C_M_RD;//将此次通信的标志并入数据包msg.len=count;//将此次接收的数据字节数写入数据包msg.buf=buf;ret=i2c_transfer(adap,&msg,1);//调用平台接口接收数据/*Ifeverythingwentok(i.e.1msgtransmitted),return*bytestransmitted,elseerrorcode.*/return(ret==1)"count:ret;//如果接收成功就返回字节数

}

E*PORT_SYMBOL(i2c_master_recv);参考驱动i2c_master_recv()函数封装属于自己用户态的承受函数。用户态是通过ioctl(handle->fd,I2C_RDWR,&data)函数与i2c从设备进展数据交互。主要有2个步骤:首先是写入需要读取的存放器的地址,然后从存放器中读取数据。需要2个数据包。如下:3.5、发送数据设备驱动中我们通常调用/driver/i2c/i2c-core.c定义的接口i2c_master_send来发送一次数据。通过i2c_transfer调用数据包inti2c_master_send(structi2c_client*client,constchar*buf,intcount)

{

intret;structi2c_adapter*adap=client->adapter;//获取adapter信息structi2c_msgmsg;//定义一个临时的数据包msg.addr=client->addr;//将从机地址写入数据包msg.flags=client->flags&I2C_M_TEN;//将从机标志并入数据包msg.len=count;//将此次发送的数据字节数写入数据包msg.buf=(char*)buf;//将发送数据写入数据包ret=i2c_transfer(adap,&msg,1);//调用平台接口发送数据/*Ifeverythingwentok(i.e.1msgtransmitted),return*bytestransmitted,elseerrorcode.*/return(ret==1)"count:ret;//如果发送成功就返回字节数

}

E*PORT_SYMBOL(i2c_master_send);参考驱动i2c_master_send()函数封装属于自己用户态的承受函数。用户态是通过ioctl(handle->fd,I2C_RDWR,&data)函数与i2c从设备进展数据交互。每次要写入两个字节数据主要包括写入的存放器地址和要写入的数据。只需发送一次数据包。如下:3.6、使用案例*include<stdio.h>*include<linu*/i2c.h>*include<linu*/i2c-dev.h>*include<ftl.h>*include<stdio.h>*include<unistd.h>*include<sys/ioctl.h>*include<string.h>*include<stdlib.h>*defineI2C_FILE_NAME"/dev/i2c-1"*defineI2C_ADDR0*40intfd;inti2c_open(){fd=open(I2C_FILE_NAME,O_RDWR);if(fd<0){perror("Unabletoopeni2ccontrolfile");return1;}}inti2c_write(intfd,unsignedchardev_addr,unsignedcharreg_addr,unsignedcharval){intret;unsignedcharbuf[2];structi2c_rdwr_ioctl_datadata;structi2c_msgmessages;buf[0]=reg_addr;buf[1]=val;messages.addr=dev_addr;//deviceaddressmessages.flags=0;//writemessages.len=2;messages.buf=buf;//dataaddressdata.msgs=&messages;data.nmsgs=1;if(ioctl(fd,I2C_RDWR,&data)<0){printf("writeioctlerr\n");return1;}usleep(1000);return1;}inti2c_read(intfd,unsignedcharaddr,unsignedcharreg,unsignedchar*val){intret;structi2c_rdwr_ioctl_datadata;structi2c_msgmessages[2];messages[0].addr=addr;//deviceaddressmessages[0].flags=0;//writemessages[0].len=sizeof(reg);messages[0].buf=®//dataaddressmessages[1].addr=addr;//deviceaddressmessages[1].flags=I2C_M_RD;//readmessages[1].len=sizeof(val);messages[1].buf=val;data.msgs=messages;data.nmsgs=2;if(ioctl(fd,I2C_RDWR,&data)<0){printf("readioctlerr\n");return1;}return0;}intmain(){inti;unsignedcharbuf[4];unsignedcharval[]={0*04,0*05,0*06,0*07};i2c_open();for(i=0;i<4;i++)i2c_write(fd,I2C_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论