Qualcomm Android camera 架构简析及如何debug

一. Camera模组(CCM)介绍

CCM一般包含四大件: 镜头(lens)、传感器(sensor)、软板(FPC)、图像处理芯片(DSP):

 

 

Camera的成像原理可以简单概括如下

 


1、CCD/CMOS将被摄体的光信号转变为电信号—电子图像(模拟信号) 
2、由模/数转换器(ADC)芯片来将模拟信号转化为数字信号 
3、数字信号形成后,由DSP或编码库对信号进行压缩并转化为特定的图像文件格式储存

4. 送到cpu中处理并display。

 



二. 电路图


 

 

1. 电源

--dvdd,iovdd,avdd。

2. I2c

由于I2C接口采用OpenDrain机制,器件本身只能输出低电平,无法主动输出高电平,只能通过外部上拉电阻RP将信号线拉至高电平。因此I2C总线上必须有上拉电阻!

阻值:I2C的上拉电阻可以是1.5K,2.2K,4.7K, 电阻的大小对时序有一定影响,对信号的上升时间和下降时间也有影响,一般接1.5K或2.2K。不能低于1k。高于10k。

过小的话灌入端口的电流变大,低电平变高。过大上升平缓。

通产情况下,SDA,SCL两条线上的上拉电阻取值是一致的,并上拉到同一电源上。

    在I2c总线可以串连300欧姆电阻RS可以用于防止SDA和SCL线的高电压毛刺.

3. Mipi

    而DDR是一个时钟周期内传输两次次数据,它能够在时钟的上升期和下降期各传输一次数据,因此称为双倍速率同步动态随机存储器

MIPI的通道模式和线上电平。在正常的操作模式下,数据通道处于高速模式或者控制模式。在高速模式下,通道状态是差分的0或者1,也就是线对内P比N高时,定义为1,P比N低时,定义为0,高低速分别200MV,1.2V.

控制模式:LP11,LP10,LP01,LP00四个状态;MIPI协议规定控制模式4个不同状态组成的不同时序代表着将要进入或者退出高速模式等;比如LP11-LP01-LP00序列后,进入高速模式。下图为线上电平的图示

MIN [ Settle count * T(Timer clock)] > T(HS_SETTLE)_MIN

MAX [ Settle count * T(Timer clock)] < T(HS-PREPARE)+T(HS_ZERO) - 4*T(Timer clock)

 

 

三.AndroidCamera框架简析



 

 

Android框架看,分为四层:应用层、应用框架层、库层、内核层。

库层是Android与底层硬件通信接口,它封装底层硬件接口实现该模块的具体逻辑,并以服务的形式通过Binder通讯机制暴露给应用框架

 

 

1.camera应用层

2.Framework.Camera client/service

3.硬件抽象层HAL Hardware Abstraction Layer

 

 

 


1.1、camera应用层

Camera 的应用层在Android 上表现为直接调用SDK API 开发的一个Camera 应用APK 包。主要对 android.hardware.Camera(在Framework中) 类的调用,并且实现Camera 应用的业务逻辑和UI 显示。

使用这个android.hardware.Camera类,需要在Manifest 文件声明Camera 的权限,另外还 需要添加一些<uses-feature> 元素来声明应用中的Camera 特性。

<uses-feature android:name = "android.hardware.camera" />

......

<uses-feature android:name = "android.hardware.camera.autofocus" />

 

1.2、Framework层

1.android.hardware.Camera封装类

/frameworks/base/core/Java/android/hardware/Camera.java

这是Android 提供给app层调用的java接口。这个类用来连接或断开一个Camera 服务,设置拍摄参数,预览,拍照等。作为Android SDK Camera部分提供给上层应用,并通过JNI的方式调用本地C++代码。

Camera的Java native调用部分(JNI):/android/frameworks/base/core/jni/android_hardware_Camera.cpp。承接JAVA 代码到C++ 代码的桥梁。

 

1.3.Camera框架的client部分:

代码位置:/android/frameworks/av/camera/ICameraClient.cpp

这部分的内容编译生成libcamera_client.so 。与另外一部分内容服务端libcameraservice.so 通过进程间通讯(即Binder 机制)的方式进行通讯

 

1.4.Camera框架的service部分

代码位置:/android/frameworks/av/camera/ICameraService.cpp

 

这部分内容被编译成库libcameraservice.so 。CameraService 是Camera 服务,Camera 框架的中间层,用于链接CameraHardwareInterface 和Client部分 ,它通过调用实际的Camera 硬件接口来实现功能,即下层HAL层。

 

1.5、硬件抽象层HAL

这层的代码在/android/hardware/qcom/camera, 直接和底层硬件驱动相关的。框架层对下在CameraHardwareInterface.h头文件中定义了Camera硬件抽象层的接口,它是包含纯虚函数的类,必须被实现类继承才能使用。HAL层正好继承CameraHardwareInterface接口,依据V4l2规范实例化底层硬件驱动,使用ioctl方式调用驱动.

 

代码流程:

1、Camera apk----java

2、camera java interface,JNI-----(java—>C++)

3、camera client-----C++

4、camera services----C++

5、HAL----C++

6、camera drv

 

a. 点击Camera 应用后,进入CameraActivity.java,完成初始化,
onCreate 调用setModuleFromIndex 方法,赋值  mCurrentModule = new PhotoModule();


mCameraDevice = CameraUtil.openCamera(
                mActivity, mCameraId, mHandler,
                mActivity.getCameraOpenErrorCallback())
其中mCameraDevice是com.android.camera.CameraManager.CameraProxy;的实例。
    CameraUtil属于公共的API,用于给不同模块提供对Camera的不同操作。
在它openCamera 方法里,执行:
CameraHolder.instance().open(handler, cameraId, cb);
其中CameraHolder.instance()单例模式。目的就是控制,相机开启的只有能是一个。再次开启前,要确认上次已经销毁。


b 在CameraManager系统服务,获得camera设备对象为Camera设备提供操作的方法。

    public CameraProxy cameraOpen(
            Handler handler, int cameraId, CameraOpenErrorCallback callback);

CameraProxy AndroidCameraProxyImpl类这个接口就是将对Camera 接受和发送的操作,送达到Camera设备。

这个接口的实现类是AndroidCameraProxyImpl,这个类属于AndroidCameraManagerImpl的内部类。在AndroidCameraManagerImpl.java 里面还有一个内部类CameraHandler,这个类属于Handler。在CameraHandler的handleMessage方法里,就是根据不同的消息参数来对android.hardware.Camera 进行控制。比如打开,释放,对焦,变焦等等

c. jni

应用里通过CameraProxy对象发送消息给CameraHandler处理,CameraHandler通过android.hardware.Camera的接口去调用JNI层的方法,Camera JNI实现在android_hardware_Camera.cpp里

 

d. Camerahal

     Camera HAL层的接口是通过CameraHardwareInterface类的各个方法给framework调用, CameraHardwareInterface对象在CameraClient里实现,并且CameraClient封装了Camera硬件的各个操作的接口.

Camera.cpp里的每一个Camera的操作方法最后都调用ICamera接口里定义的方法,这个接口被BpCamera继承,BpCamera是binder机制的标准使用方法,他对应的调用类就是BnCamera.

 

e. 为了实现一个具体功能的Camera,在最底层还需要一个硬件相关的Camere 驱动库(例如通过调用video for Linux 驱动程序和Jpeg 编码程序实现)。这个库将被Camera 的服务库libcameraservice.so 调用。  

 

f.Camera内核code

Driver,csid,csiphy..

 

android启动和camera probe


Probe:Server.c->main

 


四.Camera debug:


Sensor log:

 

adb shell setprop persist.camera.hal.debug.mask 536870919

HAL/mm-camera-interface/mm-jpeg-interface CDBG_HIGH() 和CDBG() log都会被打印. CDBG_ERROR() log总是被打印

0-27位决定打印模块(目前只有三个模块):

§Bit0: HAL (hardware/qcom/camera/QCamera2/HAL)

§Bit1: mm-camera-interface (hardware/qcom/camera/QCamera2/stack/mm-camera-interface)

§Bit2: mm-jpeg-interface (hardware/qcom/camera/QCamera2/stack/mm-jpeg-interface)

 

adb shell setprop persist.camera.sensor.debug 3

§   SERR(), SHIGH()和SLOW() log会被打印

 

adb shell setprop persist.camera.imglib.logs 4

§  IDBG_ERROR(), IDBG_HIGH() , IDBG_MED(), IDBG_LOW()都会被打印

 

adb shell setprop persist.camera.pproc.debug.mask 805306375

§805306375 = 0x30000007, 表示PPROC/C2D/CPP模块CDBG_HIGH(), CDBG(), CDBG_LOW() 都会被打印.

  Bit0: PPROC (mm-camera2/media-controller/modules/pproc-new)

§Bit1: C2D (mm-camera2/media-controller/modules/pproc-new/c2d)

§Bit2: CPP (mm-camera2/media-controller/modules/pproc-new/cpp)

 

adb shell setprop persist.camera.mct.debug.mask  536870913

§536870913 = 0x20000001, 表示MCT CDBG_HIGH(), CDBG() 都会被打印.

0-27位决定打印模块(目前只一个模块):

§Bit0: PPROC (mm-camera2/media-controller/mct)

 

adb shell setprop persist.camera.ISP.debug.mask 16777217

§16777217 = 0x1000001, 打开ISP_MOD_COM. ISP_MOD_LINEARIZATIO log

Bit 0: ISP_MOD_LINEARIZATION

Bit 1: ISP_MOD_ROLLOFF

Bit 2: ISP_MOD_DEMUX

Bit 3: ISP_MOD_DEMOSAIC

Bit 4: ISP_MOD_BPC

Bit 5: ISP_MOD_ABF

Bit 6: ISP_MOD_ASF

Bit 7: ISP_MOD_COLOR_CONV

Bit 8: ISP_MOD_COLOR_CORRECT

Bit 9: ISP_MOD_CHROMA_SS

Bit 10: ISP_MOD_CHROMA_SUPPRESS

Bit 11: ISP_MOD_LA

Bit 12: ISP_MOD_MCE

Bit 13: ISP_MOD_SCE

Bit 14: ISP_MOD_CLF

Bit 15: ISP_MOD_WB

Bit 16: ISP_MOD_GAMMA

Bit 17: ISP_MOD_FOV

Bit 18: ISP_MOD_SCALER

Bit 19: ISP_MOD_BCC

Bit 20: ISP_MOD_CLAMP

Bit 21: ISP_MOD_FRAME_SKIP

Bit 22: ISP_MOD_STATS

Bit 23: ISP_MOD_COLOR_XFORM

Bit 24: ISP_MOD_COM

 

adb shell setprop persist.camera.stats.debug.mask 7

§7 = 0b111, 打开AEC/AWB/AF log

Bit 0: STATS_DEBUG_MASK_AEC_LOG

Bit 1: STATS_DEBUG_MASK_AWB_LOG

Bit 2: STATS_DEBUG_MASK_AF_LOG

Bit 3: STATS_DEBUG_MASK_ASD_LOG

Bit 4: STATS_DEBUG_MASK_AFD_LOG

 

MSM8916 Android 5.0 Camera log -HAL

adb shell setprop persist.camera.hal.debug 2

§表示HAL/mm-camera-interface/mm-jpeg-interfaceCDBG_HIGH() 和CDBG() log都会被打印. CDBG_ERROR() log总是被打印

 

adb shell setprop persist.camera.sensor.debug 2

§表示sensor module (mm-camera2/media-controller/modules/sensors)SERR() , SHIGH() 和SLOW() log都会被打印.

 

CPP-log

没有动态开关,需要修改mm-camera2/media-controller/modules/pproc-new/cpp/cpp_log.h里面定义的CPP_LOG_VERBOSE后重新编译

§CPP_LOG_VERBOSE = 0,只有CPP_ERR() log被打印

§CPP_LOG_VERBOSE = 1,CPP_ERR(), CPP_HIGH() log被打印

§CPP_LOG_VERBOSE = 2,CPP_ERR(), CPP_HIGH(), CPP_DBG() log被打印

§CPP_LOG_VERBOSE = 3,CPP_ERR(), CPP_HIGH(), CPP_DBG() , CPP_LOW() log都被打印

§默认CPP_LOG_VERBOSE = 1

 

 

adb shell setprop persist.camera.mct.debug 2

§表示MCT(mm-camera2/media-controller/mct)CDBG_ERROR(), CDBG_HIGH(), CDBG() 都会被打印

 

adb shell setprop persist.camera.stats.debug 2

§打开AEC ERR/HIGH/LOW log, 即AEC_ERR()/AEC_HIGH()/AEC_LOW() log会被打印

Bit 0-1: STATS_DEBUG_MASK_AEC_LOG

§Bit 2-3: STATS_DEBUG_MASK_AWB_LOG

§Bit 4-5: STATS_DEBUG_MASK_AF_LOG

§Bit 6-7: STATS_DEBUG_MASK_ASD_LOG

§Bit 8-9: STATS_DEBUG_MASK_AFD_LOG

§Bit 10-11: STATS_DEBUG_MASK_Q3A_LOG

§Bit 12-13: STATS_DEBUG_MASK_STATS_LOG

§Bit 14-15: STATS_DEBUG_MASK_IS_LOG

 

adb shell setprop persist.camera.global.debug 2

§表示HAL/Sensor/MCT/3A 所有ERROR/HIGH/LOW log都会被打印

 

 

Kernel log:

 

Sensor bring up and 常见问题的分析:

如果有高通lisence的同学也可以看看下面文档

参考文档:

80-NU323-2SC_D_Multimedia_Driver_Development_and_Bringup_Guide_-_Camera_Simplified_Chinese.pdf

80-NL239-33SC_D_Linux_Camera_Debugging_Guide_Simplified_Chinese.pdf

80-ND717-2BX_MSM8X10-MSM8X12_SOFTWARE_INTERFACE_FOR_OEMS.pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值