Linux下Camera驱动的结构
Camera 驱动的结构和一般其他的驱动稍有不同。其他的驱动接口都比较单一,比如USB接口的,PCI接口的等,这些驱动在初始化阶段通过probe方法获得相关寄存器的访问地址,之后参照datasheet进行寄存器配置,再结合Linux系统的中断机制和数据传输机制(DMA和MMAP),进行数据处理即可。
Camera驱动稍有不同,从驱动的角度看Camera本身存在两种接口形式,分别是CSI接口和I2C接口,前者用于Camera感光器件数据本身的传输,后者用于控制数据的传输(曝光时间设置,图像大小设置,白平衡设置等等)。所以在初次查看Camera驱动源码时,会发现大部分摄像头(比如OV系列的)的驱动都仅仅是一些关于I2C操作的接口封装,提供的都是 设置图像格式,设置 白平衡等等的一些接口,并不见摄像头感光器件本身数据传输的相关代码。
物理摄像头本身的接口是标准的(包含CSI,I2C),所以Camera驱动大体的架构如上图所示。
不同的摄像头,驱动开发人员主要关注的是Cam部分(即具体摄像头的控制接口部分,I2C,SPI等),因为不同的摄像头,设置白平衡等功能的方式(I2C或SPI等)可能不一样,比如设置白平衡的寄存器地址以及控制位可能不一样,所以会根据摄像头的型号不同,会有一系列的Cam驱动源码,这些驱动源码按照V4L2的Subdev规范进行管理,即V4L2抽象层会按照规范调用不同Cam注册的摄像头的具体的设置方法(比如设置尺寸,白平衡,曝光时间等)。
CSI部分是由平台部分来实现的,平台(即CPU)一旦确定这部分的驱动代码就基本确定,这部分的代码主要的职责是 按照平台内的CSI控制器的特点,完成CSI控制寄存器的配置,和CSI中断服务例程的实现以及具体数据传输(内存分配,DMA数据传输等)的实现。
在CSI部分的代码里,会按照Subdev的接口规范调用注册的不同的Cam实现的控制具体摄像头的接口(加电,设置白平衡,设置曝光时间等)。
以上是摄像头驱动的基本结构简介,其具体的数据传输和中断处理和其他驱动程序没有本质差别。