设备驱动(十七)

基于I2C子系统
i2c-core:纽带;提供了一组通用的和硬件无关的接口函数
I2C adapter driver :驱动总线产生时序
i2c device driver:调用i2c-core中的函数完成i2c device driver的注册、注销和i2cmsg的封装
i2c-dev在子系统中实现的通用i2c设备驱动,可用来访问任意i2c设备,为快速测试硬件

I2C用户模式驱动
通过I2C-dev发送i2c_msg访问
用户层没有i2c_msg,内核定义结构体如下,用户层需要自己定义如下结构体,对应类型需要替换。
设备驱动(十七)_第1张图片
设备驱动(十七)_第2张图片
对应i2c-dev的设备节点是/dev/i2c-0
设备驱动(十七)_第3张图片
#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include "i2c.h"
#define I2C_RDWR 0x0707
int read_i2c(int fd, unsigned char addr, unsigned int len, char *buf);
int write_i2c(int fd, unsigned char addr, unsigned int len, char *buf);
int main()
{
     int fd, i;
     char buf[100] = {0};
     unsigned char addr = 0x20;
     if ((fd = open("/dev/i2c-0",O_RDWR)) < 0)
     {
          perror("open error");
          exit(-1);
     }
     read_i2c(fd, addr, 8, buf);
     printf("%s\n", buf);

     write_i2c(fd, addr, 8, "Hello PI");

     read_i2c(fd, addr, 8, buf);
     printf("%s\n", buf);

     close(fd);

     return 0;
}
int read_i2c(int fd, unsigned char addr, unsigned int len, char *buf)
{

     struct i2c_rdwr_ioctl_data pm_data;
     struct i2c_msg msgs[2];
     //写要读的地址
     msgs[0].addr = 0x50;     //E2PROM
     msgs[0].flags = 0;          //write
     msgs[0].len = 1;
     msgs[0].buf = (unsigned char *)malloc(1);
     *(msgs[0].buf) = addr;     //从addr开始读

     //读数据
     msgs[1].addr = 0x50;     //E2PROM
     msgs[1].flags = 1;          //read
     msgs[1].len = len;
     msgs[1].buf = (unsigned char *)malloc(len);
     pm_data.msgs = msgs;
     pm_data.nmsgs = 2;

     if (ioctl(fd, I2C_RDWR, (unsigned long)&pm_data) < 0)
     {
          perror("ioctl error 1");
          exit(-1);
     }
     usleep(100000);
     strncpy(buf, msgs[1].buf, len);
     free(msgs[0].buf);
     free(msgs[1].buf);
     return 0;
}
int write_i2c(int fd, unsigned char addr, unsigned int len, char *buf)
{

     struct i2c_rdwr_ioctl_data pm_data;
     struct i2c_msg msgs[1];

     //写数据
     msgs[0].addr = 0x50;     //E2PROM
     msgs[0].flags = 0;          //write
     msgs[0].len = len + 1;
     msgs[0].buf = (unsigned char *)malloc(len + 1);
     *(msgs[0].buf) = addr;     //从addr写
     strncpy(msgs[0].buf + 1, buf, len);
     pm_data.msgs = msgs;
     pm_data.nmsgs = 1;
     if (ioctl(fd, I2C_RDWR, (unsigned long)&pm_data) < 0)
     {
          perror("write ioctl error 1");
          exit(-1);
     }
     free(msgs[0].buf);
     usleep(100000);
     return 0;
    
}


struct i2c_msg
{
     unsigned short addr;
     unsigned short flags;
     unsigned short len;
     unsigned char *buf;
};

struct i2c_rdwr_ioctl_data
{
     struct i2c_msg *msgs;
     int nmsgs;
     /* nmsgs这个数量决定了有多少开始信号,对于“单开始时序”,取1*/
};

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