分类: LINUX
2008-09-24 14:51:41
摘要:介绍了一个基于嵌入式Linux 的网络视频监控系统的设计与实现,重点阐述其嵌入式服务器软硬件部分的设计思想和体系架构,对其中涉及的若干关键技术进行了较为详细的介绍,最后完成应用程序向目标平台的移植,并最终实现视频监控调试和运行。
关键词:嵌入式系统;Linux;Video4Linux;S3C2410;网络视频监控
引言
随着计算机技术及网络技术的迅猛发展,视频监控系统的发展趋势必然是全面数字化、网络化,即采用嵌入式网络摄像机,利用网络进行传输,利用嵌入式监控设备体积小巧、性能稳定、通讯便利等特点,将使视频监控无处不在。目前,我国基于嵌入式技术的网络视频监控系统刚刚起步,因此,研究并开发基于嵌入式系统的网络视频监控系统具有很大的工程实际意义。
本文针对网络视频监控设备的实际应用需求,结合图像采集和嵌入式系统两方面的新技术,设计了基于ARM 32 位单片机系统和图像采集存储系统的嵌入式网络视频监控设备,并实现了视频数据的采集、压缩与网络传输。
系统平台上的硬件系统
本文使用的系统平台硬件功能框图如图1 所示。该平台采用Samsung 公司的处理器S3C2410。该处理器内部集成了ARM公司ARM920T处理器核的32 位微控制器,资源丰富,带独立的16KB 的指令Cache 和16KB数据Cache,LCD控制器、RAM控制器、NAND闪存控制器、3 路UART、4 路DMA、4 路带PWM的Timer、并行I/O口、8 路10 位ADC、Touch Screen 接口、I2C 接口、I2S 接口、2 个USB接口控制器、2 路SPI,主频最高可达203MHz。在处理器丰富资源的基础上,还进行了相关的配置和扩展,平台配置了16MB 16 位的Flash和64MB 32位的SDRAM。通过以太网控制器芯片DM9000E扩展了一个网口,另外引出了一个HOST USB接口。通过在USB接口上外接一个带USB接口的摄像头,将采集到的视频图像数据放入输入缓冲区中。然后,将缓冲区的图像数据通过网络传输到远端计算机。
系统平台中的软件系统
Linux具有内核小,效率高,源代码开放,内核直接提供网络支持等优点。但嵌入式系统的硬件资源毕竟有限,因此不能直接把Linux 作为操作系统,需要针对具体的应用通过配置内核、裁减shell 和嵌入式C 库对系统进行定制,使整个系统能够存放到容量较小的Flash 中。Linux 的动态模块加载,使Linux的裁减极为方便,高度模块化的部件使添加非常容易。基于Linux 的上述优点,本文实现的平台使用的操作系统是对Linux 进行了定制的armlinux。
嵌入式系统软件开发通常采用交叉编译调试的方式。宿主机通常为Intel 处理器,而目标板如图1 所示为S3C2410,因此程序需要使用针对处理器特点的编译器才能生成在相应平台上可运行的代码。对于嵌入式Linux,宿主机PC 上应安装Linux系统,之后,在宿主机上建立交叉编译调试的开发环境。本文采用移植性很强的C 语言在宿主机上编写视频采集程序,再利用交叉编译调试工具编译链接生成可执行代码,最后向目标平台移植。
视频采集的实现
在Linux 下,设备驱动程序可以看成Linux 内核与外部设备之间的接口。设备驱动程序向应用程序屏蔽了硬件实现的细节,使得应用程序可以像操作普通文件一样来操作外部设备,可以使用和操作文件中相同的、标准的系统调用接口函数来完成对硬件设备的打开、关闭、读写和I/O 控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。
Video4Linux (V4L) 是Linux 中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列接口函数。对于USB 口摄像头,其驱动程序中需要提供基本的I/O 操作接口函数open,read,write,close 的实现。当应用程序对设备文件进行系统调用操作时,Linux 内核将通过file_operations 结构访问驱动程序提供的函数。在系统平台上对USB 口数码摄像头进行驱动,首先把USB 控制器驱动模块静态编译进内核,使平台中支持USB 接口,再在需要使用摄像头采集时,使用insmode 动态加载其驱动模块,这样摄像头就可正常工作了。
摄像头被驱动后,需要编写一个对视频流采集的应用程序。根据嵌入式系统开发特征,先在宿主机上编写应用程序,再使用交叉编译器进行编译链接,生成在目标平台的可执行文件。宿主机与目标板通信采用打印终端的方式进行交叉调试,成功后移植到目标平台。
采集程序实现过程如图2 所示。
首先打开视频设备,开启视频设备文件,在使用硬件设备之前要象存取普通的磁盘文件那样先打开设备文件。使用Open()调用。Open()调用成功后返回的文件描述符就代表了捕获设备硬件。成功开启设备文件后,通过调用video_get_capability() 和video_get_picture () 函数来获取设备的信息以及图像信息。视频设备开始工作后会有大量数据持续输入,为了提高设备的工作效率,采用MMAP 方式将设备映射到内存,以加速文件的I/O 操作,然后通过操作名为VIDIOCMCAPTURE的ioctl()函数调用启动捕获过程,完成一帧图像的捕获并将其存储到内存映射区,并使用操作名为VIDIOSYNC 的ioctl()调用等待完成。捕获完成以后关闭设备文件,调用close()函数即可完成设备文件的关闭。
网络传输及监控的实现
本文采用通过在Gqcam 程序中嵌入client 模块用来实现远程视频监控。Client 端与Server 端分别采用两个数组来存放操作指令。当Gqcam 需要对摄像头进行操作时,通过Client 服务将操作指令通过网络发送到Server,Server 端解析接收到的操作指令,根据解析到的指令启动相应操作,并将结果返回给Client,Gqcam 在得到正确的执行结果后继续下一步操作。Server 通过网络与Gqcam 实现互动,并将最终采集到的图像数据发送到Gqcam,由其实现监控图像的显示。
实现过程是将其对本地摄像头的操作通过网络连接变为对远端(服务器端)摄像头的操作,具体过程如图3 所示。在图像数据传送过程中,采用数据包传送方式来实现对数据传送的控制,以免出现图像数据的丢失或阻塞网络,因此,在编程实现时,将数据包大小定义为整数(如1000)字节,当最后剩余字节数不足时,也将其作为一个数据包传送到PC 机,从而实现数据传送的控制。
Client 端和Server 端收发数据实现部分代码如下:
int receive_image (int fd, void *databuf, int count) {//Client 端接收图像数据
……
for (i=0; i< (count/image_pack); i++) {
//接受数据量控制
if ((m=recv (ss, databuf+i*image_pack, image_pack, 0)) =
=image_pack) { //接收图像数据send (ss, &yes, 1,0);
n+=m;
}
……
}
if ((m=recv (ss, databuf+i*image_pack, count%image_pack,0)) ==count%image_pack) { send (ss, &yes, 1,0);
//接收最后剩余不足整包数据
n+=m;
}
……
int send_image (int fd, void *databuf, int count) { //Server 端发送图像数据
……
for (i=0; i< (fd/image_pack); i++) { //发送数据量控制
write (client_sockfd, buf+i*image_pack, image_pack); //发送图像数据
}
}
write (client_sockfd, buf+i*image_pack, fd%image_pack);
//发送最后剩余不足整包数据
……
结论
应用本文所述方法实现的网络视频监控,构成了一个智能终端设备,性能稳定,画面流畅,同时可以实现连续视频和图像的实时保存,可用于工厂、银行及小区等场合全天候的智能监控,具有广阔的市场和应用前景。