gooogleman

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

//-----------------------------------------------------------------------------------------------------------

// 作者:wogoyixikexie@gliet

// 版权:桂林电子科技大学一系科协wogoyixikexie@gliet

// 平台:wince5.0 2440 5.0 BSP

// 发布日期:2009年5月4日 11:05:19

// 最后修改:2009年5月20日 8:51:39

// 注意事项:未经作者同意,不得在转载的时候擅自修改、删除文章的任何部分

//-----------------------------------------------------------------------------------------------------------

C/C++ code
我使用GPIO模拟IIC初始化OV9652 已经成功(我读出来和写入数值一致) 并且用应用程序打开摄像头驱动时候,摄像头驱动也已经能够不停的产生中断。 但是不知道怎么回事,但是图像死活不出现。——我用老的BSP 编译出NK 摄像头可以正常采集,排除了硬件问题。 但是我把老的BSP的代码搬到5.0 却死活不出图像了。 我推测是DMA问题,我根据内存映射表修改了一番,可是还是没有结果。 我的内存映射表 g_oalAddressTable DCD 0x80000000, 0x30000000, 64 ; 32 MB DRAM BANK 6 DCD 0x84000000, 0x10000000, 32 ; nGCS2: PCMCIA/PCCARD DCD 0x86000000, 0x18000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 3 DCD 0x88000000, 0x20000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 4 DCD 0x8A000000, 0x28000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 5 DCD 0x8C000000, 0x08000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 1 DCD 0x90800000, 0x48000000, 1 ; Memory control register DCD 0x90900000, 0x49000000, 1 ; USB Host register DCD 0x90A00000, 0x4A000000, 1 ; Interrupt Control register DCD 0x90B00000, 0x4B000000, 1 ; DMA control register DCD 0x90C00000, 0x4C000000, 1 ; Clock & Power register DCD 0x90D00000, 0x4D000000, 1 ; LCD control register DCD 0x90E00000, 0x4E000000, 1 ; NAND flash control register DCD 0x90F00000, 0x4F000000, 1 ; Camera control register DCD 0x91000000, 0x50000000, 1 ; UART control register DCD 0x91100000, 0x51000000, 1 ; PWM timer register DCD 0x91200000, 0x52000000, 1 ; USB device register DCD 0x91300000, 0x53000000, 1 ; Watchdog Timer register DCD 0x91400000, 0x54000000, 1 ; IIC control register DCD 0x91500000, 0x55000000, 1 ; IIS control register DCD 0x91600000, 0x56000000, 1 ; I/O Port register DCD 0x91700000, 0x57000000, 1 ; RTC control register DCD 0x91800000, 0x58000000, 1 ; A/D convert register DCD 0x91900000, 0x59000000, 1 ; SPI register DCD 0x91A00000, 0x5A000000, 1 ; SD Interface register DCD 0x92000000, 0x00000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 0 DCD 0x94D00000, 0x34000000, 64 ; 64 MB SDRAM BANK 6——我使用的128M SDRAM 非连续方法扩展 DCD 0x00000000, 0x00000000, 0 ; end of table 我的config.bib的DMA内存设置。 MEMORY NK 80200000 01E00000 RAMIMAGE RAM 82000000 02000000 RAM FLASH 92000000 00100000 RESERVED ; Common RAM areas AUD_DMA 80002000 00000800 RESERVED SDIO_DMA 80010000 00010000 RESERVED ARGS 80020800 00000800 RESERVED DBGSER_DMA 80022000 00002000 RESERVED SER_DMA 80024000 00002000 RESERVED IR_DMA 80026000 00002000 RESERVED SLEEP 80028000 00002000 RESERVED EDBG 80030000 00020000 RESERVED ; DISPLAY 80100000 00100000 RESERVED ; camera DMA 用于摄像头DMA CAMERA 80050000 00110000 RESERVED DISPLAY 84800000 00100000 RESERVED CAMERA_CODE 84000000 00800000 RESERVED 在camera驱动中我是这么定义的 //----------------------------------yl2440 4.2-->5.0 BSP 's set--------------------------- // 1st Ping-pong Address #define COPIFRAMEBUFFER_A 0x30050000 // 320*240 * 2(RGB 16bit) * 4 frames = 614400 = 0x96000 // 0x30030000 + 0x96000 = 0x300c6000 //#define COPIFRAMEBUFFER_B 0x32000000 // Max buffer size of Port : 0x1c2000 (640*480+640*480*2/4)*4 #define COPIFRAMEBUFFER_B 0x34000000 // 0x32000000-->0x34000000 //要把CODE通道DMA地址放到不影响其他部分运行的RAM地址 #define VIRTUAL_OFFSET 0x7C000000 #define VIRTUAL_ADDR_OFFSET VIRTUAL_OFFSET // for MPEG4 中断的线程已经不停的执行,调用了 Display_Cam_Image(0,0, 240, 240, PORT_A);这明明是用来显示的,但是怎么会不出图像呢? ------------------------------------------找到一点问题了
引用 6 楼 morris88 的回复:
dma 的配置、启用、停止很简单,使用物理地址,网卡、硬盘等经常使用...
你贴的东西没用...


我觉得就是DMA使用的问题。

我在config.bib这样使用

CAMERA                80050000  00110000  RESERVED ——这个没有问题
——下面两个84000000 以上了就是超过34000000 /64M的 范围,导致DMA不能落在SDRAM映射范围以内了!
    DISPLAY            84800000  00100000  RESERVED——
    CAMERA_CODE        84000000  00800000  RESERVED

虽然我的内存是128M的,但是使用了不连续的映射方法,所以不出问题才怪!

引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


那我在config.bib使用 后面那块内存应该可以吧?

就是这里:DCD    0x94D00000, 0x34000000, 64      ; 64 MB SDRAM BANK 6——我使用的128M SDRAM 非连续方法扩展
让我纳闷的是。我把
;    DISPLAY            80100000  00100000  RESERVED

    DISPLAY            80138000  00100000  RESERVED
改了,在LCD驱动中没有改动,但是LCD照样能正常运行。这是怎么回事?如果不正确,那么LCD不是会黑屏吗?
有点进展了,我把原来的config.bib和内存映射文件替换了。

但是非常郁闷,图像直接显示在LCD上,不会显示在应用程序上。并且,只显示一小部分,不知道咋回事,现在贴图。希望大家帮分析一下。

我发现一个奇怪的问题——这个图像刚好覆盖了wince的背景图标!当我把wince背景图标设为无得时候,这个摄像头也不再显示了,真不知道为什么会这样
引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


昨天看了一下代码,发现用DMA专用的内存分配函数分配DMA Buffer 比较合适,昨天出了奇怪的图像,现在重新搞。

// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtPreviewAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, Preview_Mem_Size, &g_PhysPreviewAddr, FALSE);
    if (pVirtPreviewAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Preview.\r\n")));
    }

    pVirtCodecAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, Codec_Mem_Size, &g_PhysCodecAddr, FALSE);
    if (pVirtCodecAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Codec.\r\n")));
    }
有了点进展,不过非常郁闷,自己产生异常了。

[CAM_HW] InterruptThread : Waiting For a Single Object

CameraCaptureThread(0)++
CamClockOn = 0
[CAM_HW] InterruptThread : bIdlePwrDown = TRUE
[CAM_HW] InterruptThread : Waiting For a Single Object

CAMERA: CIS_Open
IOCTL_CAM_GETINFO:Width=0, Height=0, Bytes=0, scale=0
WM_SIZE:wParam=0, nHeight=269, nCyCam=153
WM_PAINT:nCxCam=218, nCyCam=153
WM_PAINT:nCxCam=218, nCyCam=153
CamClockOn = 1
Prefetch Abort: Thread=988b2b3c Proc=81d26340 'device.exe'
AKY=ffffffff PC=024330b4(???+0x024330b4) RA=024330b4(???+0x024330b4) BVA=024330b4 FSR=00000005
怎么会出现个问号的异常呢?
对了,我想请教一下,打开config.bib里面的 AUTOSIZE=ON有影响吗?
这个世界真是无奇不有啊。
我把config.bib的 AUTOSIZE=ON
改为
AUTOSIZE=OFF

;0x30 / 0xff = 15%
  FSRAMPERCENT=0x30808080

固定程序内存和存储内存比例,一旦使用摄像头,居然死机了。改回来又好了。

这两天不停的尝试,做了很多无用功。
引用 28 楼 gooogleman 的回复:
引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtPreviewAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, Preview_Mem_Size, &g_PhysPreviewAddr, FALSE);
    if (pVirtPreviewAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Preview.\r\n")));
    }

    pVirtCodecAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, Codec_Mem_Size, &g_PhysCodecAddr, FALSE);
    if (pVirtCodecAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Codec.\r\n")));
    }


照着DMA专用的内存分配函数分配DMA Buffer 能够显示图像区域了,但是不知道怎么回事,却不能出现图像,采集到不停闪烁的花纹,请有经验的大哥们指导一下。
引用 34 楼 abo77281 的回复:
lz上面好象差不多了,有数据了,只不过是数据格式和大小可能有问题.

查下你的源图像的大小和编码格式有没有设置错?目标图像的大小有没有设置错。

camera要有dma buffer,你用HalAllocateCommonBuffer来开辟,只要用足够的ram就没有问题。查下你开辟的ram区大小,这个要根据图像的大小和编码格式来确定dma buffer的大小。 不要开辟小了,大了浪费内存,小了造成桢与桢数据重叠,显示模糊或是花屏。

查下你的显示区域…


是这样的。我使用config.bib预留内存的时候是可以显示图像的。难道真的是我计算错误了,初始化的代码在4.2BSP是已经正常使用的。

我算算。
越来越雷人了。我把
;    AUTOSIZE=ON
AUTOSIZE=OFF——这样图像只会出现一些有规律的蓝点。咋别人这么做就行呢。我已经改大了啊。
==========================================================
哈哈哈哈哈哈,搞定了!!!!!!!!!!图像显示正常了。

上面那个异常,刚好是有个东西没有改,造成异常了。
//要把CODE通道DMA地址放到不影响其他部分运行的RAM地址
//#define VIRTUAL_OFFSET 0x7C000000
#define VIRTUAL_OFFSET 0x70000000——这个才行的。
为什么是这个偏移地址,呢,因为在config.bib和内存映射文件决定了,4.2BSP和5.0BSP不同,所以这个也要做相应改变,否则会产生异常的。加上这个虚拟地址偏移地址刚好是uncached 的虚拟地址,可以在wince访问了 。但是,我有点纳闷的是
我使用动态申请DMA的方法却不行,即使我修改了虚拟地址偏移。也没有异常产生,按照道理这应该是可行并且比较有效利用
内存的办法的,实在是可惜了。以后有空再研究吧。
这天是最后一天期限,终于顺利完成任务,不然要扣钱的。谢谢各位了。这几天的郁闷让我学到了好多东西。
发个照片上来
虽然立宇泰有些驱动做的比较劣质,价格也挺贵,但是毕竟带我入了门。
哈哈。


 总结一下2440 OV9650 Camera驱动的流程:初始化接口(并打开电源,我的板子改了,我上次相当郁闷,用别人的驱动没有加入打开电源的动作
结果导致,初始化OV9650一直不成功,我还以为是什么问题,真是很弱智的错误)——》初始化中断,绑定线程——)等待线程中断——》
产生中断——》显示图像,更新图像。
最后,我要提醒的是config.bib的修改注意事项:不能随便删除config.bib的保内存(reserve),因为在这里删除换成别的,但是在驱动又
没有做相应修改的话,那么这个内存就会被不同的驱动使用,撞车了,那么就会出现严重个后果,我上次死活不成功就是这个原因。后来我在
最后面增加内存给camera,遗憾的是这样可用内存被减小了很多。个人觉得使用动态申请时最合适的,可惜我失败了,不知道为什么三星的
其他DMA内存也在config.bib预留,如果全部使用动态申请不是更好吗?明白了!有时候只要不使用RAM区域来划分就没有必要了,现在我
直接在RAM区域画出内存给DMA了。郁闷!
 
posted on 2009-05-04 11:06  gooogleman.烟雨漓江  阅读(2764)  评论(5编辑  收藏  举报