总结:linux驱动之I2C至少四种读写方法
总结在linux环境下四种读写I2C设备的方法:
一:读写/dev/i2c-x设备结点
/dev/i2c-x设备结点对应的驱动文件为内核目录drivers/i2c下自带的i2c-dev.c文件,通读此文件可以发现它的工作流程。
1、通过register_chrdev注册字符设备结点
2、通过class_create在sysfs下创建对应的class结点
3、利用bus_register_nofifier对I2C总线添加通知链,在有适配器加入或删除时调用相应的处理函数
4、通过I2C核心函数i2c_for_each_dev循环遍历I2C总线上的设备,每找到一个设备便执行i2cdev_attach_adapter函数
5、在i2cdev_attach_adapter函数中会首先判断此设备是否为适配器,如果是,则通过device_create在/dev目录下生成相应的结点,名称为i2c-x,其中x为第几个适配器
6、在用户空间利用open("/dev/i2c-x",O_RDWR)操作相应结点时,会为操作此适配器的每一个用户创建一个i2c_client,i2c_client会通过client->adapter = adapter和file->private_data = client关联对应的适配器和操作文件
7、则在用户空间通过read/write函数操作设备时驱动通过struct i2c_client *client = file->private_data;获取到适配器结构,继而通过调用I2C核心函数i2c_mater_send/i2c_master_recv,最终调用到具体的适配器发送/接收数据函数
通过此方法操作I2C设备时需注意在通过open打开设备结点后,需通过ioctl I2C_SLAVE函数设置设备地址,之后才可通过read/write函数对设备进行操作
二:自定义I2C设备,并通过/dev下对应结点操作
驱动文件可按如下编写:
1、通过module_i2c_driver注册对应的I2C驱动,此时内核会遍历挂载在I2C总线上的设备,通过总线的match方法对驱动和设备进行匹配,匹配原则可以是1、基于设备树的of_driver_match_device方法,对应的结构为定义的驱动结构体是否含有of_match_table成员 2、基于id_table的匹配,对应为驱动是否定义id_table成员 3、基于名字的匹配,匹配原则为驱动的name是否和设备的name相同 4、基于ACPI风格的匹配,使用较少
2、当驱动和设备匹配后会先调用I2C总线的probe函数先做一些处理,之后便会调用我们定义的I2C驱动的probe函数
3、在probe函数中保存client指针到我们自定义的设备结构体中,如自定义为:
struct xxx{
struct i2c_client client;
...
};
4、通过register_chrdev注册字符设备,通过class_create和device_create创建/sys/和/dev/下结点(或通过mknod手工创建)
5、在open函数中将自定义的驱动结构设置为file->private_data,方便在读写函数中获取
6、在用户空间通过open函数打开我们注册的/dev/目录下结点,read/write时便会调用对应的读写函数,在读写函数中会通过file->private_data获取到自定义驱动结构,进而取到i2c_client,最终通过i2c_mater_send/i2c_master_recv或直接自己构建i2c_msg通过i2c_transfer进行发送
三:通过DEVICE_ATTR在对应的sys设备目录下创建读写文件
1、还是先通过module_i2c_driver注册对应的I2C驱动,在找到设备后调用的probe函数中,只需要通过sysfs_create_files创建一组读写函数或sysfs_create_group创建多组操作函数
2、编写读写函数并通过DEVICE_ATTR宏进行声明,将函数组织为struct attribute,多组struct attribute组织为struct attribute_group并作为刚刚sysfs函数的参数
3、用户空间不需要通过open/read/write方法,而只需要通过echo/cat对/sys/class/设备名称目录下的刚刚定义的函数进行读写就可以了
四:将驱动注册为regmap,在对应的读写函数中使用regmap的读写方法
regmap是内核3.1之后加入的特性,用于减少慢速I/O驱动上的重复逻辑,可以使驱动代码量减少。
这种方法个人觉得最大的好处是那些既支持I2C又支持SPI的设备,而在实际使用中只会使用其中一种接口,所以公共部分的读写函数不再通过i2c_transfer或者spi_sync_transfer这些特定于具体总线的操作函数,而是通过regmap提供的regmap_read/regmap_write公共函数,此函数会根据之前设备的注册自动选择为是I2C或是SPI的操作,所以我们需要做的就是:
1、通过module_i2c_driver或是module_spi_driver注册设备,内核会根据i2c_borad_info或者spi_board_info或者设备树中设备所挂载在的总线自动进行I2C或者SPI的probe操作
2、在I2C的probe函数中通过devm_regmap_init_i2c,在SPI的probe函数中通过devm_regmap_init_spi将设备注册为regmap的对应接口,函数的第二个参数为regmap_config结构,指示了寄存器宽度和数据宽度
3、可通过上方的二方法将设备注册为字符设备或三方法在/sys目录下创建对应的操作函数
4、在操作函数的实现中只需要通过regmap_read/regmap_write对数据进行处理就可以了
欢迎补充!
总结:linux驱动之I2C至少四种读写方法相关推荐
- linux驱动开发篇(四)—— platform平台设备驱动
linux系列目录: linux基础篇(一)--GCC和Makefile编译过程 linux基础篇(二)--静态和动态链接 ARM裸机篇(一)--i.MX6ULL介绍 ARM裸机篇(二)--i.MX6 ...
- Linux C++多线程同步的四种方式
目录 一.互斥锁 二.条件变量 三.读写锁 原文链接:Linux C++多线程同步的四种方式(非常详细)_Y先森0.0-CSDN博客 背景问题:在特定的应用场景下,多线程不进行同步会造成什么问题? 通 ...
- photon四种同步方式_【Linux】多线程同步的四种方式
背景问题:在特定的应用场景下,多线程不进行同步会造成什么问题? 通过多线程模拟多窗口售票为例: #include #include#include#include#include#include us ...
- 更改Linux系统的Hostname的四种方式
更改Linux系统的Hostname的四种方式 通常我们会在安装过程中设置系统的主机名 hostname.许多人不关心这一点,并且不更改主机名,即使例如安装系统的数据中心设置为非常愚蠢的东西(很可能他 ...
- Linux配置网络信息(四种方法)
Linux配置网络信息(四种方法) 临时配置IP地址(2种方式) 1.ifconfig命令 语法: ifconfig <以太网接口> <IP地址> netmask <掩码 ...
- 总结Linux修改主机名的四种方式
总结Linux修改主机名的四种方式 看网上很多文章,有些比较简洁,但是有些很繁琐,不多说,参考各路大神的文章,以下是本人对这几种方式进行简要介绍,如有不足之处,还望各位大佬指点迷津. 方式一(个人推荐 ...
- 一些计算机u口无法使用的原因,USB设备无法使用故障四种排除方法
当你想用闪存或移动硬盘来和电脑交换数据时,但插上USB口时你却发现系统居然无法识别出USB设备,这是什么原因造成的呢?其实这样的现象我们时常见到,接下来介绍一下简单的处理方法. 一.在排除USB存储设 ...
- 51单片机有几个通用io口_51单片机IO口的四种使用方法
原标题:51单片机IO口的四种使用方法 传统51单片机IO接口只可以作为标准双向IO接口,如果用其来驱动LED只能用灌电流的方式或是用三极管外扩驱动电路. 灌电流方式 LED正极接VCC,负极接IO口 ...
- 计算机无法连接无线信号,win7系统连接无线信号时提示Windows无法连接到路由器名称的四种解决方法...
现如今网络发展速度非常快,无线网络已经普及了,使用率高了遇到的问题也就多了.比如有时候笔记本win7系统连接无线信号时出现"Windows无法连接到路由器名称"(如下图所示),该如 ...
最新文章
- tensorflow 的输入层和输出层维度注意事项
- 智能车竞赛技术报告 | 智能车视觉 - 天津大学 - 北洋钽星
- Install vsftpd on centos
- SpringBoot中整合Quartz
- java arraylist 字符串_Java ArrayList、string、string[]之间的转换
- dj鲜生-07-静态文件的成功加载-用户注册的页面
- 安卓模拟器切换横屏之后怎么返回竖屏
- 微软希望通过监控开发者结束软件 bug
- 财子说丨王国斌:相信时间的力量
- 自动驾驶中的多种卡尔曼滤波算法及推导详解,值得一读!
- HMC5883L校准
- [VOT7](2022CVPR) GTELT:Global Tracking via Ensemble of Local Trackers
- charles + 雷电模拟器4进行手机抓包
- SQL两表关联查询(两表会了,三表,四表都小意思)
- Docker 入门看这一篇就够了,万字详解!
- 【高等代数】第一章:多项式部分【1】
- 阿里云code和git管理项目
- pythondjango的用途_django框架的作用是什么
- printf() 常见打印类型
- 雪球(Snow Ball)定价实作:使用Heston模型与GPU加速运算