前言 Linux的IIC驱动想必大家都耳熟能详,网上也有很多相关的教程。 网上的教程总结,比如: 方法问题描述Linux 3.X.X版本之后,设备树+驱动此方法是比较符合linux驱动的写法的。...他将会操作多个文件 上面的做法都有些困难及弊端存在,经过摸索了一遍Linux的I2C驱动框架,我发现可以很精简的写一个I2C设备的设备驱动。...分析I2C总线驱动说明 I2C总线驱动的代码在linux的源码中--i2c-dev.c中。 在代码中可以看到他提供一套文件操作接口,open,read,write,close接口。...; i2c_msg[0].flags = 0; i2c_msg[0].len = 1; i2c_msg[0].buf = (uint8_t *)®_addr;...i2c_msg[1].addr = 0x69; i2c_msg[1].flags = I2C_M_RD; i2c_msg[1].len = 1; i2c_msg[1].buf =
视频观看 百问网驱动大全 完善虚拟的I2C_Adapter驱动并模拟EEPROM 参考资料: Linux内核文档: Linux-4.9.88\Documentation\devicetree\bindings...\i2c\i2c-gpio.txt Linux-5.4\Documentation\devicetree\bindings\i2c\i2c-gpio.yaml Linux内核驱动程序:使用GPIO模拟...I2C Linux-4.9.88\drivers\i2c\busses\i2c-gpio.c Linux-5.4\drivers\i2c\busses\i2c-gpio.c Linux内核真正的I2C...在master_xfer函数里,我们模拟一个EEPROM,思路如下: 分配一个512自己的buffer,表示EEPROM 对于slave address为0x50的i2c_msg,解析并处理 对于写...:把i2c_msg的数据写入buffer 对于读:从buffer中把数据写入i2c_msg 对于slave address为其他值的i2c_msg,返回错误 2.
i2c_msg标志位 路径:linux-2.6.38/include/linux/i2c.h I2C_M_IGNORE_NAK: 设置这个标志意味当前i2c_msg忽略I2C器件的ack和nack...I2C_M_NOSTART: 设置这个标志意味当前i2c_msg不发送start信号。...其次,如果一个i2c_msg没有定义I2C_M_NOSTART而且又不是msgs序列里的第一个i2c_msg,则回发送重复start信号,我想这就是这个标志起这个名的原因。...我们可以猜想, msgs序列第一个数据必须是地址,同时必须不定义这个标志位 在进行读数据,要从写操作转变为读操作时,会发重复start信号和器件地址时,必须不定义这个标志位 其它情况下一的i2c_msg...参考文章: Linux I2C framework(2)_I2C provider
示例代码 两个重要的数据结构 struct i2c_rdwr_ioctl_data结构体 /inclue/linux/i2c-dev.h /* This is the structure as used...in the I2C_RDWR ioctl call */ struct i2c_rdwr_ioctl_data { struct i2c_msg __user *msgs; /* pointers...to i2c_msgs */ __u32 nmsgs; /* number of i2c_msgs */ }; struct i2c_msg 结构体 include/linux/i2c.h struct...i2c_msg { __u16 addr; /* slave address */ __u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten...参考 i2c驱动之调用ioctl函数进行读写at24c08 Android/linux 平台下使用 i2c-tools调试IIC方法 树莓派学习笔记——I2C Tools 学习笔记 7位,8位和10位IIC
视频观看 百问网驱动大全 I2C系统的重要结构体 参考资料: Linux驱动程序: drivers/i2c/i2c-dev.c I2CTools: https://mirrors.edge.kernel.org...Linux软件框架 4. 重要结构体 使用一句话概括I2C传输:APP通过I2C Controller与I2C Device传输数据。...在Linux中: 怎么表示I2C Controller 一个芯片里可能有多个I2C Controller,比如第0个、第1个、…… 对于使用者,只要确定是第几个I2C Controller...内核里怎么传输数据 使用一句话概括I2C传输: APP通过I2C Controller与I2C Device传输数据 APP通过i2c_adapter与i2c_client传输i2c_msg...内核函数i2c_transfer i2c_msg里含有addr,所以这个函数里不需要i2c_client
I2C Linux-4.9.88\drivers\i2c\busses\i2c-gpio.c Linux-5.4\drivers\i2c\busses\i2c-gpio.c Linux内核真正的I2C...I2C_Adapter驱动框架 2.1 核心的结构体 1. i2c_adapter 2. i2c_algorithm master_xfer:这是最重要的函数,它实现了一般的I2C传输,用来传输一个或多个i2c_msg...所涉及的函数 2. i2c_algorithm示例 Linux-5.4中使用GPIO模拟I2C Linux-5.4中STM32F157的I2C驱动 Linux-4.9.88中IMX6ULL...master_xfer函数,它的实现取决于硬件,大概代码如下: static int xxx_master_xfer(struct i2c_adapter *adapter, struct i2c_msg...*msgs, int num) { for (i = 0; i < num; i++) { struct i2c_msg *msg = msgs[i]; {
上一节 我们学习了: IIC接口下的24C02 驱动分析 接下来本节, 学习Linux下如何利用linux下I2C驱动体系结构来操作24C02 1....I2C体系结构分析 1.1首先进入linux内核的driver/i2c目录下,如下图所示: ?...1; ... ... } 其中i2c_msg结构体的结构,如下所示: struct i2c_msg { __u16 addr; //I2C从机的设备地址.../kernel.h> #include #include #include #include #include #include #include #include <asm/uaccess.h
针对i2c的算法,需要熟悉struct i2c_rdwr_ioctl_data 、struct i2c_msg。使用的命令是I2C_RDWR。 ...struct i2c_rdwr_ioctl_data { struct i2c_msg __user *msgs; /* pointers to i2c_msgs...*/ __u32 nmsgs; /* number of i2c_msgs */ }; struct i2c_msg { ...unistd.h> #include // #include #include #include #include #include #include #include #include #include
但是,读某个地址的数据时,就要用两个i2c_msg结构体来描述它,因为一个i2c_msg结构体只能描述一个传输方向(读/写),我们读取ac24ccxx某个地址上的数据时,要先写出要读取的地址,然后来读取设备地址上的数据...我们要发出I2c传输时,要构造出i2c_msg,把构造出的i2c_msg扔给下面的i2c_controller.c,i2c_controller.c会选择某一个i2c控制器,使用里面的master_xfer.../* 实现 i2c_transfer 接口函数 */ int i2c_transfer(i2c_msg msgs, int num) { return p_i2c_con_selected->...3).调用i2c接口函数,传输构造i2C_msg结构体,我们传输指针只需要传输四个字节,我们需要把以前的参数都改成传输指针的格式。...从设备读函数和写函数类似,读函数需要构造两个i2c_msg(每个i2c_msg只能表示一个传输方向) ,因为在读操作之前,需要把要读的地址告诉从设备。
set-device enable i2c1 重启后查看引脚状态,可以看到3和5都处于alt5了 并且存在/dev/i2c-1这个文件,因为后续我们需要通过操作这个文件来控制i2c通讯 i2c读写程序 linux...打开文件 linux下一切皆是文件,先使用open函数打开我们要操作的设备对应文件,获取文件描述符。...> open设备节点 int fd =open("/dev/i2c-1", O_RDWR); if(fd <0) { perror("Fail to Open\n"); return-1; } 2. i2c_msg...linux下操作i2c不是使用write和read函数,而是使用一个i2c_msg结构体来配置从i2c从起始到停止之间要做的内容。...首先,需要这些头文件 #include #include #include uint8_t addr =0x3c;
构建i2c_driver,并注册到linux i2c中 d. 注册字符设备 e. 向应用层提供i2c设备操作接口 f. 注销i2c设备 本篇文章会按照以上六个阶段展开解析。 流程解析 a....char reg, void *val, int len) { int ret; struct i2c_msg...unsigned char *buf, unsigned char len) { unsigned char temp_buf[256]; struct i2c_msg...由于Linux内部的实现较为复杂,本篇主要以设备驱动的角度来分析整个驱动的代码走向,涉及到内部API的实现,本篇只大概介绍其功能,剩余部分会放在i2c核心继续分析。...参考: 《Linux设备驱动开发详解》 《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.4》 https://blog.csdn.net/Egean/article/details/81085077
而且众所周知,在linux系统中,每一个设备都是以文件的形式存在的,所以在linux中操作I2C外设就变成了操作I2C适配器设备文件。...注意:千万不要忘记给 2c_rdwr_ioctl_data结构体中的最重要的结构i2c_msg中的buf分配内存。...接着就是struct i2c_msg; 它可以包含多条消息,而一条消息有可能包含多个数据。...构建 struct i2c_msg messages */ 47 /* 2.1....构建 struct i2c_msg messages */ 98 /* 1.1. 构建第一条消息 messages[0] */ 99 /* 1.1.1.
源码如下: #include #include #include #include #include #include #include #include #include #include #include #include <linux...unsigned int iicadd; unsigned int iicds; unsigned int iiclc; }; struct s3c2440_i2c_xfer_data { struct i2c_msg...(&s3c2440_i2c_xfer_data.wait); } static int s3c2440_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg
: static int qrd_icn_i2c_read(uint8_taddr) { int ret = 0; intval = 0 ; /* Create a i2c_msg..., that is used to put the controller into read mode and then to read some data. */ struct i2c_msg...uint8_t val) { intret = 0; uint8_tdata_buf[] = { addr, val }; /*Create a i2c_msg
s3c24xx_i2c_message_start()函数代码如下: static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, struct i2c_msg...#include #include #include #include #...include #include #include #include #include...char __user *buf, size_t size, loff_t * offset) { unsigned char address; unsigned char data; struct i2c_msg...struct file *file, const char __user *buf, size_t size, loff_t *offset) { unsigned char val[2]; struct i2c_msg
简介 Regmap 机制是在 Linux 3.1 加入进来的特性。主要目的是减少慢速 I/O 驱动上的重复逻辑,提供一种通用的接口来操作底层硬件上的寄存器。其实这就是内核做的一次重构。...比如如下这个读取寄存器的函数: static int xxx_i2c_read_reg(struct i2c_client *client, u8 reg, u8 *val) { struct i2c_msg...这个结构体的定义在 include/linux/regmap.h,其中包含该设备的寄存器数量,寄存器位宽,缓存类型,读写属性等。 这一层是直接和驱动对接的。...unsigned int max); int (*drop)(struct regmap *map, unsigned int min, unsigned int max); }; 在最新 Linux...LZO(Lempel–Ziv–Oberhumer) 是 Linux 中经常用到的一种压缩算法,Linux 编译后就会用这个算法来压缩。
Linux总线设备框架的工作原理 如果想要弄清楚I2C驱动框架,必须深刻的理解Linux的总线设备框架。之所以会形成这样的框架,很重要的原因是为了代码的复用性。...为了提高驱动的可移植性,Linux抽象出一套管理资源的函数。设备是存在的硬件,在设备里包含自己的属性,也包含需要用到的资源。...3.Linux下I2C驱动程序的体系结构 ---- 对于Linux下的I2C驱动,其体系结构的组成主要分为三个部分 (1)I2C核心:I2C核心提供了I2C总线驱动和设备驱动的注册,注销方法,I2C通信方法...struct i2c_algorithm{ //i2c模式下,收发函数接口 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg...struct i2c_algorithm{ //i2c模式下,收发函数接口 int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg
PPC-Linux中I2C的实现 内核代码(linux-2.6.24)中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-mpc.c中 最重要的函数是mpc_xfer...static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { struct i2c_msg
模块接口说明 3.1 i2c-core 接口 3.1.1 i2c_transfer() 函数原型:int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg...参数: adap:指向所属的 I2C 总线控制器; msgs:i2c_msg 类型的指针; num:表示一次需要处理几个 I2C msg 返回: >0:已经处理的 msg... #include #include #include #include...MODULE_DEVICE_TABLE(i2c, at24_ids); static int eeprom_i2c_rxdata(char *rxdata, int length) { int ret; struct i2c_msg...return ret; } static int eeprom_i2c_txdata(char *txdata, int length) { int ret; struct i2c_msg
(3)i2c传输 寄存器读写通过I2C协议,需定义一个i2c_msg数组,并填充这个数组的地址,buffer等内容,通过i2c_transfer将这个msgs数组转发出去。
领取专属 10元无门槛券
手把手带您无忧上云