基于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,内核定义结构体如下,用户层需要自己定义如下结构体,对应类型需要替换。
对应i2c-dev的设备节点是/dev/i2c-0
#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;
}
#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*/
};
{
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*/
};

本文详细介绍了I2C通信的基本原理及其在用户模式下的驱动实现方法。通过具体的代码示例展示了如何使用I2C-dev设备节点进行数据读写操作。
2353

被折叠的 条评论
为什么被折叠?



