目录
- 驱动目录
- sample中相关部分分析
- 海思中的sensor驱动框架
- sensor_register_callback详细分析
驱动目录
在SDK的
\Hi3518E_SDK_V1.0.3.0\package\mpp\ko
底下
hi3518e_isp.ko是isp相关部分驱动
sensor部分的源码在
\Hi3518E_SDK_V1.0.3.0\package\mpp\component\isp\sensor
中
可以通过Makefile看到编译出来的驱动
编出来的驱动放到了lib目录中
sample中相关部分分析
系统一开始进行内存分配、mpp初始化,等操作,做完之后就开始进入vi部分
vi部分的第一步就是配置sensor的接口
在VI开始的时候,会根据sensor的名字进行配置mipi,如果是mipi接口就配置mipi,不是就配置为空
接口配置完之后,就是isp的初始化
SAMPLE_COMM_ISP_Init
这个callback就是在驱动里面,sensor驱动里的所有函数就是通过这个函数和应用层关联起来的
这里要注意的是,这里的sensor驱动不是内核驱动,是应用层驱动。
真正的内核不是lib是ko,使用insmod进行安装,这才是真正工作在内核态的。
这里使用的是应用层驱动,好处是灵活。比如这里sensor改了,是不用去重新编译烧录内核的,只需要将新的sensor对于的.a和.so编译一下,再链接进去运行就可以了,不用动内核。
应用层驱动的坏处是很容易被替换,所以不稳定性是有的,本身的效率与纯内核层的驱动相比效率没有那么高。
应用层驱动一定是基于一个工作在内核层的驱动的,而不是自己去操作对应的寄存器,这里的内核层驱动就指的就是I2C驱动。
从
sensor_register_callback
进去ar0130的应用层驱动
后两段是3A算法中的AE和AW
关键的是第一个配置AR0130的寄存器
cmos_init_sensor_exp_function
以内部第一个函数
sensor_init
为例,里面是sensor支持的两种原始尺寸
以
sensor_init_720p_30fps
为例
有非常多配置寄存器的操作,那怎么写呢,肯定是通过I2C总线
追入
sensor_write_register
,看到内部有一个编译选项
#ifdef HI_GPIO_I2C
海思定义了两种I2C,一种是硬件I2C,一种是软件GPIO模拟I2C
追入
sensor_i2c_init
函数,可以看到
内核里实现了一个驱动,叫
i2c-0
,是海思将硬件上的i2c-0硬件接口封装出来的。它是一个总线驱动,工作在内核态,实际不同的sensor应用层驱动,就是调用的这一个驱动进行硬件的去写。
所以sensor驱动中,没有i2c底层操作,只有i2c层次的操作,即只管往i2c发的东西,不管它是怎么发的。
海思中的sensor驱动框架
mpp中定义了一套sensor驱动的实现和封装(应用层驱动)
每一个sensor的应用层驱动包含两个文件
- xxxx_cmos.c中定义回调和上层函数(面向功能)
- xxxx_sensor_ctl.c中定义底层硬件相关的寄存器值配置函数(底层)
kernel中的I2C驱动提供I2C层面的物理层操作接口,只关心I2C中的值如何传输
sensor_register_callback详细分析
sensor_register_callback
就是应用层和底层交互的函数接口。
函数主要做了回调的绑定,就是实现设计好了一套框架,别人把这套框架及函数名订好了,而且函数已经调用了。只是在注册的时候提供函数的一个实体
sensor驱动就是注册方,也就是在我们的mpp中,规定好了sensor实现的功能,将sensor的所有行为订好了,并有相应的函数和这个行为做对应。sensor驱动提供sensor行为的具体方法。
sensor_register_callback
就是sensor驱动为mpp提供回调函数实现的实体。
HI_MPI_ISP_SensorRegCallBack
就是典型的用来注册sensor的函数,有三个参数
-
IspDev
海思VI中的一个单元,规定了sensor的行为
-
AR0130_ID
海思给每一个sensor规定了一个唯一的编码,用于区分不同sensor,也做预留,将来可以通过这个编号来某些东西
-
&stAeRegister
是最关键的数据结构,在isp中定义的有关sensor的一套操作全在这里,每一个操作对应一个函数去执行。它为isp预留了很多函数指针,isp要做什么操作只需要去调用对应的函数指针即可。如下图
每一种sensor具体的驱动,负责将这些函数指针和具体的函数挂接起来。
以第一个
为例,sensor的应用层驱动就会有一个函数和它对应HI_VOID(*pfn_cmos_sensor_init)(HI_VOID);
底下有ISP相关配置,注意这里不是海思VI中的ISP,是sensor内部的ISP。大部分sensor内部有一个简单的ISP。
&stAeRegister
在
cmos_init_sensor_exp_function
中填充,将其内部的函数指针和sensor的应用层驱动的函数相接。
进入
sensor_init
这里就是在设置
sensor
的寄存器,通过底层的i2c驱动和硬件进行交互。
除了sensor的配置,底下还有两个结构相似的配置,是AE(自动曝光)和AWB(自动白平衡),分别对应了不同的功能,结构是一模一样的。
可以看到没有AF(自动对焦),因为sensor不支持AF功能