ov9650 VS2005应用程序设计

xunorange   2010-5-20 19:43 楼主
TQ2440板子,ov9650摄像头,用VS2005下的VC++编写应用程序,如何把OV9650 拍到的图像保存为BMP格式的文件?需要用到那些函数?如何得到数据缓冲区的地址?下面是部分驱动程序代码:
1、CIS_IoControl()中的一部分:
// for MPEG4
                case CAM_IOCTL_GET_LATEST_FRAME:
                        RETAILMSG(MSG_EN_1,(TEXT("CAMERA:CAM_IOCTL_GET_LATEST_FRAME\r\n")));
                        if (frame_count < 2) {
                        RETAILMSG(1,(TEXT("CAMERA:CAM_IOCTL_GET_LATEST_FRAME - frame not available!!!\r\n")));
                        return FALSE;}
                        Tick_GET_FRAME_PREV = Tick_GET_FRAME_CUR;
                        Tick_GET_FRAME_CUR = GetTickCount();
                        Copy_Cam_Image(pBufOut, QCIF_XSIZE, QCIF_YSIZE, PORT_A);
                        break;

                case CAM_IOCTL_SAMSUNG_CAM:                // ID=0x520
                        RETAILMSG(MSG_EN_1,(_T("CAM_IOCTL_SAMSUNG_CAM\r\n")));
                        Samsung_camcoder(pBufOut);
                        break;

                。。。。

2、Copy_Cam_Image(pBufOut, QCIF_XSIZE, QCIF_YSIZE, PORT_A)函数 一部分
             {    。。。
                pImage = pBufOut;
        if (image_size == 1) // QCIF       
                Y_size = QCIF_XSIZE*QCIF_YSIZE;
        else if (image_size == 2) // CIF
                Y_size = CIF_XSIZE*CIF_YSIZE;
                       
        C_size = Y_size/4;       
        P_size = Y_size + C_size*2;
              。。。
                buffer_y += VIRTUAL_ADDR_OFFSET;
        buffer_cb += VIRTUAL_ADDR_OFFSET;
        buffer_cr += VIRTUAL_ADDR_OFFSET;
        。。。
              RETAILMSG(MSG_EN_1,(_T("pBufOut 0 offset = 0x%x\r\n"), pImage));
        memcpy(pImage, &yuvinfo, sizeof(YUVINFO));
        pImage += sizeof(YUVINFO);       
       
        RETAILMSG(MSG_EN_1,(_T("pBufOut Y = 0x%x\r\n"), pImage));
        memcpy(pImage, buffer_y, Y_size);
        pImage += (Y_size);
       
        RETAILMSG(MSG_EN_1,(_T("pBufOut cb = 0x%x\r\n"), pImage));
        memcpy(pImage, buffer_cb, C_size);
        pImage += C_size;
        RETAILMSG(MSG_EN_1,(_T("pBufOut cr = 0x%x\r\n"), pImage));
        memcpy(pImage, buffer_cr, C_size);
       。。。
}

请问从驱动程序缓冲区的数据是不是可以通过 deviceIOcontrol 调用CAM_IOCTL_GET_LATEST_FRAME来读取并进一步保存为bmp格式图片?

回复评论 (29)

我也不知道。不过建议可以看看开发板上带的camera测试代码。里面应该有抓图的功能在里面。
点赞  2010-5-21 10:12
是的,屏上能够显示,但我不知道怎么把图片保存下来,继续学习啊,谢谢你!
点赞  2010-5-21 11:50
楼主加油~!顺便帮顶。
点赞  2010-5-21 11:52
你这个读出来的是yuv格式的,需要转成rgb,或者看驱动支不支持抓取rgb格式的数据。Samsung_camcoder内容是什么?
点赞  2010-5-21 13:00
驱动输出的图片数据,要么是YUV数组,要么是RGB数组,弄清它们和BMP格式文件的转换即可。
点赞  2010-5-21 13:22
void Samsung_camcoder(U8 *pBufOut)
{
        U8 *pImage;
        PINGPONG caminfo;

        pImage = pBufOut;

        if( codec_flag )
        {
                caminfo.flag = 1;
                caminfo.y_address = y_address;
                caminfo.cb_address = cb_address;
                caminfo.cr_address = cr_address;
               
                memcpy(pImage, &caminfo, sizeof(PINGPONG));
                codec_flag = 0;
        }
}
y_address、cb_address、cr_address是驱动中的全局变量,它们的值是由下面的函数获取传递得到:
void Buffer_codec_info_update()
{
        U32 Y_size, C_size, P_size;
        int temp;
        unsigned int buffer_y, buffer_cb, buffer_cr;
       
        if ( image_size == 1 )
                Y_size = QCIF_XSIZE*QCIF_YSIZE;
        else if ( image_size == 2 )
                Y_size = CIF_XSIZE*CIF_YSIZE;

        C_size = Y_size/4;       
        P_size = Y_size + C_size*2;

        temp = (s2440CAM->CICOSTATUS>>26)&3;
        temp = (temp + 2) % 4;

        switch (temp)
        {
        case 0:
                buffer_y = s2440CAM->CICOYSA1;
                buffer_cb = s2440CAM->CICOCBSA1;
                buffer_cr = s2440CAM->CICOCRSA1;
                break;
        。。。。
        case 3:
                buffer_y = s2440CAM->CICOYSA4;
                buffer_cb = s2440CAM->CICOCBSA4;
                buffer_cr = s2440CAM->CICOCRSA4;
                break;
        default :
                buffer_y = s2440CAM->CICOYSA1;
                buffer_cb = s2440CAM->CICOCBSA1;
                buffer_cr = s2440CAM->CICOCRSA1;
                break;
        }

        buffer_y += VIRTUAL_ADDR_OFFSET;
        buffer_cb += VIRTUAL_ADDR_OFFSET;
        buffer_cr += VIRTUAL_ADDR_OFFSET;

        if( codec_flag )RETAILMSG(MSG_EN_1,(_T("Buffer is not read\r\n")));
        codec_flag = 1;
        y_address = buffer_y;
        cb_address = buffer_cb;
        cr_address = buffer_cr;
}

我在网上看到一篇帖子(gooogleman:Topic:如何实现OV9650摄像头拍照:
http://www.cnblogs.com/wogoyixikexie/archive/2009/11/04/1595676.html),很受启发,他好像是用下面的驱动程序函数获取到缓冲区数据地址,然后通过DeviceIoControl函数,得到数据并保存为图片:
void Samsung_camcoder_pr(U8 *pBufOut)
{
        U8 *pImage;
        PINGPONG_PR prinfo;

        pImage = pBufOut;

        if ( rgb_flag )
        {
                prinfo.flag = 1;
                prinfo.rgb_address = rgb_address;
                memcpy(pImage, &prinfo, sizeof(PINGPONG_PR));
                rgb_flag = 0;
        }       
}
rgb_address的地址s2440CAM->CICOYSA1=CoFrameBuffer是由下面的函数得到的:
点赞  2010-5-21 16:37
void Buffer_preview_info_update()
{
//        U32 Y_size;
        int temp;
        unsigned int buffer_rgb;
       
        temp = (s2440CAM->CIPRSTATUS>>26)&3;
        temp = (temp + 2) % 4;

        RETAILMSG(MSG_EN_2,(_T("preview index = %d, size %d\r\n"), temp, image_size));

        switch (temp)
        {
        case 0:
                buffer_rgb = s2440CAM->CIPRCLRSA1;
                break;
        case 1:
                buffer_rgb = s2440CAM->CIPRCLRSA2;
                break;
        case 2:
                buffer_rgb = s2440CAM->CIPRCLRSA3;
                break;
        case 3:
                buffer_rgb = s2440CAM->CIPRCLRSA4;
                break;
        default :
                buffer_rgb = s2440CAM->CIPRCLRSA1;
                break;
        }

        RETAILMSG(MSG_EN_1,(_T("buffer_rgb[PHY] = 0x%x\r\n"), buffer_rgb));
        buffer_rgb += VIRTUAL_ADDR_OFFSET;
#if 1
        RETAILMSG(MSG_EN_1,(_T("buffer_rgb = 0x%x\r\n"), buffer_rgb));
#endif
        if( rgb_flag )        RETAILMSG(MSG_EN_1,(_T("Prev Buffer is not read\r\n")));
        rgb_flag = 1;
        rgb_address = buffer_rgb;
}
buffer_rgb = s2440CAM->CIPRCLRSA1中的s2440CAM->CIPRCLRSA1和
void CamInit(U32 CoDstWidth, U32 CoDstHeight, U32 PrDstWidth, U32 PrDstHeight,
                        U32 WinHorOffset, U32 WinVerOffset,  U32 CoFrameBuffer, U32 PrFrameBuffer)
{
        U32 WinOfsEn;
        U32 divisor, multiplier;
        U32 MainBurstSizeY, RemainedBurstSizeY, MainBurstSizeC, RemainedBurstSizeC, MainBurstSizeRGB, RemainedBurstSizeRGB;
        U32 H_Shift, V_Shift, PreHorRatio, PreVerRatio, MainHorRatio, MainVerRatio;
        U32 SrcWidth, SrcHeight;
        U32 ScaleUp_H_Co, ScaleUp_V_Co, ScaleUp_H_Pr, ScaleUp_V_Pr;

        //constant for calculating codec dma address
        if(CAM_CODEC_OUTPUT)  //=0

                divisor=2; //CCIR-422
        else
                divisor=4; //CCIR-420
               
        //constant for calculating preview dma address
        if(CAM_PVIEW_OUTPUT)  //=1
                multiplier=4;
        else
                multiplier=2;
       
        if(WinHorOffset==0 && WinVerOffset==0)
                WinOfsEn=0;
        else
                WinOfsEn=1;

        SrcWidth=CAM_SRC_HSIZE-WinHorOffset*2;
        SrcHeight=CAM_SRC_VSIZE-WinVerOffset*2;

        if(SrcWidth>=CoDstWidth) ScaleUp_H_Co=0; //down
        else ScaleUp_H_Co=1;                //up

        if(SrcHeight>=CoDstHeight) ScaleUp_V_Co=0;
        else ScaleUp_V_Co=1;               

        if(SrcWidth>=PrDstWidth) ScaleUp_H_Pr=0; //down
        else ScaleUp_H_Pr=1;                //up

        if(SrcHeight>=PrDstHeight) ScaleUp_V_Pr=0;
        else ScaleUp_V_Pr=1;               

        ////////////////// common control setting
        s2440CAM->CIGCTRL |= (1<<26)|(0<<27); // inverse PCLK, test pattern
        s2440CAM->CIWDOFST = (1<<30)|(0xf<<12); // clear overflow
        s2440CAM->CIWDOFST = 0;       
        s2440CAM->CIWDOFST=(WinOfsEn<<31)|(WinHorOffset<<16)|(WinVerOffset);

//#if(CIS_TYPE == CIS_S5X3A1)
        s2440CAM->CISRCFMT=(CAM_ITU601<<31)|(0<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_YCBYCR<<14)|(CAM_SRC_VSIZE);
//#elif(CIS_TYPE == CIS_S5X3AA)
//        s2440CAM->CISRCFMT=(CAM_ITU601<<31)|(0<<30)|(0<<29)|(CAM_SRC_HSIZE<<16)|(CAM_ORDER_CBYCRY<<14)|(CAM_SRC_VSIZE);
//#endif


        ////////////////// codec port setting
        s2440CAM->CICOYSA1=CoFrameBuffer;
        s2440CAM->CICOYSA2=s2440CAM->CICOYSA1+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
        if(CoDstWidth*CoDstHeight < 655360)   // Codec Max. Size = 1280*1024   Above sXGA, use only 2 memory of the 4 pingpong memory
        {
                s2440CAM->CICOYSA3=s2440CAM->CICOYSA2+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
                s2440CAM->CICOYSA4=s2440CAM->CICOYSA3+CoDstWidth*CoDstHeight+2*CoDstWidth*CoDstHeight/divisor;
        }
        else
        {
                s2440CAM->CICOYSA3=s2440CAM->CICOYSA1;
                s2440CAM->CICOYSA4=s2440CAM->CICOYSA2;               
        }
       
        s2440CAM->CICOCBSA1=s2440CAM->CICOYSA1+CoDstWidth*CoDstHeight;
        s2440CAM->CICOCBSA2=s2440CAM->CICOYSA2+CoDstWidth*CoDstHeight;
        s2440CAM->CICOCBSA3=s2440CAM->CICOYSA3+CoDstWidth*CoDstHeight;
        s2440CAM->CICOCBSA4=s2440CAM->CICOYSA4+CoDstWidth*CoDstHeight;

        s2440CAM->CICOCRSA1=s2440CAM->CICOCBSA1+CoDstWidth*CoDstHeight/divisor;
        s2440CAM->CICOCRSA2=s2440CAM->CICOCBSA2+CoDstWidth*CoDstHeight/divisor;
        s2440CAM->CICOCRSA3=s2440CAM->CICOCBSA3+CoDstWidth*CoDstHeight/divisor;
        s2440CAM->CICOCRSA4=s2440CAM->CICOCBSA4+CoDstWidth*CoDstHeight/divisor;

        s2440CAM->CICOTRGFMT=(CAM_CODEC_IN_422<<31)|(CAM_CODEC_OUTPUT<<30)|(CoDstWidth<<16)|(CAM_FLIP_NORMAL<<14)|(CoDstHeight);

        CalculateBurstSize(CoDstWidth, &MainBurstSizeY, &RemainedBurstSizeY);
        CalculateBurstSize(CoDstWidth/2, &MainBurstSizeC, &RemainedBurstSizeC);
        s2440CAM->CICOCTRL=(MainBurstSizeY<<19)|(RemainedBurstSizeY<<14)|(MainBurstSizeC<<9)|(RemainedBurstSizeC<<4);

        。。。。。
        s2440CAM->CICOSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);
        s2440CAM->CICOSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
        s2440CAM->CICOSCCTRL=(CAM_SCALER_BYPASS_OFF<<31)|(ScaleUp_H_Co<<30)|(ScaleUp_V_Co<<29)|(MainHorRatio<<16)|(MainVerRatio);

        s2440CAM->CICOTAREA=CoDstWidth*CoDstHeight;

        ///////////////// preview port setting
        s2440CAM->CIPRCLRSA1=PrFrameBuffer;
        s2440CAM->CIPRCLRSA2=s2440CAM->CIPRCLRSA1+PrDstWidth*PrDstHeight*multiplier;
        s2440CAM->CIPRCLRSA3=s2440CAM->CIPRCLRSA2+PrDstWidth*PrDstHeight*multiplier;
        s2440CAM->CIPRCLRSA4=s2440CAM->CIPRCLRSA3+PrDstWidth*PrDstHeight*multiplier;
        s2440CAM->CIPRTRGFMT=(PrDstWidth<<16)|(CAM_FLIP_XAXIS<<14)|(PrDstHeight);
       
        if (CAM_PVIEW_OUTPUT==CAM_RGB24B)
                CalculateBurstSize(PrDstWidth*4, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
        else // RGB16B
                CalculateBurstSize(PrDstWidth*2, &MainBurstSizeRGB, &RemainedBurstSizeRGB);
           s2440CAM->CIPRCTRL=(MainBurstSizeRGB<<19)|(RemainedBurstSizeRGB<<14);

        CalculatePrescalerRatioShift(SrcWidth, PrDstWidth, &PreHorRatio, &H_Shift);
        CalculatePrescalerRatioShift(SrcHeight, PrDstHeight, &PreVerRatio, &V_Shift);
        MainHorRatio=(SrcWidth<<8)/(PrDstWidth<         MainVerRatio=(SrcHeight<<8)/(PrDstHeight<         s2440CAM->CIPRSCPRERATIO=((10-H_Shift-V_Shift)<<28)|(PreHorRatio<<16)|(PreVerRatio);                 
        s2440CAM->CIPRSCPREDST=((SrcWidth/PreHorRatio)<<16)|(SrcHeight/PreVerRatio);
        s2440CAM->CIPRSCCTRL=(1<<31)|(CAM_RGB16B<<30)|(ScaleUp_H_Pr<<29)|(ScaleUp_V_Pr<<28)|(MainHorRatio<<16)|(MainVerRatio);

        s2440CAM->CIPRTAREA= PrDstWidth*PrDstHeight;

        // initialization for buffer addresses
        y_address = s2440CAM->CICOYSA1;
        cb_address = s2440CAM->CICOCBSA1;
        cr_address = s2440CAM->CICOCRSA1;
        rgb_address = s2440CAM->CIPRCLRSA1;
}

上面两种codec和preview 方式是不是都可以得到相关的图片?数据转化为bmp格式的图片有没有相应的函数或者编写这类函数的步骤?看到gooogleman的帖子:
http://topic.eeworld.net/u/20091021/17/b03d7311-6f69-46b4-9b5f-7f563353c668.html
void CCameratestDlg::OnButton3()
{
    // TODO: Add your control notification handler code here
    PINGPONG_PR image;
    WORD width=GetSystemMetrics(SM_CXSCREEN);
    WORD height=GetSystemMetrics(SM_CYSCREEN);
    BOOL ret;
    BYTE* DDBdata=new BYTE[width*height*2];
    BYTE* DIBdata;
    if(width>640)
        width=640;
    if(height>480)
        height=480;
    ret=DeviceIoControl(m_hled,CAM_IOCTL_SAMSUNG_CAM_PR,NULL,NULL,(PBYTE)&image,NULL,NULL,NULL);
    if(!ret)
        AfxMessageBox(_T("读取图片失败!"));
    else
    {
        SetKMode(TRUE);
        memcpy(DDBdata,(void *)image.rgb_address,width*height*2);
        SetKMode(FALSE);
        CBitmap bitmap;
        HBITMAP dstBmp;
        bitmap.CreateBitmap(width,height,1,16,DDBdata);
        HDC hdcSrc = CreateCompatibleDC(NULL);
        HDC hdcDst = CreateCompatibleDC(NULL);
         BITMAPINFOHEADER   bih   =   {0};//位图信息头   
         bih.biBitCount   =   16;//每个像素字节大小   
         bih.biCompression   =   BI_RGB;   
         bih.biHeight   =   height;//高度   
         bih.biPlanes   =   1;   
         bih.biSize   =   sizeof(BITMAPINFOHEADER);   
         bih.biSizeImage   =  0;// width*height*2;//图像数据大小   
         bih.biWidth   =   width;//宽度   
         BITMAPFILEHEADER   bfh   =   {0};//位图文件头   
         bfh.bfOffBits   =   sizeof(BITMAPFILEHEADER)   +   sizeof(BITMAPINFOHEADER);//到位图数据的偏移量   
         bfh.bfSize   =   bfh.bfOffBits + width*height*2;//文件总的大小   
         bfh.bfType   =   (WORD)0x4d42;   
         BITMAPINFO bi={0};
         bi.bmiHeader=bih;
        dstBmp=CreateDIBSection(hdcDst, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void **)&DIBdata, NULL, 0);
        SelectObject(hdcDst, dstBmp);
        SelectObject(hdcSrc, bitmap);
        BitBlt(hdcDst, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
        CFile file(_T("image.bmp"),CFile::modeCreate|CFile::modeReadWrite);
        file.Write(&bfh,sizeof(bfh));
        file.Write(&bih,sizeof(bih));
        file.Write(DIBdata,width*height*2);
        file.Close();
    }
    delete []DDBdata;
}

如果保存的话,保存的地点在哪儿?
点赞  2010-5-21 16:38
就你上面的代码就有保存了

CFile file(_T("image.bmp"),CFile::modeCreate|CFile::modeReadWrite
应该在我的设备下。
点赞  2010-5-21 17:13
我用的是VS2005+wince6.0,编译以后:
1>正在编译...
1>OV9650Dlg.cpp
1>.\OV9650Dlg.cpp(306) : error C2065: 'PINGPONG_PR' : undeclared identifier
1>.\OV9650Dlg.cpp(306) : error C2146: syntax error : missing ';' before identifier 'image'
1>.\OV9650Dlg.cpp(306) : error C2065: 'image' : undeclared identifier
1>.\OV9650Dlg.cpp(323) : error C3861: 'SetKMode': identifier not found
1>.\OV9650Dlg.cpp(324) : error C2228: left of '.rgb_address' must have class/struct/union
1>        type is ''unknown-type''
1>.\OV9650Dlg.cpp(325) : error C3861: 'SetKMode': identifier not found
1>Generating Code...

这是怎么回事?在应用程序中不能调用SetKMode()吗?'PINGPONG_PR' 是驱动程序中定义的一个结构体,在应用程序中能直接使用吗?如何使用?
点赞  2010-5-21 17:28
我用的是VS2005+wince6.0,编译以后:
1>正在编译...
1>OV9650Dlg.cpp
1>.\OV9650Dlg.cpp(306) : error C2065: 'PINGPONG_PR' : undeclared identifier
1>.\OV9650Dlg.cpp(306) : error C2146: syntax error : missing ';' before identifier 'image'
1>.\OV9650Dlg.cpp(306) : error C2065: 'image' : undeclared identifier
1>.\OV9650Dlg.cpp(323) : error C3861: 'SetKMode': identifier not found
1>.\OV9650Dlg.cpp(324) : error C2228: left of '.rgb_address' must have class/struct/union
1> type is ''unknown-type''
1>.\OV9650Dlg.cpp(325) : error C3861: 'SetKMode': identifier not found
1>Generating Code...

这是怎么回事?在应用程序中不能调用SetKMode()吗?'PINGPONG_PR' 是驱动程序中定义的一个结构体,在应用程序中能直接使用吗?如何使用?
点赞  2010-5-21 19:46
void CCameratestDlg::OnButton3()  
{
  // TODO: Add your control notification handler code here
  PINGPONG_PR image;
  WORD width=GetSystemMetrics(SM_CXSCREEN);
  WORD height=GetSystemMetrics(SM_CYSCREEN);
  BOOL ret;
  BYTE* DDBdata=new BYTE[width*height*2];
  BYTE* DIBdata;
  ret=DeviceIoControl(m_hled,CAM_IOCTL_SAMSUNG_CAM_PR,NULL,NULL,(PBYTE)&image,NULL,NULL,NULL);
  if(!ret)
  AfxMessageBox(_T("读取图片失败!"));
  else
  {
  SetKMode(TRUE);
  memcpy(DDBdata,(void *)image.rgb_address,width*height*2);
  SetKMode(FALSE);
  CBitmap bitmap;
  HBITMAP dstBmp;
  bitmap.CreateBitmap(width,height,1,16,DDBdata);
  HDC hdcSrc = CreateCompatibleDC(NULL);
  HDC hdcDst = CreateCompatibleDC(NULL);
  BITMAPINFOHEADER bih = {0};//位图信息头   
  bih.biBitCount = 16;//每个像素字节大小   
  bih.biCompression = BI_RGB;   
  bih.biHeight = height;//高度   
  bih.biPlanes = 1;   
  bih.biSize = sizeof(BITMAPINFOHEADER);   
  bih.biSizeImage = 0;// width*height*2;//图像数据大小   
  bih.biWidth = width;//宽度   
  BITMAPFILEHEADER bfh = {0};//位图文件头   
  bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量   
  bfh.bfSize = bfh.bfOffBits + width*height*2;//文件总的大小   
  bfh.bfType = (WORD)0x4d42;   
  BITMAPINFO bi={0};
  bi.bmiHeader=bih;
  dstBmp=CreateDIBSection(hdcDst, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void **)&DIBdata, NULL, 0);
  SelectObject(hdcDst, dstBmp);
  SelectObject(hdcSrc, bitmap);
  BitBlt(hdcDst, 0, 0, width, height, hdcSrc, 0, 0, SRCCOPY);
  CFile file(_T("image.bmp"),CFile::modeCreate|CFile::modeReadWrite);
  file.Write(&bfh,sizeof(bfh));
  file.Write(&bih,sizeof(bih));
  file.Write(DIBdata,width*height*2);
  file.Close();
  }
  delete []DDBdata;
}

我用的是VS2005+wince6.0,编译以后:
1>正在编译...
1>OV9650Dlg.cpp
1>.\OV9650Dlg.cpp(306) : error C2065: 'PINGPONG_PR' : undeclared identifier
1>.\OV9650Dlg.cpp(306) : error C2146: syntax error : missing ';' before identifier 'image'
1>.\OV9650Dlg.cpp(306) : error C2065: 'image' : undeclared identifier
1>.\OV9650Dlg.cpp(323) : error C3861: 'SetKMode': identifier not found
1>.\OV9650Dlg.cpp(324) : error C2228: left of '.rgb_address' must have class/struct/union
1> type is ''unknown-type''
1>.\OV9650Dlg.cpp(325) : error C3861: 'SetKMode': identifier not found
1>Generating Code...

这是怎么回事?在应用程序中不能调用SetKMode()吗?'PINGPONG_PR' 是驱动程序中定义的一个结构体,在应用程序中能直接使用吗?如果不能通过SetKMode()获取内存缓冲区数据,如何在应用程序中操作才能够实现?
点赞  2010-5-22 08:55
可以的。是你头文件问题。嘿嘿。
点赞  2010-5-22 10:32
应该包含那个头文件?这是.cpp文件里的:
#include "stdafx.h"
#include "OV9650.h"
#include "OV9650Dlg.h"
#include "winioctl.h"
#include
请明示,呵呵
点赞  2010-5-22 10:52
引用: 引用 13 楼 shoushui2009 的回复:
应该包含那个头文件?这是.cpp文件里的:
#include "stdafx.h"
#include "OV9650.h"
#include "OV9650Dlg.h"
#include "winioctl.h"
#include
请明示,呵呵


要学会查找啊,看MSN'SetKMode'在哪个里,就知道了。
点赞  2010-5-22 11:02
好的,多谢gooogleman!
点赞  2010-5-22 11:04
学习了
点赞  2010-5-22 11:45
MSDN关于这个函数有如下内容:
This function switches between kernel and user modes.
This function is no longer supported as of CE 6.0.
Syntax
BOOL SetKMode(  BOOL fMode);

Parameters
fMode
[in] Setting to TRUE enters kernel mode. Setting to FALSE enters user mode.
Return Value
Returns the mode prior to the current call to SetKMode. TRUE if the previous mode was kernel mode; FALSE if the previous mode was user mode.
Remarks
Only the calling thread is affected by SetKMode.

To allow nested operation, set fMode to the value returned from an initial call to SetKMode to return to the original state.

Requirements
Header pkfuncs.h
Library coredll.lib
Windows Embedded CE Windows CE 2.10 and later
在6.0里不支持SetKMode()函数,是不是?又该如何修改?


点赞  2010-5-22 12:31
想办法在驱动解决。关于这个问题看看sunrain_hjb的博客,有讲。
点赞  2010-5-22 12:35
可是我水平还不够啊,驱动程序就看了很长时间,渐渐地看懂一点。应用程序也是慢慢理解,现在就想把图片保存下来,看到了你的一个帖子,试了一下,看来还得改一下。拖得时间很长了,我想尽快完成,想听一下gooogleman的建议
点赞  2010-5-22 13:11
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复