Linux应用层的i2c读写
i2c通道在开发过程中使用是非常的方便的,主要是由于其简单的结构,i2c主要有SCL,SDA两条通道,一个时钟线,一个数据线,这也是i2c之所以应用如此普遍的原因。i2c的时序如下:
实现上述时序,便可以轻松通过i2c读写寄存器了,接下来看看i2c下在Linux应用层中实现读写,主要是通过O_RDWR IOTCL读写i2c设备,写函数如下:
static int iic_write(int i2c_fd, unsigned int reg_address ,unsigned int reg_val)
{
struct i2c_rdwr_ioctl_data work_queue;
int ret;
work_queue.nmsgs = 2;
work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs * sizeof(struct i2c_msg));
if(!work_queue.msgs)
{
printf("msgs memery alloc error\n");
close(i2c_fd);
return 0;
}
if ((work_queue.msgs[0].buf = (unsigned char *)malloc(2 * sizeof(unsigned char))) == NULL)
{
printf("buf memery alloc error...\n");
close(i2c_fd);
return 0;
}
(work_queue.msgs[0]).len = 2;
(work_queue.msgs[0]).flags = 0;
(work_queue.msgs[0]).addr = slave_address;
(work_queue.msgs[0]).buf[0] = reg_address;
(work_queue.msgs[0]).buf[1] = reg_val;
work_queue.nmsgs = 1;
ioctl(i2c_fd, I2C_RDWR, (unsigned long) &work_queue);
if(ret < 0)
{
printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
return 0;
}
free(work_queue.msgs[0].buf);
free(work_queue.msgs);
}
上述贴出的代码分析 :
i2c_rdwr_ioctl_data结构体的源码如下
/* pointers to i2c_msgs */
struct i2c_msg __user *msgs;
/* number of i2c_msgs */
__u32 nmsgs;
};
{
unsigned short addr; //slave IIC device addr
unsigned short flags; //write read flags
#define I2C_M_TEN0x0010/* this is a ten bit chip address */
#define I2C_M_RD0x0001/* read data, from slave to master */
#define I2C_M_NOSTART0x4000/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_REV_DIR_ADDR0x2000/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK0x1000/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK0x0800/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN0x0400/* length will be first received byte */
unsigned short len; //写入或者读出数据的个数(字节)
unsigned char *buf; //写入或者读出数据的地址 buf[0]
};
i2c的实际地址是0x1c,通过 (0x1c<<1) | 0 得到i2c写地址, (0x1c<<1) | 1 得到i2c读地址。在读i2c主设备模式下ST是指开始位,Device Address是指传感器设备地址及0x1c,w写标志位,后面紧跟着寄存器地址,SR是指重写启动i2c地址,所以读i2c至少要两条消息,我在写消息的时候为了保持读写消息的一致,也将写函数中写了两条消息,在运行过程中导致系统内核崩溃。为了解决这个问题,只要在i2c下发消息前,重新给发送的消息赋值即可。接下来实现i2c的读函数,在调试过程中一旦实现了i2c的驱动,首先应该实现的是读函数。
i2c的读函数如下:
static int iic_read(int i2c_fd, unsigned int reg_address)
{
struct i2c_rdwr_ioctl_data work_queue;
unsigned char val;
int ret;
work_queue.nmsgs = 2;
work_queue.msgs = (struct i2c_msg *)malloc(work_queue.nmsgs *sizeof(struct i2c_msg));
if(!work_queue.msgs)
{
printf("Memery alloc error\n");
close(i2c_fd);
return 0;
}
val =(unsigned char)reg_address;
(work_queue.msgs[0]).len = 1;
(work_queue.msgs[0]).flags = 0;
(work_queue.msgs[0]).addr = slave_address;
(work_queue.msgs[0]).buf = &val;
(work_queue.msgs[1]).len = 1;
(work_queue.msgs[1]).flags = 1;
(work_queue.msgs[1]).addr = slave_address;
(work_queue.msgs[1]).buf = &val;
ret = ioctl(i2c_fd, I2C_RDWR, (unsigned long) &work_queue);
if(ret < 0)
{
printf("Error during I2C_RDWR ioctl with error code: %d\n", ret);
return 0;
}
free(work_queue.msgs);
return val;
}
这样就可以直接调用i2c读写函数实现对传感器寄存器的操作了。最后在说明一点,千万不要忘记给i2c_rdwr_ioctl_data结构体中的最重要最重要最重要的结构i2c_msg中的buf分配内存。
Linux应用层的i2c读写相关推荐
- Linux系统 通过i2c读写铁电存储器 ram
imx6ul上要加入铁电存储器,型号fm24cl64b,存储器焊接在i2c 1上,期间选择位都为0,使用open打开/dev/i2c-0,配置地址时舍弃最后一位读写位,系统会自动提供,(如:铁电存储器 ...
- S3C2440 Linux下的I2C驱动以及I2C体系下对EEPROM进行读写操作。
这篇文档算上期末复习这段时间其实拖了有好久了,因为从一开始接触linux的i2c驱动体系我就各种凌乱,因为起初脑海中既没有整体框架也不熟悉相关体系下的结构,所以四处乱看,经常性的在看内核代码时看着看着 ...
- linux i2c 读写函数,Linux下读写芯片的I2C寄存器
要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...
- linux i2c 读写函数,Linux内核调用I2C驱动_实现MPU6050的数据读取
0. 导语 最近一段时间都在恶补数据结构和C++,加上导师的事情比较多,Linux内核驱动的学习进程总是被阻碍.不过,十一假期终于没有人打扰,有这个奢侈的大块时间,可以一个人安安静静的在教研室看看Li ...
- linux kernel 2.6 i2c设备驱动程序框架介绍,linux设备驱动程序-i2c(2)-adapter和设备树的解析...
linux设备驱动程序-i2c(2)-adapter和设备树的解析 (注: 基于beagle bone green开发板,linux4.14内核版本) 而在linux设备驱动程序--串行通信驱动框架分 ...
- 嵌入式Linux应用层开发教程(一)基本概念
1 应用层与驱动层 要想学习嵌入式Linux应用层的开发,首先要区分好应用层和驱动层之间的关系.我们在本科阶段学习51等较简单的单片机时,都是把应用层和驱动层混在一个文件里写的.比如拿下面的I2C程序 ...
- Linux驱动分析——I2C子系统
stm32mp157 盘古开发板 Linux内核版本4.19 目录 1.朱有鹏老师视频笔记 2.I2C子系统的4个关键结构体 3.关键文件 4.i2c-core.c初步分析 4.1.smbus代 ...
- linux驱动之i2c学习
最近在研究linux的i2c驱动,从最底层i2c控制器初始化到应用层与i2c设备交互基本打通了. 一.linux的i2c架构可以用下图表示: IIC适配器对应一条i2c总线,linux里面用i2c_a ...
- linux i2c子系统看不懂啊,Linux 下的I2C子系统
Linux 下的I2C子系统 2013.7.16 本文分为两部分,一.设备模型 二.平台相关 . ================================================ 第一 ...
最新文章
- 附庸风雅(2006-10-20 13:39:32)(新浪)
- Android 让你的SeekBar 也支持长按事件
- 并发编程—Volatile关键字
- Android之SharedPreferences 存储复杂对象
- JavaScript日期格式化处理
- 【转】js日期时间函数
- Windows环境下配置thrift编译器(VS2015)
- ArcGIS API for Silverlight开发入门准备
- pku 1094(拓扑排序,多次拓扑)
- cas内外网同时访问_科普:CAS 和 ABA
- 多线程实战(二)线程同步
- Asp.net中Bind()和Eval()的区别
- 如何写一份优秀的java程序员简历
- jeecms系统使用介绍——通过二次开发实现对word、pdf、txt等上传附件的全文检索
- 如何将本地图片转换成链接
- jQuery第二章选择器
- Vue install 失败的一些解决办法
- 区块链+大数据:万物互联时代的“CP组合”
- Error:Skipped due to earlier error
- 揭开影响RS485通讯因素的面纱