首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
python
filter
integer
chat
express
php5
hashcode
dagger
vba
tree
list
datetime
char
cPlusPlus
go
split
join
replace
shell
metadata
web
get
schema
keyword
timezone
lua
install
const
cookie
default
include
loops
sum
stream
web3
php
header
runtime
merge
object
regex
dll
int
java
nodejs
php8
testing
cpython
version
golang
substring
actionscrip
foreach
yaml
uml
bitmap
timestamp
subset
expression
require
hash
perl
range
controller
byte
instance
match
node.js
utf-8
select
main
process
jsp
blob
rsa
ip
config
python3
eval
当前位置:
开发笔记
>
编程语言
> 正文
LinuxI2C几个结构体间的关系以及对于一个I2C设备的移植,我们需要做些什么工作
作者:虔州小小编_590 | 来源:互联网 | 2023-10-16 17:40
在Linux内核源代码中的drivers目录下包含一个i2c目录,而在i2c目录下又包含如下文件和文件夹:•i2c-core.c这个文件实现了I2C核心的功能以及proc
在Linux内核源代码中的drivers目录下包含一个i2c目录,而在i2c目录下又包含如下文件和文件夹:
• i2c-core.c
这个文件实现了I2C核心的功能以及/proc/bus/i2c*接口。
• i2c-dev.c
实 现了I2C适配器设备文件的功能,每一个I2C适配器都被分配一个设备。通过适配器访问设备时的主设备号都为89,次设备号为0~255。应用程序通过 “i2c-%d” (i2c-0, i2c-1, ..., i2c-10, ...)文件名并使用文件操作接口open()、write()、read()、ioctl()和close()等来访问这个设备。
i2c-dev.c并没有针对特定的设备而设计,只是提供了通用的read()、write()和ioctl()等接口,应用层可以借用这些接口访问挂接在适配器上的I2C设备的存储空间或寄存器并控制I2C设备的工作方式。
• chips文件夹
这个目录中包含了一些特定的I2C设备驱动,如Dallas公司的DS1337实时钟芯片、EPSON公司的RTC8564实时钟芯片和I2C接口的EEPROM驱动等。
• busses文件夹
这个文件中包含了一些I2C总线的驱动,如S3C2410的I2C控制器驱动为i2c-s3c2410.c。
• algos文件夹
实现了一些I2C总线适配器的algorithm。
此外,内核中的i2c.h这个头文件对i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这4个数据结构进行了定义。理解这4个结构体的作用十分关键,代码清单15.1、15.2、15.3、15.4分别给出了它们的定义。
代码清单15.1 i2c_adapter结构体
1 struct i2c_adapter {
2 struct module *owner;/*所属模块*/
3 unsigned int id; /*algorithm的类型,定义于i2c-id.h,以I2C_ALGO_开始*/
4 unsigned int class;
5 struct i2c_algorithm *algo;/*总线通信方法结构体指针 */
6 void *algo_data; /* algorithm数据 */
7 int (*client_register)(struct i2c_client *); /*client注册时调用*/
8 int (*client_unregister)(struct i2c_client *); /*client注销时调用*/
9 struct semaphore bus_lock; /*控制并发访问的自旋锁*/
10 struct semaphore clist_lock;
11 int timeout;
12 int retries; /*重试次数*/
13 struct device dev; /* 适配器设备 */
14 struct class_device class_dev; /* 类设备 */
15 int nr;
16 struct list_head clients; /* client链表头*/
17 struct list_head list;
18 char name[I2C_NAME_SIZE]; /*适配器名称*/
19 struct completion dev_released; /*用于同步*/
20 struct completion class_dev_released;
21};
代码清单15.2 i2c_algorithm结构体
1 struct i2c_algorithm {
2 int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs,
3 int num); /*i2c传输函数指针*/
4 int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, /*smbus传输函数指针*/
5 unsigned short flags, char read_write,
6 u8 command, int size, union i2c_smbus_data * data);
7 int (*slave_send)(struct i2c_adapter *,char*,int);/*当i2c适配器为slave时,发送函数*/
8 int (*slave_recv)(struct i2c_adapter *,char*,int); /*当i2c适配器为slave时,接收函数*/
9 int (*algo_control)(struct i2c_adapter *, unsigned int, unsigned long); /*类似ioctl*/
10 u32 (*functionality) (struct i2c_adapter *);/*返回适配器支持的功能*/
11 };
上述代码第4行对应为SMBus传输函数指针,SMBus大部分基于I2C总线规范,SMBus不需增加额外引脚。与I2C总线相比,SMBus增加了一些新的功能特性,在访问时序也有一定的差异。
代码清单15.3 i2c_driver结构体
1 struct i2c_driver {
2 int id;
3 unsigned int class;
4 int (*attach_adapter)(struct i2c_adapter *); /*依附i2c_adapter函数指针 */
5 int (*detach_adapter)(struct i2c_adapter *); /*脱离i2c_adapter函数指针*/
6 int (*detach_client)(struct i2c_client *); /*i2c client脱离函数指针*/
7 int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); /*类似ioctl*/
8 struct device_driver driver; /*设备驱动结构体*/
9 struct list_head list; /*链表头*/
10 };
代码清单15.4 i2c_client结构体
1 struct i2c_client {
2 unsigned int flags; /* 标志 */
3 unsigned short addr; /* 低7位为芯片地址 */
4 struct i2c_adapter *adapter; /*依附的i2c_adapter*/
5 struct i2c_driver *driver; /*依附的i2c_driver */
6 int usage_count; /* 访问计数 */
7 struct device dev; /* 设备结构体 */
8 struct list_head list; /* 链表头 */
9 char name[I2C_NAME_SIZE]; /* 设备名称 */
10 struct completion released; /* 用于同步 */
11 };
下面分析一下i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这4个数据结构的作用及其盘根错节的关系。
• i2c_adapter与i2c_algorithm
i2c_adapter 对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个I2C适配器需要i2c_algorithm中提供的通信函数来控制适配 器上产生特定的访问周期。缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含其使用的 i2c_algorithm的指针。
i2c_algorithm中的关键函数master_xfer()用于产生I2C访问周期需要的信号,以i2c_msg(即I2C消息)为单位。i2c_msg结构体也非常关键,代码清单15.5给出了它的定义。
代码清单15.5 i2c_msg结构体
1 struct i2c_msg {
2 __u16 addr; /* 设备地址*/
3 __u16 flags; /* 标志 */
4 __u16 len; /* 消息长度*/
5 __u8 *buf; /* 消息数据*/
6 };
• i2c_driver与i2c_client
i2c_driver对应一套驱动方法,是纯粹的用于辅助作用的数据结构,它不对应于任何的物理实体。i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述。i2c_client一般被包含在i2c字符设备的私有信息结构体中。
i2c_driver 与i2c_client发生关联的时刻在i2c_driver的attach_adapter()函数被运行时。attach_adapter()会探测 物理设备,当确定一个client存在时,把该client使用的i2c_client数据结构的adapter指针指向对应的i2c_adapter, driver指针指向该i2c_driver,并会调用i2c_adapter的client_register()函数。相反的过程发生在 i2c_driver 的detach_client()函数被调用的时候。
• i2c_adpater与i2c_client
i2c_adpater 与i2c_client的关系与I2C硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adpater。由于一个适配器上可以连 接多个I2C设备,所以一个i2c_adpater也可以被多个i2c_client依附,i2c_adpater中包括依附于它的i2c_client 的链表。
假设I2C总线适配器xxx上有两个使用相同驱动程序的yyy I2C设备,在打开该I2C总线的设备结点后相关数据结构之间的逻辑组织关系将如图15.2所示。
图
15.2 I
2
C
驱动各数据结构关系
图15.2 I2C驱动各数据结构关系
从上面的分析可知,虽然I2C硬件体系结构比较简单,但是I2C体系结构在Linux中的实现却相当复杂。当工程师拿到实际的电路板,面对复杂的 Linux I2C子系统,应该如何下手写驱动呢?究竟有哪些是需要亲自做的,哪些是内核已经提供的呢?理清这个问题非常有意义,可以使我们面对具体问题时迅速地抓住 重点。
一方面,适配器驱动可能是Linux内核本身还不包含的。另一方面,挂接在适配器上的具体设备驱动可能也是Linux不存在的。即便上述设备驱动都存在于Linux内核中,其基于的平台也可能与我们的电路板不一样。因此,工程师要实现的主要工作将包括:
• 提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。
• 提供I2C适配器的algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。
• 实现I2C设备驱动与i2c_driver接口,用具体设备yyy的yyy_attach_adapter()函数指针、 yyy_detach_client()函数指针和yyy_command()函数指针的赋值给i2c_driver的attach_adapter、 detach_adapter和detach_client指针。
• 实现I2C设备驱动的文件操作接口,即实现具体设备yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等。
上述工作中1、2属于I2C总线驱动,3、4属于I2C设备驱动,做完这些工作,系统会增加两个内核模块。本章第3~4节将详细分析这些工作的实施方法,给出设计模板,而5~6节将给出两个具体的实例。
linux
文件
io
ip
go
client
struct
int
并发
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
get
远程访问用户 Kindle通过电子书实现控制
介绍自2007年以来,亚马逊已售出数千万台Kindle,令人印象深刻。但这也意味着数以千万计的人可能会因为这些Kindle中的软件漏洞而被黑客入侵。他 ...
[详细]
蜡笔小新 2024-11-29 07:58:24
const
理解System V与POSIX在Linux中的应用
本文旨在探讨Linux系统中两种重要的进程间通信(IPC)机制——System V和POSIX的标准及其特性,为开发者提供深入的理解。 ...
[详细]
蜡笔小新 2024-11-29 18:47:58
web
PHP 中 Application 对象的使用与管理
本文探讨了如何利用 Application 对象在 PHP 应用程序中共享数据,特别是在多用户环境中保持数据的一致性和安全性。文章还介绍了 Application 对象的基本结构、方法和事件,并提供了实际应用示例。 ...
[详细]
蜡笔小新 2024-11-29 15:34:01
default
优化Nginx中PHP-FPM模块配置以提升性能
通过调整Nginx与PHP-FPM之间的配置,可以显著提高Web服务器处理PHP请求的速度和效率。本文将详细介绍如何针对不同的应用场景优化PHP-FPM的各项关键参数。 ...
[详细]
蜡笔小新 2024-11-29 11:28:39
default
解决Python中Crypto.Cipher模块ImportError问题
本文详细探讨了在Python开发中遇到的ImportError: 无法找到名为Crypto.Cipher的模块的问题,并提供了多种解决方案,包括环境配置、库安装和代码调整等方法。 ...
[详细]
蜡笔小新 2024-11-29 20:01:52
install
利用手机连接和管理Linux树莓派
树莓派(简称RPI)通常需要配合电脑使用,但对于某些用户或特定场合,手机作为主要携带设备,能够直接用于配置和管理RPI,这具有重要的实用价值。 ...
[详细]
蜡笔小新 2024-11-29 14:50:14
default
如何使用JavaScript获取绑定到DropDownList的ID值
本文探讨了在JavaScript中如何有效地从服务器控件DropDownList中获取绑定的ID值,而非仅仅是显示的文本值。这对于需要根据用户选择动态处理数据的应用场景非常有用。 ...
[详细]
蜡笔小新 2024-11-29 13:19:37
get
2023年PHP处理请求超时的全面指南
本文详细介绍了在PHP中处理请求超时的各种方法,包括设置脚本执行时间、处理file_get_contents函数超时以及优化AJAX请求等,适合开发者参考学习。 ...
[详细]
蜡笔小新 2024-11-29 12:55:50
shell
ANSI最全介绍linux终端字体改变颜色等
ANSI最全介绍linux终端字体改变颜色等ANSI转义序列维基百科,自由的百科全书由于国内不能访问wiki而且国内关于ANSI的介绍都是简短的不能达到,不够完整所以转wiki到此 ...
[详细]
蜡笔小新 2024-11-29 12:47:14
default
oracle怎么打开使用方法,Oracle中打开10046 Trace的各种方法
Oracle中打开10046Trace的各种方法10046trace的跟踪等级10046是一个Oracle的内部事件(event),通过设置这个事件可以得到Oracl ...
[详细]
蜡笔小新 2024-11-29 11:48:47
default
解决EasyRTSPClient与大华球机连接时的预览问题
本文介绍了EasyRTSPClient这一高效、稳定的RTSP客户端工具库,并详细阐述了其在与大华球机对接过程中遇到的预览问题及解决方法。 ...
[详细]
蜡笔小新 2024-11-29 08:38:47
install
深入理解SAP Fiori及其核心概念
本文详细介绍了SAP Fiori的基本概念、发展历程、核心特性、应用类型、运行环境以及开发工具等,旨在帮助读者全面了解SAP Fiori的技术框架和应用场景。 ...
[详细]
蜡笔小新 2024-11-28 22:05:47
install
解决 ClickOnce 部署时自动更新功能失效的问题
本文探讨了在使用 ClickOnce 部署方式时遇到的自动更新失败问题,包括本地安装与服务器安装的不同表现,并提供了详细的解决方案。 ...
[详细]
蜡笔小新 2024-11-28 17:00:42
char
如何在Ubuntu Linux系统上安装PyCharm编辑器
本文探讨了为何在Linux系统上进行项目开发的重要性,并详细介绍了如何在Ubuntu系统上安装PyCharm这一流行的Python集成开发环境(IDE)。通过本文,您将了解在Linux环境下进行Python开发的优势及具体安装步骤。 ...
[详细]
蜡笔小新 2024-11-28 10:27:34
default
利用Linux服务器构建简单路由器
本文介绍如何通过配置Linux服务器作为路由器来实现两个不同网段(192.168.1.0/24 和 192.168.2.0/24)之间的互联互通。 ...
[详细]
蜡笔小新 2024-11-27 20:39:27
虔州小小编_590
这个家伙很懒,什么也没留下!
Tags | 热门标签
python
filter
integer
chat
express
php5
hashcode
dagger
vba
tree
list
datetime
char
cPlusPlus
go
split
join
replace
shell
metadata
web
get
schema
keyword
timezone
lua
install
const
cookie
default
RankList | 热门文章
1
git 一个分支完全替换另一个分支
2
amd_xata.sys 无法验证此文件的数字签名
3
win10系统无法使用git,报错/dev/null找不到
4
在PS里盖印图层在哪个菜单里 在PS里盖印图层怎么找
5
新萝卜家园win7系统安装教程光盘
6
git diff 两个分支的差别,并生成patch
7
为什么我将位图信息头结构中的biHeight设成负值,想将DIB拷贝到剪贴板时显示正向图像
8
webstorm如何汉化
9
仅在分割模式github/git中复制添加更改
10
公开课 | 比MobileNet更高效,微软资深研究员详解基于交错组卷积的高效DNN
11
不用光盘和u盘怎么重装系统win10 无光盘无u盘重装系统
12
/etc/passwd 文件不小心删除了,机器重启起不来
13
如何有效管理自己电脑里的文件
14
windows10、Win95面对面:二十年光景缩影?
15
电脑屏幕如何调亮度win7
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有