Linux I2C read eeprom 从应用层看系统
来源:互联网 发布:云图tv电视直播mac版 编辑:程序博客网 时间:2024/05/16 12:38
Linux 操作I2C从设备有两种不同的方法。本篇文章将会介绍通过系统总线来操作I2C设备的流程。
在应用层操作I2C,使用ioctl来传参。 ret = ioctl(fd, I2C_RDWR, (unsigned long)&erom_data);
这是设备接口控制函数ioctl,
fd是打开设备节点的文件描述符fd = open("/dev/i2c-0",O_RDWR);
I2C_RDWR 是命令控制符,这是定义在 linux/i2c-dev.h 中的宏。就是告诉驱动我们要它干什么。
#define I2C_RETRIES 0x0701 /* number of times a device address should be polled when not acknowledging */#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms *//* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses * are NOT supported! (due to code brokenness) */#define I2C_SLAVE 0x0703 /* Use this slave address */#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it is already in use by a driver! */#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */#define I2C_PEC 0x0708 /* != 0 to use PEC with SMBus */#define I2C_SMBUS 0x0720 /* SMBus transfer */
透过这些命令控制符,可向定义在 /linux/i2c-dev.c 的i2cdev_ioctl()函数传递cmd。下面的fops 就是定义在i2c-dev.c 的钩子函数,在应用程序空间调用ioctl,内核就会找到i2cdev_ioctl(),并且调用。然后根据传入的不同的命令控制符,来调用不同函数来实现不同的功能。
static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = i2cdev_read, .write = i2cdev_write, .unlocked_ioctl = i2cdev_ioctl, .open = i2cdev_open, .release = i2cdev_release,};
比如,我们现在传入的 I2C_RDWR ,意思就是读写,ioctl就会继续调用
i2cdev_ioctl_rdrw(client, arg);
这个函数就会透过i2c_transfer(client->adapter, rdwr_pa, rdwr_arg.nmsgs);对I2C从设备进行操作。
下面介绍重头戏 erom_data
定义如下
struct i2c_rdwr_ioctl_data erom_data;
我们看看 i2c_rdwr_ioctl_data 是什么内容
struct i2c_rdwr_ioctl_data { struct i2c_msg __user *msgs; /* pointers to i2c_msgs */ __u32 nmsgs; /* number of i2c_msgs */};
msgs 从命名上就可以看出 这就是我们和终端设备通讯 的消息,
nmsgs 也可以看出,这是消息的数量。
我们看看 i2c_msg 是什么内容
struct i2c_msg { __u16 addr; /* slave address */ __u16 flags;#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */#define I2C_M_RD 0x0001 /* read data, from slave to master */#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ __u16 len; /* msg length */ __u8 *buf; /* pointer to msg data */};
这些成员就不用解释了吧,上面的注释都写得很清楚了。
flags需要解释下(我认为)如果在设置的时候不赋值,或者设置为0,应该是向从设备写入数据。赋值为I2C_M_RD 则为向从设备读取数据。
总结 ioctl(fd, I2C_RDWR, (unsigned long)&erom_data);
这一行代码,就实现了以下内容
-明确我们操作的设备是什么,这个由fd确定。
- 告诉驱动我们让它实现什么功能,这个由I2C_RDWR确定,还可以填入另外的值,可以参照上面宏设置。
- 和从设备通讯的 msgs。(个人认为,这个msgs 可能是发送给master,即I2C控制器的消息,这里面包含了 slave address 、flags等设置,这些都是告诉master 怎么和 终端设备通讯)。
- 我们可以从*buf 读出或者写入数据
以上解释了ioctl内核操作的流程.下面介绍我们该如何填充 i2c_rdwr_ioctl_data erom_data;
0 0
- Linux I2C read eeprom 从应用层看系统
- Linux I2C read eeprom 从应用层看系统
- 应用层对i2c通用驱动接口与eeprom的i2c驱动接口从应用层到内核层调用区别和联系
- linux I2C读写EEPROM
- 应用层读写i2c从设备寄存器
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- Linux下使用I2C总线读写 EEPROM(读写i2c从设备通用程序)
- 从"read"看系统调用的耗时
- 从"read"看系统调用的耗时
- 从"read"看系统调用的耗时
- 从"read"看系统调用的耗时
- linux I2c FM24C256应用层代码
- Linux应用层的i2c读写
- Linux应用层的i2c读写
- I2C 总线接口电路EEPROM及应用
- linux i2c-eeprom-at24c02字符驱动问题
- ASCII
- tensorflow表情识别:训练、参数固化、应用预测
- Java基础--I/O流--File类--删除
- Fastxml 简单常用注解学习笔记
- Android开发艺术探索——第八章:理解Window和WindowManager
- Linux I2C read eeprom 从应用层看系统
- 文件操作相关函数
- map中containsKey与get方法区别
- 算法导论 练习题 13.4-6
- 微信小程序:页面跳转
- 线程基础:多任务处理(13)——Fork/Join框架(解决排序问题)
- Sql Server系统数据库的作用
- POJ 1603 Risk 最短路 Floyd Dijstra
- 【数据结构_BFS_1069】图的深度优先录入