Linux I2C驱动个人理解(二)
来源:互联网 发布:淘宝手机版店招制作 编辑:程序博客网 时间:2024/05/22 10:42
I2C的核心也就是I2C总线驱动如何设备驱动如何连接起来的,下面一组函数表示主要的。
1.i2c_adapter.
int i2c_add_adapter(struct i2c_adapter *adap);
int i2c_del_adapter(struct i2c_adapter *adap);
2.i2c_driver
int i2c_register_driver(struct module *owner ,struct i2c_driver * driver);
int i2c_del_driver(struct i2c_driver * driver);
inline int i2c_add_driver(struct i2c_driver * driver);
3.i2c_client
int i2c_attach_client(struct i2c_client *client);
int i2c_detach_client(struct i2c_client *client);
4.
int i2c_transfer(struct i2c_adapter *adap,struct i2c_msg *msgs,int num);
int i2c_master_send(struct i2c_client *client ,const char *buf ,int count);
int i2c_master_recv(struct i2c_client *client ,const char *buf ,int count);
以上函数原型都可以在i2c-core.c中找到,有助于理解。
/**********************************************************************************************************************************************/
说一下i2c设备驱动
1.首先是初始化
static struct i2c_driver xx_driver={
.driver={
.name="xx",
},
.probe=xx_probe,
.remove=xx_remove,
.id_table=xx_id,
};
2.加载与卸载
static int __init xx_init(void)
{
return i2c_add_driver(&xx_driver);
}
static int __exit xx_exit(void)
{
i2c_del_driver(&xx_driver);
}
3.读写
struct i2c_msg msg[2];
/*******写******/
msg[0].addr=client->addr;
msg[0].flags=0;
msg[0].len=1;
msg[0].buf=&offs;
/*********读******/
msg[0].addr=client->addr;
msg[0].flags=I2C_M_RD;
msg[0].len=sizeif(buf);
msg[0].buf=&buf[0];
i2c_transfer(client->adapter,msg,2);
4.ioctl
i2cdev_ioctl()常用功能:I2C_SLAVE(设置从地址),I2C_RETRIES(没有收到ACK充实次数,默认为1),I2C_TIMEOUT(超时),I2C_RDWR。
demo:
#include <stdio.h>#include <linux/i2c.h>#include <linux/i2c-dev.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <string.h>#include <stdlib.h>#define I2C_DEFAULT_TIMEOUT 1#define I2C_DEFAULT_RETRY 3/* * fd : 文件描述符 * timeout : 发送超时时间 * retry : 重复发送次数 *///重复发送次数可以设多一点,在调试的时候,只设置了一次,导致有时候发送会失败。int i2c_set(int fd, unsigned int timeout, unsigned int retry){ if (fd == 0 ) return -1; if (ioctl(fd, I2C_TIMEOUT, timeout ? timeout : I2C_DEFAULT_TIMEOUT) < 0) return -1; if (ioctl(fd, I2C_RETRIES, retry ? retry : I2C_DEFAULT_RETRY) < 0) return -1; return 0;}/* * fd : 文件描述符 * addr : i2c的设备地址 * reg : 寄存器地址 * val : 要写的数据 * 描述 :从指定地址写数据 */int i2c_byte_write(int fd, unsigned char addr, unsigned char reg, unsigned char val){ int ret = 0; unsigned char outbuf[2]; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages; packets.nmsgs = 1; packets.msgs = &messages; //发送要读取的寄存器地址 messages.addr = addr; messages.flags = 0; messages.len = 2; //寄存器地址加数据,共发送2个字节 messages.buf = outbuf; outbuf[0] = reg; outbuf[1] = val; ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets); //读出来 if (ret < 0) ret = -1; return ret;}/* * fd : 文件描述符 * addr : i2c的设备地址 * reg : 寄存器地址 * val : 要写的数据 * len : 数据长度 * 描述 :从指定地址写数据 * 24c02以8字节为1个page,如果在一个page里面写,写的字节长度超过这个page的末尾, * 就会从page的开头写,覆盖开头的内容 */int i2c_nbytes_write(int fd, unsigned char addr, unsigned char reg, unsigned char *val, int len){ int ret = 0; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages; int i; packets.nmsgs = 1; packets.msgs = &messages; //发送要读取的寄存器地址 messages.addr = addr; messages.flags = 0; //write messages.len = len + 1; //数据长度 //发送数据 messages.buf = (unsigned char *)malloc(len+1); if (NULL == messages.buf) { ret = -1; goto err; } messages.buf[0] = reg; for (i = 0; i < len; i++) { messages.buf[1+i] = val[i]; } ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets);//读出来 if (ret < 0){ printf("write error!\n"); return -1; }err: free(messages.buf); return ret;}/* * fd : 文件描述符 * addr : i2c的设备地址 * val : 保存读取数据 * 描述 :从当前地址读取一个字节数据 */int i2c_byte_read(int fd, unsigned char addr, unsigned char *val){ int ret = 0; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages; packets.nmsgs = 1; //数据帧类型只有一种,读操作,只需要发送一个起始信号,因此是1 packets.msgs = &messages; //发送要读取的寄存器地址 messages.addr = addr; //i2c设备地址 messages.flags = I2C_M_RD; //读操作 messages.len = 1; //数据长度 messages.buf = val; //读取的数据保存在val ret = ioctl (fd, I2C_RDWR, (unsigned long)&packets); //发送数据帧 if (ret < 0) ret = -1; return ret;}/* * fd : 文件描述符 * addr : i2c的设备地址 * reg : 寄存器地址 * val : 保存读取的数据 * len : 读取数据的长度 * 描述 :读取达到eeprom的末尾时,会读取最开头的字节 */int i2c_nbytes_read(int fd, unsigned char addr, unsigned char reg, unsigned char *val, int len){ int ret = 0; unsigned char outbuf; struct i2c_rdwr_ioctl_data packets; struct i2c_msg messages[2]; /* 数据帧类型有2种 * 写要发送起始信号,进行写寄存器操作,再发送起始信号,进行读操作, * 有2个起始信号,因此需要分开来操作。 */ packets.nmsgs = 2; //发送要读取的寄存器地址 messages[0].addr = addr; messages[0].flags = 0; //write messages[0].len = 1; //数据长度 messages[0].buf = &outbuf; //发送寄存器地址 outbuf = reg; //读取数据 messages[1].len = len; //读取数据长度 messages[1].addr = addr; //设备地址 messages[1].flags = I2C_M_RD; //read messages[1].buf = val; packets.msgs = messages; ret = ioctl(fd, I2C_RDWR, (unsigned long)&packets); //发送i2c,进行读取操作 if (ret < 0) ret = -1; return ret;}
- Linux I2C驱动个人理解(二)
- Linux I2C驱动个人理解(一)
- linux驱动:i2c驱动(二)
- Linux I2C驱动完全分析(二)
- Linux I2C驱动源码分析(二)
- Linux I2C驱动源码分析(二)
- Linux I2C驱动源码分析(二)
- Linux I2C驱动完全分析(二)
- Linux I2C驱动完全分析(二)
- Linux I2C设备驱动编写(二)
- Linux i2c设备驱动编写(二)
- Linux I2C驱动完全分析(二)
- Linux I2C驱动完全分析(二)
- Linux I2C设备驱动编写(二)
- linux I2C驱动分析(二)
- Linux I2C设备驱动编写(二)
- Linux下I2C驱动分析(二)
- Linux I2C设备驱动编写(二)
- FFMPEG avformat_find_stream_info替换
- 每日一题(15): poj2533
- ebtables/iptables interaction on a Linux-based bridge
- NumPy之二:数组形状操作
- 图像处理与计算机视觉基础,经典以及最近发展
- Linux I2C驱动个人理解(二)
- spring cloud微服务框架 第四天
- 移动端input上传调用相机
- 数据结构—链表(三)
- 类继承学习笔记
- linux 让history显示时间
- 正则表达式
- REST学习(二)
- ViewPager设置切换动画