Linux I2C总线框架 学习笔记
来源:互联网 发布:cern数据 编辑:程序博客网 时间:2024/06/07 00:35
【I2C框架结构】
Linux 内核中的 I2C 框架分为 3 部分,分别是 Core、Bus Driver、DeviceDriver 。其中 Core 部分是框架中的框架,会调用 Bus Driver 和 Device Driver 中的函数和结构体进行 I2C 注册、数据读写。我将其整理成为下面这张框图(按下 ctrl+鼠标滚轴 可放大图片):
【驱动编写的主要工作】
I2C 框架里需要我们完善的内容存在于 Bus Driver 和 Device Driver 中,我将其分为 2 部分——接口结构体、接口函数。
先来看结构体。根据设备的不同我们需要定义包含不同内容的 adapter 结构体、client结构体、driver 结构体、algorithm 结构体。一个adapter结构体可以用于注册多个 client结构体,这些 client结构体都存储在 adapter结构体的 clients链表中。adapter结构体的定义如下:
struct i2c_adapter { struct module *owner; unsigned int id; unsigned int class; const struct i2c_algorithm *algo; // i2c 时序实现算法 void *algo_data; // 私有数据,包含要收发的消息 *msg int(*client_register)(struct i2c_client *); // 用于注册 client int (*client_unregister)(struct i2c_client *); /* data fields that are valid for all devices */ u8 level; struct mutex bus_lock; struct mutex clist_lock; int timeout; /* in jiffies*/ int retries; struct device dev; /* the adapter device */ int nr; // 适配器的个数 struct list_head clients; //client链表头 char name[48]; // 适配器名称 struct completion dev_released; // 用于同步};
client结构体定义如下:
struct i2c_client { unsigned int flags; /* 标志 */ unsigned short addr; /* 低 7 位为芯片地址 */ struct i2c_adapter *adapter; /*依附的 i2c_adapter*/ struct i2c_driver *driver; /*依附的 i2c_driver*/ struct device dev; /* 设备结构体 */ char name[I2C_NAME_SIZE]; /* 设备名称 */ struct completion released; /* 用于同步 */};
i2c_msg结构体定义如下:
struct i2c_msg { __u16 addr; // 设备地址 __u16 flags; // 读/写标志 __u16 len; // 消息长度 __u8 *buf; // 消息数据};
再来看在上述的接口结构体中存在的众多接口函数,她们也需要我们根据具体情况实现。这些待实现的接口函数有 (*master_xfer)、(*probe)、(*remove) 等。如下:
struct i2c_algorithm { int(*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data * data); u32 (*functionality) (struct i2c_adapter *);/*返回适配器支持的功能*/}; struct i2c_driver { int id; unsigned int class; int (*attach_adapter)(struct i2c_adapter *); /* 依附i2c_adapter函数指针 */ int (*detach_adapter)(struct i2c_adapter *); /* 脱离i2c_adapter函数指针 */ int (*detach_client)(struct i2c_client *); /* i2c client脱离函数指针 */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); /* driver model interfaces that don't relate to enumeration */ void (*shutdown)(struct i2c_client *); int (*suspend)(struct i2c_client *, pm_message_t mesg); int (*resume)(struct i2c_client *); int (*command)(struct i2c_client *client,unsigned int cmd, void*arg); /* 类似ioctl */ struct device_driver driver; /* 设备驱动结构体 */ struct list_headlist; /* 链表头 */};
以上就是需要我们在自己的驱动里主要编写的内容。按照 Linux I2C 的框架,我们将这些内容分别写到 2 个驱动模块中,即 Bus Driver 模块和 Device Driver 模块。
【I2C驱动调用流程】
驱动加载时,从模块入口函数开始执行。2 个模块的加载/卸载函数与其余各部分的关系如上文框图所示,其形式类似下方代码:
static int __init i2c_adapter_xxx_init(){ xxx_adapter_hw_init(); // 硬件相关初始化,如申请I/O地址、中断号等 i2c_add_adapter(&xxx_adapter); // 添加实际情况需要的 xxx_adapter …} static void __exit i2c_adapter_xxx_exit(){ xxx_adapter_hw_free(); i2c_del_adapter(&xxx_adapter);} static struct i2c_driver device_xxx_driver= { .driver = { .name = “device_xxx”, // 为各设备填充 driver 结构体 } .probe =device_xxx_probe, .remove =device_xxx_remove, .id_table =device_xxx_id,}; static int __init device_xxx_init(){ return i2c_add_driver(&device_xxx_driver); // 为设备添加 driver 结构体,有几个设备就要添加几个 driver} static void __exit device_xxx_exit(){ i2c_del_driver(&device_xxx_driver);}
之后的 I2C 操作,如设备注册、数据读写等,将按照以上各结构体中关联的函数相应进行。
- Linux I2C总线框架 学习笔记
- 学习笔记 --- LINUX I2C总线驱动框架分析
- I2C总线学习笔记
- I2C 总线规范学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- I2C总线协议学习笔记
- Linux I2C框架学习
- 学习笔记 --- LINUX USB总线驱动框架分析
- Linux I2C 总线浅析
- Linux I2C总线驱动程序
- Spring系列之事务处理
- 面向对象和面向过程的区别
- Unity自学之Update()、FixedUpdate()、LateUpdate()
- 985的数字难题
- 代理模式C++实现
- Linux I2C总线框架 学习笔记
- 串连接
- 离线安装cocoapods环境教程
- Python基础进阶1
- 【面试题】停车场记录
- 算法
- 从RGB色转为灰度色算法(转)
- POJ 1113 Wall (凸包问题) .
- <sdut-ACM> 数据结构上机测试1:顺序表的应用