摘要:本文介绍了一种嵌入式视频图像压缩模块的USB接口设计方案,给出了该系统的硬件实现方案以及USB控制芯片CY7C68013在系统中的应用,并编写了USB固件程序、嵌入式操作系统Windows CE.net下的USB驱动程序和应用程序。
关键词:视频压缩;固件程序;驱动;USB总线
视频图像监控技术已经得到了广泛应用。但是在一些特殊场合,虽然并不需要实时图像监控,对图像的质量却有很高的要求。例如需要以图像画面作为证据的远程视频监视系统,H.261和H.263图像的质量已无法胜任,而是需要高质量的JPEG图像。所以研究和设计满足工业级要求的静态图像压缩模块对于特殊场合的视频图像监控有非常重要的意义。
在远程视频监控系统中,视频采集及压缩传送是不可或缺的重要组成。本文介绍了一种基于CY7C68013的JPEG视频压缩模块设计方案,它具有130万像素图像分辨率、压缩率大、接口简单等特点,可以方便地和USB主控设备结合在一起,由上位机通过软件指令控制拍摄、视频压缩和上传压缩图像数据,从而组成静态视频监控系统。
硬件结构
本文所开发的这套嵌入式视频图像压缩模块,其硬件框图见图1。上位机是嵌人式智能工业控制器。它是以S3C4510B为核心处理器, 采用ARM7TDMI RISC内核,在其上运行WinCE.Net 5.0操作系统。下位机由三个主芯片构成:CY7C68013、S1D13718和K9650FB模块。CY7C68013是一款集成USB2.0的微处理器,在单片机上集成了USB2.0收发器、串行接口引擎(SIE)、增强的8051微控制器和可编程的外围接口,支持USB1.1和USB2.0协议。S1D13718是图像引擎芯片,负责JPEG编解码。视频采集模块采用K9650FB模块,它内部包含CMOS摄像头和图像处理芯片OV9650,输出图像最大可为130万像素,并具有标准的视频接口和OmniVision公司自定义的SCCB配置总线。系统上位机与远程监控系统组成局域网,以接收远程监控系统的命令和上传图片数据。上位机通过USB总线将各种与拍摄相关的命令发送给CY7C68013,最后在CY7C68013的固件程序里具体实现SID13718和K9650FB的初始化,并从S1D13718片内RAM中取出压缩好的JPEG图片上传。
图1 硬件结构框图
软件设计
本设计中USB软件设计包括3部分:固件程序、USB设备驱动程序和应用程序。
固件程序
在外部EEPROM中存放有CY7C68013固件程序,该程序在上电后加载到8051内核,主要完成两项功能:对USB设备进行配置及实现USB数据传输;实现对S1D13718和K9650FB的初始化。
USB传输方式分为4种:控制传输、批量传输、同步传输和中断传输。考虑到实际应用环境和复杂度,在开发中使用了控制传输和批量传输。控制传输主要用来完成主机对设备的配置和各种控制操作。批量传输主要用来完成上位机和CY7C68013之间的图像数据传输。固件程序流程如图2所示。
图2 固件程序流程
在这里,步骤①~⑤主要是完成USB接口的初始化工作,而步骤⑥~⑩可以看作是任务派发阶段,完成USB事务及用户特定的任务。
驱动程序
WinCE.Net的USB系统软件由两层组成:上层为USB设备驱动程序层,即本文所研究的内容;底层为USB功能的实现层,包括主机控制器驱动HCD以及USB协议栈USBD两部分,这一层次由WinCE.Net操作系统本身提供。
WinCE.Net系统提供的两种驱动模型是本机驱动程序和流接口驱动程序。前者通常适用于集成到平台上的设备,后者为一般类型的驱动程序,适用于大部分平台外部连接的设备。流接口驱动程序表现为在用户一级的动态链接库DLL,用来实现一组固定的函数——流接口函数,这些流接口函数使得应用程序可以通过文件系统访问这些驱动程序。本文采用了流接口驱动程序。图3说明了流接口驱动程序的工作结构。应用程序通过文件系统的API函数调用流接口函数,然后由流接口驱动程序调用本机驱动,或者通过设备管理器与系统内核或外围设备打交道。
图3 流接口驱动程序的工作结构
编写Wi nCE.Net系统下USB总线设备的驱动程序必须实现的三个入口函数USBDeviceAttach()、 USBInstallDriver()、USBUninstallDriver(),这是WinCE.Net系统编写的USB协议栈的要求,这三个函数本身也体现了USB总线设备与其他设备驱动程序不同的编写特征。在设备接到主机上后,系统底层的USB总线功能实现层会将检测到的设备基本信息及设备某功能接口的有关信息提供给上层,USBDeviceAttach()等函数会接受该信息,从而为客户端驱动的下一步工作打下基础;另外,也能更好地进行必要的注册表项设置。在WinCE.Net系统中,设备的配置信息都是存储在系统注册表中,因此,有关具体设备的必要信息和一些附加信息可以在USBInstallDriver()中实现注册,而USBUninstallDriver()函数负责卸载这些注册的设备信息。
一个具体的流接口驱动程序跟注册表部分肯定是分不开的。这里,我们将自己写的一个注册表文件通过添加组件的方式添加到内核中。下面是这个注册表文件的内容。
[HKEY_LOCAL_MACHINE\ Drivers\USB\LoadClients\JPEG]
“Index”=dword:1
“Prefix”=“JPEG”
//设备名称为JPEG
“DLL”=“MyDriver.dll”
//驱动名称,其中包括上文提到的三个入口函数和DLL接口函数
“Order”=dword:0
当有外设插入后,系统在取得VID/PID后将自动在注册表中寻找是否有这一项,依据注册表找到驱动程序dll文件后,将首先调用USBInstallDriver函数,该函数使用USBD.dll中的函数注册设备,并依据VID/PID设置注册表项,这样在这个项不丢失的时候,下次插入将能够自动找到;如果这个函数的VID/PID和实际设备不符,将返回失败;USBInstallDriver成功之后,系统调用USBDeviceAttach函数;该函数的主要实现内容有三个:
(1) 分配设备对象结构,利用系统传递上来的设备接口数据填写该设备对象结构成员变量值,从而在流驱动函数中作为参数传递设备信息;
(2) 创建获取中断设备数据的线程,注册线程处理回调函数;
(3) 在设备对象结构填写完毕后调用ActivateDevice()系统函数,并向系统注册该驱动程序,激活该设备驱动程序。最后调用RegisterNotificationRoutine()函数登记注册DeviceNotify函数——这个函数是必须的,在设备被移走后调用这个函数完成善后工作。
驱动加载完成后,用户程序再用CreateFile打开设备的时候,将返回驱动程序上下文给用户程序,这样用户程序和驱动就可以交互了。在本驱动中,所有对S1D13718和K9650FB模块的操作都是通过DeviceIoControl()函数映射到JPEG_Iocontrol来完成。下面是部分驱动程序。
BOOL JPEG_IOControl( DWORD hOpenConext, DWORD dwCode,DWORD* pBufin,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{ switch(dwCode)
{
case Cameral_INITIAL:
//初始化数字Camera接口
Break;
case Enable_JPEG:
//使能JPEG模块
Break;
case Initial_JPEG:
//初始化JPEG模块并启动JPEG编码
Break;
case READ_JPEG
//读取一幅图片
Break;
Else:
Break;
}
}
应用程序
本文上位机的应用程序是在Embedded Visual C++开发环境下使用WIN32 API开发的。由于在Win32系统中,每一外部设备都可以抽象为文件,USB设备同样可以作为系统文件来进行操作,所以在应用程序调用文件操作API函数,就可以实现与驱动程序中的USB设备通信。在本系统中,利用CreateFile()、CloseFile()函数取得或关闭USB设备句柄,用DeviceloControl()函数来进行系统控制,ReadFile()函数进行读取图像。
结语
本文介绍了嵌入式视频图像压缩模块的USB接口设计方案,可以成功地进行每秒一帧1300×1028的图片拍摄、JPEG压缩和在USB1.1协议下的上传,最后通过以太网将图片传到远程监控中心,从而组成静态视频监控系统。该模块已经得到实现并在防窃电远程监控系统中得到应用。■