DSP

Qualcomm android camera 架构简析及如何debug

2019-07-13 19:05发布

                                                       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 的权限,另外还 需要添加一些 元素来声明应用中的Camera 特性。 ......   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