本讲是Camera KMD ISP子系统专题的第3讲,我们讲解Camera KMD驱动V4L2模型之Component 框架的运用第1部分。
更多资源:
资源 | 描述 |
---|---|
在线课程 | 极客笔记在线课程 |
知识星球 | 星球名称:深入浅出Android Camera 星球ID: 17296815 |
极客笔记圈 |
Linux Component架构介绍
为什么要引入Component?
一些subsystem需要由很多组件组成,kernel中的component框架是为了让subsystem能够按照一定的顺序初始化设备而提出的架构。
subsystem中由较多设备模块组成,而内核加载每个模块时间不定。子系统内有些模块是需要依赖其它先初始化才能进行自己初始化工作(例如v4l2 subdev和v4l2 video device),这是就要用到component框架。
component框架代码:
drivers/base/component.c
Linux Component重要数据结构
struct component
用来表示系统组件。
struct component {
struct list_head node;//用于链接到全局component_list中
struct aggregate_device *adev;//保存本组件属于哪个aggregate device
bool bound;//表示本component是否已经bind了
const struct component_ops *ops;//本component的回调接口
int subcomponent;//camera子系统暂时未使用
struct device *dev;//本component属于哪个device
};
struct aggregate_device (master)
表示需要构建的系统。
struct aggregate_device {
struct list_head node;//用于链接到全局aggregate_devices中
bool bound;//表示本aggregate_device是否已经bind了
const struct component_master_ops *ops;// master设备的回调接口
struct device *parent;// 用于记录本aggregate device属于哪个struct device
struct component_match *match;// 按照顺序保存了本aggregate_device的所有component匹配条件
};
struct component_match
用来匹配系统需要的组件,并规定了组件的初始化顺序
struct component_match {
size_t alloc;//记录分配了多少个struct component_match_array对象
size_t num;//记录保存了多少个component匹配条件
struct component_match_array *compare;//保存了分配好的内存,用于保存component匹配条件
};
Linux Component两个重要的链表
static LIST_HEAD(component_list)
保存整个linux系统中所有添加到component框架里的struct component数据结构。
static LIST_HEAD(aggregate_devices)
保存整个linux系统中所有的struct aggregate_device(master)数据结构。
Linux Component四个重要的API
component_match_add()
添加一个component_match_entry实例,第一个调用这个函数时会创建struct component_match内存
component_master_add_with_match()
- 分配一个aggregate_device(master)对象 ,并且把所有需要match的component绑定到这个aggregate_device。
- 添加aggregate_device(master)对象到全局链表aggregate_devices中
- 检查是否所有属于该master device的所有component都ready,如果ready就调用master的bind回调接口进行初始化
component_add()
- 分配一个component对象并且添加到全局链表component_list中
- 检查系统中每一个master device的所属component是否都ready,如果ready就调用该master的bind回调接口进行初始化
component_bind_all()
遍历一个master设备的所有component,并且顺序调用每个component的bind回调函数进行初始化。