嵌入式实践教程--【Linux驱动】Linux驱动开发基于Linux4.0+(六)I2C总线驱动

简介: 嵌入式实践教程--【Linux驱动】Linux驱动开发基于Linux4.0+(六)I2C总线驱动

I2C总线经常挂载eeprom、温度传感器、湿度传感器等设备。I2C总线下可以挂载多个设备,识别设备采用一个地址,这个地址在一条i2c总线是独一无二的。I2C总线驱动与spi总线驱动框架是一致的,都是采用控制器、core、设备三层驱动。


内核中I2C 的处理已经做好了,我们只需要做设备驱动程序相关的内容。总线处理好了I2C 协议,即总线知道如何收发数据,而不知道数据的含义,我们要做的只是设备相关层的代码。


I2C 协议中,先发出7bit“设备地址”,然后是1 位“写”或“读”的标志位。然后接着是每发出8 位数据有一个ACK 位。


一般I2C 驱动分为两层:


总线层:知道设备如何读写。芯片厂家会帮我们做好,操作寄存器。

设备驱动层:知道数据的含义。


一、4个数据结构的作用及区别



1、i2c_adapter和i2c_algorithm


i2c_adapter:对应于物理上的适配器

i2c_algorithm:对应于一套通信方法


缺少了i2c_algorithm的i2c_adapter什么也做不了。


i2c_algorithm中的关键函数master_xfer用于产生i2c访问周期所需要的信号,以i2c_msg为单位,i2c_msg非常重要,它包含了i2c的传输地址、方向、缓冲区、缓冲区长度。


2、i2c_driver和i2c_client


i2c_driver:对应一套驱动方法

i2c_client:对应于真实的物理设备


每个i2c设备都需要一个i2c_client来描述。i2c_driver和i2c_client是一对多的关系,一个i2c_driver可以支持多个同类型的i2c_client。


3、i2c_client和i2c_adapter


i2c_client依赖于i2c_adapter,i2c_adapter可以被多个i2c_client依赖。


二、总线驱动



I2C总线控制器通常是在内存上,所以它本身是在platform总线上。使用总线驱动模型,通过platform_driver和platform_device的匹配来执行。


(1)适配器驱动的初始化


在platform_driver的probe函数中完成两个工作:


1、初始化I2C适配器的硬件资源,申请IO、中断号、时钟等;

2、使用i2c_add_adapter()添加i2c_adapter数据结构,并且在此之前i2c_adapter已经被初始化。


static int xxx_i2c_probe(struct platform_device *pdev)
{
  struct i2c_adapter *adap;
  ...
  xxx_adapter_hw_init();
  ,,,
  i2c_add_adapter(adap);
}


在platform_driver的remove函数中完成相反的两个工作。


(2)i2c总线的通信方法


主要是实现i2c_algorithm的functionality和master_xfer函数。


三、设备驱动



1、初始化i2c_driver 和模块的加载和卸载


(同大部分总线驱动一样,不再赘述)


2、数据传输


在i2c设备上读写数据的时序且数据常通过i2c_msg组织,最后由i2c_transfer()发送


struct i2c_msg msg[2];
//第一条是写消息
msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = 1;
msg[0].buf = &offs;
//第二条是读消息
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = sizeof(buf);
msg[1].buf = &buf[0];
i2c_transfer(client->adapter, msg, 2);


更详细示例的参考drivers/i2c/busses/i2c-tegra.c

相关文章
|
3月前
|
NoSQL Linux C语言
嵌入式GDB调试Linux C程序或交叉编译(开发板)
【8月更文挑战第24天】本文档介绍了如何在嵌入式环境下使用GDB调试Linux C程序及进行交叉编译。调试步骤包括:编译程序时加入`-g`选项以生成调试信息;启动GDB并加载程序;设置断点;运行程序至断点;单步执行代码;查看变量值;继续执行或退出GDB。对于交叉编译,需安装对应架构的交叉编译工具链,配置编译环境,使用工具链编译程序,并将程序传输到开发板进行调试。过程中可能遇到工具链不匹配等问题,需针对性解决。
101 3
|
3月前
|
传感器 人工智能 网络协议
:嵌入式 Linux 及其用途
【8月更文挑战第24天】
175 0
|
4月前
|
Ubuntu 算法 Linux
嵌入式Linux的学习误区
**嵌入式Linux学习误区摘要** 1. **过度聚焦桌面Linux** - 许多学习者误将大量时间用于精通桌面Linux系统(如RedHat、Fedora、Ubuntu),认为这是嵌入式Linux开发的基石。 - 实际上,桌面Linux仅作为开发工具和环境,目标不应是成为Linux服务器专家,而应专注于嵌入式开发工具和流程。 2. **盲目阅读Linux内核源码** - 初学者在不了解Linux基本知识时试图直接研读内核源码,这往往导致困惑和挫败感。 - 在具备一定嵌入式Linux开发经验后再有针对性地阅读源码,才能有效提升技能。
|
5月前
|
Linux
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
【Linux驱动学习(1)】USB与input子系统,linux统一设备模型,枚举,USB描述符深入剖析
|
2月前
|
Linux 程序员 编译器
Linux内核驱动程序接口 【ChatGPT】
Linux内核驱动程序接口 【ChatGPT】
|
缓存 Linux 虚拟化
戴文的Linux内核专题:03 驱动程序【转】
转自:http://www.lai18.com/content/432194.html 驱动程序是使内核能够沟通和操作硬件或协议(规则和标准)的小程序。没有驱动程序,内核不知道如何与硬件沟通或者处理协议(内核实际上先发送指令给BIOS,然后BIOS传给硬件)。
4333 0