wince5.0 2440 BSP之摄像头驱动分析

时间:2021-12-22 08:07:50

现在看驱动就看那几个接口函数即可,现在先看初始化函数。

  1. DWORD CIS_Init(DWORD dwContext)
  2. {
  3.     DWORD dwErr = ERROR_SUCCESS, bytes;
  4.     RETAILMSG(MSG_EN_1, (TEXT("CIS::CIS_Init() /r/n")));
  5. // Allocate for our main data structure and one of it's fields.
  6.     pCIS = (PCIS_CONTEXT)LocalAlloc( LPTR, sizeof(CIS_CONTEXT) );
  7.     if ( !pCIS )
  8.         return( NULL );
  9.     
  10.     pCIS->Sig = CIS_SIG;    
  11.     // 1. Virtual Alloc
  12.     Virtual_Alloc();
  13.     RETAILMSG(MSG_EN_1, (TEXT("CIS::Virtual_Alloc /r/n"))); 
  14.     //RETAILMSG(1, (TEXT("CIS_Init : IOCTL_HAL_REQUEST_SYSINTR /r/n")));
  15. //这里动态申请Camera接口的中断
  16.     if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_CamIrq, sizeof(UINT32), &g_CamSysIntr, sizeof(UINT32), NULL))
  17.     {
  18.         RETAILMSG(1, (TEXT("ERROR: CIS_INIT: Failed to request sysintr value for Camera interrupt./r/n")));
  19.         return(0);
  20.     }
  21.     
  22.     InitializeCriticalSection(&pCIS->RegCS);
  23. //MSG_EN_1控制是否打印,这里MSG_EN_1是0故没有打印出来
  24.     RETAILMSG(MSG_EN_1, (TEXT("CIS::InitializeCriticalSection /r/n")));
  25.     //
  26.     // Init I2C
  27.     //这里让我大开眼界,在驱动中调用另外一个驱动,并且方法完全和应用程序相同
  28.     pCIS->hI2C = CreateFile( L"I2C0:",
  29.                              GENERIC_READ|GENERIC_WRITE,
  30.                              FILE_SHARE_READ|FILE_SHARE_WRITE,
  31.                              NULL, OPEN_EXISTING, 0, 0);
  32.                    
  33.     if ( INVALID_HANDLE_VALUE == pCIS->hI2C ) {
  34.         dwErr = GetLastError();//这个查错函数也比较有意思
  35.         //DEBUGMSG(ZONE_ERR, (TEXT("Error %d opening device '%s' /r/n"), dwErr, L"I2C0:" ));
  36.         RETAILMSG(I2C_MSG, (TEXT("Error %d opening device '%s' /r/n"), dwErr, L"I2C0:" ));
  37.         goto _error_exit;
  38.     }
  39.     RETAILMSG(MSG_EN_1, (TEXT("CIS::CreateFile(/"I2C0/") /r/n")));
  40.     //memset((void*)pCIS->eg, 0, sizeof(pCIS->eg));
  41.     //
  42.     // Gat Fastcall driver-to-driver entrypoints
  43.     //
  44.     if ( !DeviceIoControl(pCIS->hI2C,
  45.                           IOCTL_I2C_GET_FASTCALL, //IOCTL_I2C_GET_FASTCALL是在IIC驱动里面的
  46.                           NULL, 0, 
  47.                           &pCIS->fc, sizeof(pCIS->fc),
  48.                           &bytes, NULL) ) 
  49.     {
  50.         dwErr = GetLastError();
  51.         DEBUGMSG(ZONE_ERR,(TEXT("IOCTL_I2C_GET_FASTCALL ERROR: %u /r/n"), dwErr));
  52.         goto _error_exit;
  53.     }            
  54.     RETAILMSG(MSG_EN_1, (TEXT("CIS::DeviceIoControl /r/n")));
  55.     // Init H/W
  56.     pCIS->State = INITIALIZE;
  57.     Cam_Init();//这是摄像头读取注册表的一些信息,并初始化,我现在暂时不看这部分。
  58.     if (!InitInterruptThread())//这个用来初始化Camera中断线程
  59.     {
  60.         RETAILMSG(1,(TEXT("Fail to initialize camera interrupt event/r/n")));
  61.         return FALSE;
  62.     }    
  63.     pCIS->Dx = D0;
  64.     m_Dx = (_CEDEVICE_POWER_STATE)D0;
  65.     DevicePowerNotify(_T("CIS1:"),(_CEDEVICE_POWER_STATE)D0, POWER_NAME);
  66.     mInitialized = TRUE;
  67.     return TRUE;
  68. _error_exit:
  69.     return dwErr;   
  70. }

DeviceIoControl到底是怎么和驱动联系起来的呢?

我发现在IIC驱动中有如下代码

// OUT: PI2C_FASTCALL
#define IOCTL_I2C_GET_FASTCALL  /
    CTL_CODE(FILE_DEVICE_I2C, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)

 

还有,在I2C_IOControl中有

case IOCTL_I2C_GET_FASTCALL:
            if ( (dwLenOut < sizeof(I2C_FASTCALL)) || !pBufOut ) {
                bRc = FALSE;
                dwErr = ERROR_INVALID_PARAMETER;
                break;
            }

现在来看看CTL_CODE(FILE_DEVICE_I2C, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)到底是什么意思

这个是个微软的函数

This macro creates a unique system I/O control code (IOCTL).

#define CTL_CODE(, , , ) (
  (() << 16) | (() << 14) | (() << 2) | ()
)
现在暂时不理会先。继续往下看。
InitInterruptThread
 
  1. //这个是5.0动态中断线程,见过很多了,就不注释了。
  2. BOOL InitInterruptThread()
  3. {
  4.     DWORD         threadID;                         // thread ID
  5.     BOOL bSuccess;
  6.     CameraEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  7.     
  8.     if (!CameraEvent)
  9.     {
  10.         return FALSE;
  11.     }
  12.     bSuccess = InterruptInitialize(g_CamSysIntr, CameraEvent, NULL, 0);
  13.     if (!bSuccess) 
  14.     {
  15.         RETAILMSG(1,(TEXT("Fail to initialize camera interrupt event/r/n")));
  16.         return FALSE;
  17.     }    
  18.     
  19.     CameraThread = CreateThread(NULL,
  20.                                  0,
  21.                                  (LPTHREAD_START_ROUTINE)CameraCaptureThread,
  22.                                  0,
  23.                                  0,
  24.                                  &threadID);
  25.     
  26.     if (NULL == CameraThread ) {
  27.         RETAILMSG(1,(TEXT("Create Camera Thread Fail/r/n")));
  28.     }
  29.     
  30.     RETAILMSG(1,(_T("CAMERA.DLL::InterruptThread Initialized./r/n")));
  31.     return TRUE;
  32. }

再往下看

CameraCaptureThread

  1. DWORD CameraCaptureThread(void)
  2. {
  3.     unsigned char tmp=0;
  4.     static unsigned int time,old_time;
  5.     static unsigned int cam_intr;
  6.     
  7.     DWORD   dwCause;                    // LJY PWR040613
  8.     //dwDisplayTimeout = INFINITE;
  9.     SetProcPermissions((DWORD)-1);
  10.     
  11.     while(TRUE)
  12.     {
  13.         RETAILMSG(0,(TEXT("[CAM_HW] InterruptThread : Waiting For a Single Object/n/r")));
  14.         //一般查询dwDisplayTimeout是一个时间常数,中断是INFINITE,在这里是个
  15.         dwCause = WaitForSingleObject(CameraEvent, dwDisplayTimeout);
  16.         
  17.         RETAILMSG(MSG_EN_1,(_T("CameraCaptureThread(%d)++/r/n"), frame_count));
  18. #if 0
  19.         if (frame_count <= 2) {
  20.             //frame_count++;
  21.             // Enable camera interrupt
  22.             s2440INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
  23.             s2440INT->INTMSK &= ~( 1 << IRQ_CAM );
  24.             
  25.             continue;
  26.         }
  27. #endif
  28.         
  29.         if (dwCause == WAIT_OBJECT_0) // LJY PWR
  30.         {
  31.             Lock();
  32.             __try
  33.             {
  34.                 if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C ))
  35.                 {
  36.                     frame_count++;
  37.                     cam_intr |= ( 1 << IRQ_SUB_CAM_C );
  38.                     
  39.                     s2440INT->SUBSRCPND  =  (1<<IRQ_SUB_CAM_C);
  40.                     s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_C);
  41.                     //RETAILMSG(1,(_T("CAM_C, ts %d/r/n"), GetTickCount()));
  42.                 }
  43.                 if (s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P ))
  44.                 {
  45.                     cam_intr |= ( 1 << IRQ_SUB_CAM_P );
  46.                     
  47.                     s2440INT->SUBSRCPND  =  (1<<IRQ_SUB_CAM_P);
  48.                     s2440INT->INTSUBMSK &= ~(1<<IRQ_SUB_CAM_P);
  49.                     //RETAILMSG(1,(_T("CAM_P, ts %d/r/n"), GetTickCount()));
  50.                 }
  51.                 if (((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_C )) == 0) && ((s2440INT->INTSUBMSK & ( 1 << IRQ_SUB_CAM_P )) == 0))
  52.                 {
  53.                     RETAILMSG(MSG_EN_1,(_T("[CAM]NOP/r/n")));                   
  54.                 }
  55.                 
  56.                 
  57.                 InterruptDone(g_CamSysIntr);                
  58.             
  59.                 //time = GetTickCount();
  60.                 //RETAILMSG(1,(TEXT("+time:%d/r/n"),(time - old_time)));
  61.     
  62.                 // Handle any interrupts on the input source
  63.                 if (cam_intr & ( 1 << IRQ_SUB_CAM_P ))
  64.                 {
  65.                     // display the image    
  66.                     if (DRIVER_PREVIEW_ENABLE == 1)
  67.                     Display_Cam_Image(0,0,PREVIEW_X, PREVIEW_Y, PORT_A);
  68.                     Buffer_preview_info_update();
  69.                     cam_intr &= ~( 1 << IRQ_SUB_CAM_P );
  70.                 }
  71.                     
  72.                 if (cam_intr & ( 1 << IRQ_SUB_CAM_C ))
  73.                 {
  74.                     Buffer_codec_info_update();
  75.                     cam_intr &= ~( 1 << IRQ_SUB_CAM_C );
  76.                 }
  77.                 // Enable camera interrupt
  78.                 //s2440INT->INTSUBMSK &= ~(( 1 << IRQ_SUB_CAM_P )|( 1 << IRQ_SUB_CAM_C ));
  79.                 //s2440INT->INTMSK &= ~( 1 << IRQ_CAM );
  80.                 //old_time = GetTickCount();
  81.                 //RETAILMSG(1,(TEXT("-time:%d/r/n"),(old_time-time)));
  82.             }
  83.             __except(EXCEPTION_EXECUTE_HANDLER)
  84.             {
  85.                 RETAILMSG(PM_MSG, (TEXT("Camera.DLL:InterruptThread() - EXCEPTION: %d"), GetExceptionCode()));
  86.             }
  87.                 
  88.             Unlock();
  89.             
  90.         }
  91.         else if (dwCause == WAIT_TIMEOUT)
  92.         {
  93.             Lock();
  94.             
  95.             RETAILMSG(PM_MSG,(_T("[CAM_HW] InterruptThread Timeout : %d msec/r/n"), dwDisplayTimeout));
  96.             
  97.             dwDisplayTimeout = INFINITE;                // reset timeout until Camera Interrupt occurs
  98.             bIdlePwrDown = TRUE;                    // Codec is off
  99.             CamInterface_PowerDown();
  100.             RETAILMSG(PM_MSG, (TEXT("[CAM_HW] InterruptThread : bIdlePwrDown = TRUE/r/n")));
  101.             Unlock();
  102.         }
  103.         else
  104.         {
  105.             RETAILMSG(PM_MSG, (TEXT("[CAM_HW] InterruptThread : Exit %d, Cause %d/r/n"), GetLastError(), dwCause));
  106.         }
  107.     }
  108.     return 0;
  109. }

我看上去觉得一开机就会产生这个摄像头扑捉线程,我觉得不合理,串口打印信息也没有打印出来,应该没有被调用。到底在哪里控制这些程序的调用呢?