I2C设备驱动编写

在Linux内核源代码中的drivers/i2c/busses目录下包含着一些适配器的驱动。如S3C2410的驱动i2c-s3c2410.c。当适配器加载到内核后,接下来的工作就要针对具体的设备编写设备驱动了。

编写I2C设备驱动也有两种方法。一种是利用系统给我们提供的i2c-dev.c来实现一个i2c适配器的设备文件。然后通过在应用层操作i2c适配器来控制i2c设备。另一种是为i2c设备,独立编写一个设备驱动。注意:在后一种情况下,是不需要使用i2c-dev.c的。

i2c-s3c2410.c 为总线驱动,好像是必需的,编译的时候不添加i2c-s3c2410.c的配置选项测试程序不能读写IIc设备dev/i2c/0

项目中的是独立的设备驱动程序。

下面是利用i2c-dev.c创建的设备文件/dev/i2c-0用户模式下控制适配器访问at24c02的例子:

#define I2C_RETRIES 0x0701

 17 #define I2C_TIMEOUT 0x0702

 18 #define I2C_RDWR 0x0707

 19 /*********定义struct i2c_rdwr_ioctl_data和struct i2c_msg,要和内核一致*******/

 20 struct i2c_msg

 21 {

 22         unsigned short addr;

 23         unsigned short flags;

 24         #define I2C_M_TEN 0x0010

 25         #define I2C_M_RD 0x0001

 26         unsigned short len;

 27         unsigned char *buf;

 28 };

 29 

 30 struct i2c_rdwr_ioctl_data

 31  {

 32         struct i2c_msg *msgs;

 33         int nmsgs;

 34         /* nmsgs这个数量决定了有多少开始信号,对于“单开始时序”,取1*/

 35 };

 36 int main()

{

 38         int fd,ret;

 39         struct i2c_rdwr_ioctl_data e2prom_data;

 40         fd=open("/dev/i2c-0",O_RDWR);

 41 /*

 42 /dev/i2c-0是在注册i2c-dev.c后产生的,代表一个可操作的适配器。如果不使用i2c-d    ev.c*的方式,就没有,也不需要这个节点。

 43 */

 44         if(fd<0)

 45         {

 46         perror("open error");

 47         printf("open device error\n");

 48         return 0;

 49         }

 50         e2prom_data.nmsgs=2;

 51 /*

 52 *

 53 *          *因为操作时序中,最多是用到2个开始信号(字节读操作中),所以此将

 54 *                   *e2prom_data.nmsgs配置为2

 55 *

 56 **/

 57         e2prom_data.msgs=(struct i2c_msg*)malloc(e2prom_data.nmsgs*sizeof(st    ruct i2c_msg));

 58         if(!e2prom_data.msgs)

 59         {

 60         perror("malloc error");

 61         exit(1);

 62         }

 63         ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/

 64         ioctl(fd,I2C_RETRIES,2);/*重复次数*/

 65         /***write data to e2prom**/

 66         e2prom_data.nmsgs=1;

 67         (e2prom_data.msgs[0]).len=5; //1个 e2prom 写入目标的地址和4个数据

 68         (e2prom_data.msgs[0]).addr=0x50;//e2prom 设备地址

 69         (e2prom_data.msgs[0]).flags=0; //write

 70         (e2prom_data.msgs[0]).buf=(unsigned char*)malloc(5);

 71         (e2prom_data.msgs[0]).buf[0]=0x10;// e2prom 写入目标的地址

 72         (e2prom_data.msgs[0]).buf[1]=0x11;//the data to write

 73         (e2prom_data.msgs[0]).buf[2]=0x22;

 74         (e2prom_data.msgs[0]).buf[3]=0x33;

 75         (e2prom_data.msgs[0]).buf[4]=0x44;

              ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);

 78         if(ret<0)

 79         {

 80         perror("ioctl error1");

 81         printf("ioctl error1\n");

 82         }

 83         sleep(1);

 84 

 85         /******read data from e2prom*******/

 86         e2prom_data.nmsgs=2;

 87         (e2prom_data.msgs[0]).len=1; //e2prom 目标数据的地址

 88         (e2prom_data.msgs[0]).addr=0x50; // e2prom 设备地址

 89         (e2prom_data.msgs[0]).flags=0;//write

 90         (e2prom_data.msgs[0]).buf[0]=0x10;//e2prom数据地址

 91         (e2prom_data.msgs[1]).len=4;//读出的数据

 92         (e2prom_data.msgs[1]).addr=0x50;// e2prom 设备地址

 93         (e2prom_data.msgs[1]).flags=I2C_M_RD;//read

 94         (e2prom_data.msgs[1]).buf=(unsigned char*)malloc(4);//存放返回值的地

    址。

 95         (e2prom_data.msgs[1]).buf[0]=0;//初始化读缓冲

 96         (e2prom_data.msgs[1]).buf[1]=0;//初始化读缓冲

 97         (e2prom_data.msgs[1]).buf[2]=0;//初始化读缓冲

 98         (e2prom_data.msgs[1]).buf[3]=0;//初始化读缓冲

                 ret=ioctl(fd,I2C_RDWR,(unsigned long)&e2prom_data);

100         if(ret<0)

101         {

102                 perror("ioctl error2");

103                 printf("ioctl error2\n");

104         }

105 

106         printf("buff[0]=%x\n",(e2prom_data.msgs[1]).buf[0]);

107         printf("buff[1]=%x\n",(e2prom_data.msgs[1]).buf[1]);

108         printf("buff[2]=%x\n",(e2prom_data.msgs[1]).buf[2]);

109         printf("buff[3]=%x\n",(e2prom_data.msgs[1]).buf[3]);

110         /***打印读出的值,没错的话,就应该是前面写的0x11 0x22 0x33 0x44了***/

111         close(fd);

112         return 0;

113 }

你可能感兴趣的:(linux,驱动)