您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 其它文档 > MTK6235+Camera架构及其500万摄像头软解码实现ov5642
Cameraarchitecture&driverinMTK林耕书booklinbook@hotmail.comOv5642usedinMTK6235Agenda概述IRQ,FIQ介绍LCD介绍Camera在mtk中的整体架构和驱动介绍下期预告概述这个ppt主要把mtk中camera部分向大家做个尽量系统的汇报。ppt以camera的工作流程为线索,以及数据流为副线索,从mmi层开始经media中间层一直讲到camerasensordriver层,希望能给大家一个camera模块总体的介绍,为以后的开发提供一个资料参考。由于有的时候我的思路和mtk的烂代码一样会错乱,所以有些地方我们就图个不求甚解,我尽量把它说的清楚一些,时间和水平有限,如果在ppt中有疏误的地方,请大家能指出一起讨论,谢谢IRQ&FIQ驱动的开发是以系统为基础的,功能实现过程中离不开系统服务和调用。在camera中也是这样,比如中断的使用就涉及到的很多,sensor什么时候传来一帧数据,什么时候传输完成,类似与这样的异同步的流程都会涉及到中断,而且也相对有些复杂,所以我单独把mtk中断部分先做个简要的介绍,为后续的讲解提供一些方便。con什么是中断,什么是IRQ,FIQ?(我来口述)FIQIRQFIQcontrollerIRQcontrollerInteruputinputmultiplesEintTDMAGPTSIMUARTBB(1)FIQ优先与IRQ。(2)系统中只用一个FIQ和一个IRQpin,那么多人用,就要加中断控制模块来仲裁和控制。在程序里FIQ和IRQ怎样体现,现在来看code。1.中断向量表(..\init\src\bootarm.s)conINT_IRQ_Parse就是irq中断处理函数在汇编中,再往下看con在INT_IRQ_Parse中有一句BLisrC_Main就跳到c代码部分进行进一步的中断处理isrC_Main()中Irqx就是不同的irq的中断号,这句话就调用相应的irq的处理函数了lisr_dispatch_tbl在IRQ_Register_LISR这个中断注册函数中被赋值,你看到了吗?讲到这里好像已经把中断讲完了,硬件产生电位变化引发中断,经过中断控制器的仲裁,给bb发最终的irq或fiq中断,bb收到中断,中断当前手头上的事,跳到中断向量表处指定的处理函数,然后执行相应的irq之类的函数。一切看起来都很完整了,很完美了。好像是喔!但是我们可能忽略了一个问题,就是中断不能太久,要很快就要回来,要短要快,但是如果我们中断中要处理的东西的确很多,就好比sensor传来一帧数据,我们要处理,要解码,要保存,要…,的确很多事情快不了怎么办?下面就讨论这个问题,完善中断处理机制。中断处理函数架构上半部(紧急的部分)下半部(延时的部分)中断调度把中断处理分为两部分,先把紧急的部分处理了,然后通过调度的方式来处理接下来的事情。一旦一个东西是被以调度的方式远行的话,os就会根据相应的调度方式让他运行,这个是os的活儿,我们就不用担心了,os会处理的很好。这样就可以很好的解决刚才提出的问题。其实几乎所有的系统都是这样解决这个问题的,在mtk里我们用visual_active_hisrkal_create_hisr(VISUHISR,1,1024,VISUAL_HISR,NULL);这样的函数来实现,我们不妨叫他虚中断。下面分析一下。先看虚中断相关的函数,我一个个解释说明通过以上分析,不难看出,虚中断就是通过利用kal_create_hisr,kal_activate_hisr这样kal层提供的有一点点像信号机制一样的功能函数来实现中断下半部的调度。(kal还有些功能函数后面会介绍)这样说可能还是有点抽象,没关系,下面我举个小小的例子把一个中断的上下部串起来讲一遍大家就清楚了。看这个,我来讲解这个是isp模块初始化时,其中就注册了一个中断上部份camera_isp_LISR和注册了一个中断下半部camera_isp_HISRisp(imagesignalprocessor)是图像处理模块,sensor传来的照片yuv格式的数据就是由isp处理的(这个后面详细讲),isp处理中就会用到中断。首先isp的硬件产生中断,camera_isp_LISR()就被调用了,camera_isp_LISR中先把重要的一些事给做了,最后通过visual_active_hisr(VISUAL_CAMERA_HISR_ID);来激发调度isp中断的下半部camera_isp_HISR(这个函数里做的事情可多了)再介绍一下后面会用到的几个异同步函数kal_create_event_group(…),kal_set_eg_events(…),kal_retrieve_eg_events(…),举个例子给大家说明一下,什么原理,怎么用(口述)。Lcd相关部分的简介这里只介绍两个关于lcd的问题,一个是关于layer的问题,另一个是快速定时自动刷新的问题。先看一幅截图,我来说明说白了layer就是一个memorybuffer,要画在屏幕上的数据就写在这个buffer相应的位置上,最后buffer的数据就传给lcd,图像就被显示出来。多个layer无非就是多开了几个memorybuffer,在不同buffer上画画,最后在把他们几个buffer进行叠加,有透明值部分的点就被过滤掉,叠加后再把他传到lcd中显示出来,这样做好处就是提高了显示能力和效率,像camera部分,preview的图像就被画在一个层上面,而那些图标(即osd)画在另一个层上,叠加后传到lcd中刷新显示。设想一下如果只有一个layer(一个buffer)的话,像这样的osd之类的功能就很难实现了。具体看一下代码中的几个部分,我来讲解这个是lcd刷新显示的底层的一个函数了,其两个参数:lcd_layer是表示第几层如LCD_LAYER0,LCD_LAYER1.addr就是具体的buffer地址,buffer可以是系统默认的,也可以是动态开的(mmi的开发过程中就会常常碰到这个东西)接下来看LCD_config_fw_layer_address(addr);在这个函数里buffer的地址就被写入相应的layer地址寄存器中去了如LCD_LAYER0_SIZE_REG,(刚才说过)最后开始传输START_LCD_TRANSFER赋值相应寄存器地址Lcd快速定时自动刷新问题在某些情况下(如camerapreview时)对lcd的刷新速度是要求很高的。因此mtk的为lcd度身定制了一个自动刷新,原理很简单,大家只要知道有这回事情就可以了,不用深究,这里只做一个简单的介绍。先看一下代码的几个片段,我来讲述说明。一般用到定时自动刷新的,都是重复的刷新,比如cameraporeview,所以刷新显示的区域都是相对固定的,只是刷新的内容在变,所以在上面的这个函数里,它要刷新的参数都保存在了lcd_hw_trigger_para[]数组中,它将在lcd_HISR()中被用到。看下图lcd_HISR()就是中断处理函数在lcd_system_init()被注册,lcd_hw_trigger_flag就是开关变量,这个一目了然。讲这个的目的就是为下面的camerapreview时刷屏问题做个铺垫,当然camerapreview的刷屏和这个还有一点点不同,还涉及到resizer的问题,这是后话,暂且不表。camera终于可以开始讲camera了,让大家久等了。先看几副图,听我一个个讲解。ISP的组成部分ISP(imagesingalproccessor)顾名思义图像数据的处理。ImageResizer图像数据的压缩。ImageDMA把数据传给lcd显示。RESIZER的大致组成Sensor部分原理图DVDD,VDD,DIOVDD这3个电源,要单独说明一下,听我口述。最低层的sensordriver配置部分大家都很熟悉了,不是要介绍的重点,我们看看,就一笔带过设置a,d电压大小,cis_module_power_on()是对sensor进行上电,不是对camera在bb中的模块上电。cis_module_power_on()在,sensorinitial时被调用。从camerapoweron开始讲起下面我们以camera的使用流程为线索开始分析,流程分为启动,预览,抓拍,保存,回显几个部分。先说启动(是启动camera在bb的相关module即isp,不是sensor,sensor要到后面启动init,前面提过)。mmi_camera_app_screen(void)mmi_camera_entry_app_screen_internal()mdi_camera_power_on()media_cam_power_up()SendMSG_ID_MEDIA_CAM_POWER_UP_REQcam_power_up_req_hdlr(ilm_ptr);init_isp_if()和init_yuv_isp()关键CameraApp.cCameraApp.cmdi_camera.ccam_api.ccam_ilm.ccam_main.ccam_msg_handler.ccamera_process_v2.c这部分了解就可以。而后面接下去要讲的preview和capture就是关键了。Sensor驱动部分initial一启动,接下来就直接preview了。我来讲解下面流程mmi_camera_entry_preview_state()CAMERA_ENTER_STATE(CAMERA_STATE_PREVIEW);即mmi_camera_enter_state(CAMERA_STATE_PREVIEW;mmi_camera_entry_app_screen_internal()mmi_camera_preview_start()mdi_camera_preview_start(&camera_preview_data,&camera_setting_data);mdi_camera_preview_start_internal()media_cam_preview()以上是函数流程图供大家以后跟踪代码时参考,现在我先用白话文描述一下这个preview的全过程,然后分别例举代码片段,重点讨论几个问题。isp初始化启动以后,就马上进入preview状态,首先通过数据流设置,告诉isp相应模块预览的屏幕有多宽多长,sensor传来的数据是什么格式yuv422啊还是yuv444,或者是rawdata,图片效果啊,亮度啊,对比度啊,传来的数据要放在哪个buffer中,要多大,外部存还是内部存memory,给lcd刷新显示的数据放在哪个buffer中,用哪个layer来刷,等等。这些事情做好后,就通过sensordriver的preivew函数告诉sensor,你开始传数据(如yuv格式的)吧!我等着收呢。于是sensor就按照要求media_cam_preview()cam_send_preview_req()SendMSG_ID_MEDIA_CAM_PREVIEW_REQcam_preview_req_hdlr(ilm_ptr);camera_preview_process()yuv_preview_process()这个函数是要重点介绍的源源不断的开始发数据了,发给谁,发给isp,一个个pixel地发,若干个pixel组成一行,若干行组成一个帧,等isp收到一个帧之后,先做数据图像处理,让后告诉Resizer“我收好一帧了,也处理好了,给你了”,resizer接到指示把数据收过来,进行横向,纵向压缩。压好后通过dma往lcd上传,我们就看到了preview的图像,就这样sensor不断的发数据过来,isp,resizer,dma,lcd周而复始的皆同工作,就
本文标题:MTK6235+Camera架构及其500万摄像头软解码实现ov5642
链接地址:https://www.777doc.com/doc-5084504 .html