论文部分内容阅读
摘要:将视频监控应用于输电线路防止外力破坏的工作中,是一个新的应用。介绍了输电线路视频监控系统嵌入式平台的软件框架,详细给出了各个部分的设计方案,并通过实验验证了设计的有效性。
关键词:输电线路;智能监控;嵌入式;软件框架
作者简介:唐洪良(1980-),男,江苏徐州人,浙江省杭州余杭供电局,工程师;孙磊(1983-),男,山东聊城人,浙江省杭州余杭供电局,助理工程师。(浙江?杭州?311106)
中图分类号:TM726?????文献标识码:A?????文章编号:1007-0079(2012)21-0141-03
随着本地经济的繁荣发展,工业与民用建筑、市政设施与建设在空间上不可避免地与输电线路发生接触,近年来通道隐患突出,外力破坏事件频繁发生,严重影响杭州余杭供电局的供电可靠性和电网的安全稳定。传统的线路通道危险点监管主要是“人防”为主,在当前输电线路里程不断增加、网架日益复杂、线路运行管理部门人员紧张、运维工作繁重的矛盾面前,采用提高通道巡视频率或人员现场蹲守已经困难重重,即便采用无线视频监控,人员也难以做到实时查看监视影像,加之没有预警告警机制,仍然无法有效解决防外破问题。
鉴于以上视频监控方案存在的不足,采用基于计算机视觉技术的智能视频监控,替代人员工作对输电线路本体及通道进行监控预警。该智能监控前端采用嵌入式软硬件系统,本文对涉及的软件框架进行了研究设计,经实际系统应用测试,证明功能完备、可靠性高。
一、嵌入式软件设计方案
嵌入式系统是将先进的计算机技术、半导体技术以及电子技术和各个行业的具体应用相结合后的产物,必须根据应用需求对软硬件进行裁剪,满足应用系统的功能、可靠性、成本、体积等要求。本文所述嵌入式平台下的程序功能是实现输电线路视频智能监控前端对摄像机模拟视频输入的采集、RGB格式的转换、图像的压缩和传输,以便服务器接收图片后存储并提供给用户显示,同时可以通过对客户端网页进行操作,实现与监控节点控制命令传输、云台控制和摄像机调整等功能。监控前端程序包括三部分线程程序:图像处理线程capture_video()、音频报警线程audio_play()和控制命令消息线程message_rec()。图像处理线程capture_video()是嵌入式平台的主线程程序,包括图像采集和格式转换程序、JPEG编码与传输程序,该部分软件是在配置好的嵌入式内核环境下,基于视频图像采集相关函数进行集成开发实现,图像处理线程程序流程如图1所示。消息线程程序包含控制命令传输与解析、云台控制和看门狗程序,音频报警线程实现声音报警。
1.嵌入式开发环境
开发环境主要包括一台安装有Linux操作系统的宿主机和DVS357开发板,宿主机操作系统是Windows XP,通过VMware Workstation 7安装openSUSE 11.0 Linux操作系统,开发板与宿主机直连至一个交换机,处于同一网络中[1],如图2所示。在Linux 服务器上安装工具链,建立交叉编译环境,Windows工作台通过串口和JTAG与DVS357 开发平台连接,可以在Windows 操作系统进行界面交互和在Linux 服务器上进行程序开发[2],最终将交叉编译后的可执行文件下载至目标机启动运行。本系统通过SDK安装与配置、NFS挂载文件系统、TFTP的配置、BootLoader烧录、内核编译和嵌入式自启动脚本程序修改六个步骤完成软件开发环境的搭建。
2.图像采集与格式转换
(1)图像采集。DVS357的图像采集模块实现将模拟视频信号转换成数字视频信号的功能。图像采集程序的流程图如图3所示。
主要函数实现过程如下:
先创建设备实例,对设备输入指针进行赋值Capture_Attrs.videoInput= CaptureEnv ->videoInput,保存视频输入指针信息至数据结构,然后系统调用Venc_create(hEngine,envp->videoEncoder)创建视频编码模块准备进行视频流采集;
调用Capture_detectVideoStd(NULL,&videoStd,&cAttrs)函数检测输入视频流的标准,videoStd中记录了相应视频格式NTSC或PAL,通过判断然后设置相应的格式;
然后通过调用envp->imageWidth = dim.width,envp->imageHeight = dim.height,对图像宽和高等基本信息进行配置;
接着调用Buffer_getUserPtr(hCapBuf)函数获取一个缓冲区用于存放图像采集数据;
最后调用Capture_create(NULL,&cAttrs)函数,返回该实例的句柄,如果句柄为空则提示创建采集设备失败,跳转至出错线程进行处理,如果成功则开始启动图像采集。
(2)格式转换。视频监控领域中数字视频的色彩空间不同于计算机显示的色彩空间,视频监控领域采用由一个亮度信号(Y)和两个色差信号U、V组成的YUV空间,其中U=R-Y、V=B-Y,采用YUV色彩空间能明显减少数据储存空间和数据传输带宽,利于网络传输。数字图像处理领域采用RGB色彩模型,彩色图像每个像素点都用R、G、B三个分量表示,每个分量的灰阶均为0~255。本系统中,需要将YUV格式转换为RGB格式,为后期图像处理做准备。
本系统DVS357从摄像机接收到原始未处理的YCbCr 4:2:2格式的视频数据,其中4:2:2表示每4个像素有4个亮度分量,2个Cb和Cr色差分量,色差信道的采样率是亮度信道的一半。视频数据在内存中存放的码流为:U0 Y0 V1 Y1 U2Y2 V3 Y3,通过映射出像素点后码流为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]。在内存缓冲区中获取UYVY码流后,将每个像素点通过以下三个公式转换为RGB格式:
具体实现时,通过查表法完成图像数据格式由YUV到RGB的转换,构造出4个1*256的一维系数数组,表示每一个系数的变化值。格式转换程序流程图如图4所示。
3.JPEG编码与传输
(1)JPEG编码。一张像素为720*576的图像占用近1.2M字节,本系统的通信环境为无线网络,其带宽限制大数据量的传输,必须对视频单帧图像进行压缩。JPEG格式压缩是将图像中的高频信息进行压缩,对一般色彩信息丰富的图像具有较好的压缩效果,普遍应用于无线网络传输,不仅可以减少图像的网络传输时间,而且提高了传输服务质量。对于单帧720*560像素的图像,JPEG编码的压缩率能够达到几十倍,以30倍压缩率为例,图像则可以压缩到40KB左右,而且图像压缩质量也可在保证在50%以上,既保证了图像质量,也满足了图像对无线传输带宽要求。系统采用开源库IJG(Independent JPEG Group[3])完成图像的JPEG编码。JPEG图像压缩程序流程图如图5所示。
(1)图像传输。压缩后的图像数据存储在内存缓冲区中,在嵌入式Linux操作系统下通过网络服务访问服务器文件系统中的资源,系统采取mount命令挂载服务器的NFS文件系统来实现。
在PC机Linux 操作系统中,在/nfs/usr/下通过mkdir pls 命令新建一个名为pls的文件夹,进入pls文件夹,通过mkdir pls_init新建一个pls_init文件夹用来存放我们将要编写的pls_init.c脚本程序,其代码如下:
#include
#include
main()
{
while(fopen("mnt2/PLS_PICS/001/pls_node","rb")==NULL)
{
system("mount -o tcp -o nolock 192.168.1.151:PLS01 mnt2")//挂载文件
}
system("mnt2/PLS_PICS/001/pls_node");
}
宿主机通过命令arm_v5t_le-gcc pls_init.c –o pls_init交叉编译,生成可执行文件并下载至目标板,同时在初始化文件rc.loca中添加上述脚本文件,DVS357上电启动初始化时会自动执行该应用程序,从而完成与服务器文件系统的挂载。其中参数说明如下:tcp规定NFS使用TCP协议;nolock表示禁用文件锁;61.155.106.89 指明了NFS文件服务器的主机IP地址;PLS01是服务器的一个文件共享;mnt2是嵌入Linux系统中的文件,它指定该文件系统在本地计算机上的挂载文件。在嵌入式Linux系统内通过操作mnt2来访问服务器Windows系统指定的共享文件。
挂载至服务器PLS01文件夹后,然后在节点程序可以通过读取内存缓冲区中的数据向服务器文件夹直接写数据,完成图像的传输过程。由于服务器时刻读取该文件夹下的图片进行显示,这会造成写文件与读取文件冲突,为避免出错,通过调用flock()函数建立互斥锁定。在打开文件后,需要在对文件读写之前进行flock锁定,在对图像完全写至目标文件后再进行flock解锁。不过注意的是flock不提供锁检查,即在用flock之前需要用户自己去检查一下是否已经上锁,读写文件之前必须检查判断flock文件是否上锁,若上锁则flock将会阻塞在那里,必须等待解除解锁。
4.控制命令的传输与解析
服务器与节点之间的控制命令传输采用了Socket通信模式。服务器发送命令至节点,节点通过对命令的解析判断执行相应的操作。为保证对节点控制过程的正确性,定义相应的通信协议数据帧,包括命令字1和+命令字2两部分,分别都用3个字节,如表1。将监控节点作为Socket的客户端,服务器作为Socket的服务端,服务器与节点之间从建立连接到最后通信的步骤如下:
(1)服务端必须首先启动调用socket(int af,int type,int protocol)函数创建一个套接字,其中第一个参数af是一个地址描述,支持AF_INET和AF_UNIX格式,第二参数type指定套接字类型,第三个参数是所有协议,实现函数如下:
if((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
printf(“failed to create socket!”);
}
创建成功后会返回文件描述符,失败时返回-1,可以查看错误信息记录文件查找错误原因。
(2)绑定本机地址和端口号,将套接字描述符和一个指针传递给一个地址结构,同时也传递结构的长度,bind函数如下:
int bind(Socket s,const struct sockaddr *locadr,,int namelen);
其中s是没有绑定的套接字描述符,该描述符就是调用socket()函数的返回值,locadr是地址结构,通常随着网络的不同而不同,需要在绑定前对其初始化。系统采用TCP/IP网络协议,对协议族、端口和IP初始化后进行绑定,实现代码如下:
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.s_addr = inet_addr(IP);
if(bind(sockfd,(structsockaddr*)&servadr,sizeof(struct sockaddr))==-1)
{ printf(“failed to bind socket!”);
}
(3)将相应的套接字设置成侦听方式,不断探测客户机的连接请求,通过调用listen函数在套接字上监听,函数原型是int listen(SOCKET s,int backlog),第一个参数是进行侦听的套接字描述符,第二个参数backlog则是告知应用程序能够接收多少个连接请求,设置成功后返回0。
(4)一旦服务器的套接字设置成侦听状态,就可以接收客户机的连接请求,客户端通过connect()函数发起连接,而服务器由accpet()函数接收连接,函数实现原型如下:
int connect(Socket s,const struct sockaddr*servaddr,socklen_t addrlen);
int accept(Socket s,struct sockaddr*addr,int*addrlen);
其中参数s是服务器应用程序中调用了listen()函数的那个侦听套接字的描述符,后两个参数返回所连接的客户机套接字的地址,由于事先知道服务器IP地址,客户端程序不需要保存。当客户端发送的连接请求被服务器成功接收时,accept()函数将返回一个新的套接字描述符,这个新的套接字将用来处理客户机与服务器之间的连接和数据传输工作,而原来的侦听套接字将继续侦听新的连接请求,若连接错误则返回INVALID_SOCKET的错误信息。服务器必须保证对所有客户机的侦听,必须将accept()函数设置为非阻塞模式,否则服务器会一直等待侦听,系统不能进行其它操作,耗费了服务器的资源,通过调用fcntl(sockfd,F_SETFL,O_NONBLOCK)函数设置。
(5)当客户机套接字和服务器套接字建立连接之后,就可以通过send(Socket s,,const char *buf,int len,int flag)和recv(Socket s,,const char *buf,int len,int flag)函数进行数据传输。本系统服务器向客户机发送6字节控制命令,而客户机则接收控制命令并解析执行相应的动作。
(6)执行完命令动作后调用close(int sockfd)函数关闭套接字,服务器继续监听等待客户端连接请求。
将该部分功能代码通过单独的一个消息线程去实现,以保证节点的实时响应[4],节点接收解析服务器命令后执行音频报警和云台控制等相应操作。
5.音频报警
音频的播放软件设计主要是在DVS357提供的SDK基础上集成实现,其中inputBuffer和outputBuffer作为音频输入和输出接口的缓冲区,通过inputBuffer接口读取需要播放的音频信息,再通过outputBuffe接口输出音频内容。本系统采取方式是通过将5秒钟录音写成文件,存储在节点嵌入式平台文件中,通过接收服务器指令解析后打开该文件,并将该文件的句柄传到设备文件的入口,可以通过该方法实现播放声音,在程序中可以通过修改宏设置采样频率调节声音的品质,音频线程函数的核心代码段如下:
void *audio_thread_fxn(void *envByRef)
{
if((int)read(outfile,inputBuffer,blksize)< blksize){
// 读取文件
ERR("Error reading the data from file descriptor %d ",inputFd);
status = AUDIO_THREAD_FAILURE;
goto cleanup;
if(write(outputFd,outputBuffer,blksize)== -1)
{
//写入设备
ERR("Error writing the data to file descriptor %d ",outputFd);
status = AUDIO_THREAD_FAILURE;
goto cleanup;
}
}
close(outfile);
}
二、软件功能分析
为了验证软件设计的有效性和可靠性,在服务器端编写展示软件用于显示通过嵌入式端采集、压缩、传输至服务器端的图像数据,系统的通行环境选择3G网络,嵌入式端将采集的模拟视频信号经过JPEG编码压缩后,通过网络传输至服务器端,如图6所示。同时,监控中心可以正常控制云台上下左右转动。
三、结语
本文介绍了输电线路视频监控系统嵌入式平台的软件总体构成,并对各个部分的设计方案实现方式进行了详细的分析。实验结果表明,本文所述的视频监控系统的嵌入式端软件运行良好,为该系统的应用奠定了技术基础。
参考文献:
[1]Karim Yaghmour.构建嵌入式LINUX系统[M].北京:中国电力出版社,2004:21-95.
[2]韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008:58-73.
[3]汤霄峰.基于Internet的嵌入式远程监控系统的研究与实现[D].长沙:湖南大学,2009.
[4]杨锋,桂卫华,陈峰.Win32环境下基于VC++ 6.0串口通信编程方法[J].计算机技术与自动化,2004,23(2):70-73.
(责任编辑:刘辉)
关键词:输电线路;智能监控;嵌入式;软件框架
作者简介:唐洪良(1980-),男,江苏徐州人,浙江省杭州余杭供电局,工程师;孙磊(1983-),男,山东聊城人,浙江省杭州余杭供电局,助理工程师。(浙江?杭州?311106)
中图分类号:TM726?????文献标识码:A?????文章编号:1007-0079(2012)21-0141-03
随着本地经济的繁荣发展,工业与民用建筑、市政设施与建设在空间上不可避免地与输电线路发生接触,近年来通道隐患突出,外力破坏事件频繁发生,严重影响杭州余杭供电局的供电可靠性和电网的安全稳定。传统的线路通道危险点监管主要是“人防”为主,在当前输电线路里程不断增加、网架日益复杂、线路运行管理部门人员紧张、运维工作繁重的矛盾面前,采用提高通道巡视频率或人员现场蹲守已经困难重重,即便采用无线视频监控,人员也难以做到实时查看监视影像,加之没有预警告警机制,仍然无法有效解决防外破问题。
鉴于以上视频监控方案存在的不足,采用基于计算机视觉技术的智能视频监控,替代人员工作对输电线路本体及通道进行监控预警。该智能监控前端采用嵌入式软硬件系统,本文对涉及的软件框架进行了研究设计,经实际系统应用测试,证明功能完备、可靠性高。
一、嵌入式软件设计方案
嵌入式系统是将先进的计算机技术、半导体技术以及电子技术和各个行业的具体应用相结合后的产物,必须根据应用需求对软硬件进行裁剪,满足应用系统的功能、可靠性、成本、体积等要求。本文所述嵌入式平台下的程序功能是实现输电线路视频智能监控前端对摄像机模拟视频输入的采集、RGB格式的转换、图像的压缩和传输,以便服务器接收图片后存储并提供给用户显示,同时可以通过对客户端网页进行操作,实现与监控节点控制命令传输、云台控制和摄像机调整等功能。监控前端程序包括三部分线程程序:图像处理线程capture_video()、音频报警线程audio_play()和控制命令消息线程message_rec()。图像处理线程capture_video()是嵌入式平台的主线程程序,包括图像采集和格式转换程序、JPEG编码与传输程序,该部分软件是在配置好的嵌入式内核环境下,基于视频图像采集相关函数进行集成开发实现,图像处理线程程序流程如图1所示。消息线程程序包含控制命令传输与解析、云台控制和看门狗程序,音频报警线程实现声音报警。
1.嵌入式开发环境
开发环境主要包括一台安装有Linux操作系统的宿主机和DVS357开发板,宿主机操作系统是Windows XP,通过VMware Workstation 7安装openSUSE 11.0 Linux操作系统,开发板与宿主机直连至一个交换机,处于同一网络中[1],如图2所示。在Linux 服务器上安装工具链,建立交叉编译环境,Windows工作台通过串口和JTAG与DVS357 开发平台连接,可以在Windows 操作系统进行界面交互和在Linux 服务器上进行程序开发[2],最终将交叉编译后的可执行文件下载至目标机启动运行。本系统通过SDK安装与配置、NFS挂载文件系统、TFTP的配置、BootLoader烧录、内核编译和嵌入式自启动脚本程序修改六个步骤完成软件开发环境的搭建。
2.图像采集与格式转换
(1)图像采集。DVS357的图像采集模块实现将模拟视频信号转换成数字视频信号的功能。图像采集程序的流程图如图3所示。
主要函数实现过程如下:
先创建设备实例,对设备输入指针进行赋值Capture_Attrs.videoInput= CaptureEnv ->videoInput,保存视频输入指针信息至数据结构,然后系统调用Venc_create(hEngine,envp->videoEncoder)创建视频编码模块准备进行视频流采集;
调用Capture_detectVideoStd(NULL,&videoStd,&cAttrs)函数检测输入视频流的标准,videoStd中记录了相应视频格式NTSC或PAL,通过判断然后设置相应的格式;
然后通过调用envp->imageWidth = dim.width,envp->imageHeight = dim.height,对图像宽和高等基本信息进行配置;
接着调用Buffer_getUserPtr(hCapBuf)函数获取一个缓冲区用于存放图像采集数据;
最后调用Capture_create(NULL,&cAttrs)函数,返回该实例的句柄,如果句柄为空则提示创建采集设备失败,跳转至出错线程进行处理,如果成功则开始启动图像采集。
(2)格式转换。视频监控领域中数字视频的色彩空间不同于计算机显示的色彩空间,视频监控领域采用由一个亮度信号(Y)和两个色差信号U、V组成的YUV空间,其中U=R-Y、V=B-Y,采用YUV色彩空间能明显减少数据储存空间和数据传输带宽,利于网络传输。数字图像处理领域采用RGB色彩模型,彩色图像每个像素点都用R、G、B三个分量表示,每个分量的灰阶均为0~255。本系统中,需要将YUV格式转换为RGB格式,为后期图像处理做准备。
本系统DVS357从摄像机接收到原始未处理的YCbCr 4:2:2格式的视频数据,其中4:2:2表示每4个像素有4个亮度分量,2个Cb和Cr色差分量,色差信道的采样率是亮度信道的一半。视频数据在内存中存放的码流为:U0 Y0 V1 Y1 U2Y2 V3 Y3,通过映射出像素点后码流为:[Y0 U0 V1] [Y1 U0 V1] [Y2 U2 V3] [Y3 U2 V3]。在内存缓冲区中获取UYVY码流后,将每个像素点通过以下三个公式转换为RGB格式:
具体实现时,通过查表法完成图像数据格式由YUV到RGB的转换,构造出4个1*256的一维系数数组,表示每一个系数的变化值。格式转换程序流程图如图4所示。
3.JPEG编码与传输
(1)JPEG编码。一张像素为720*576的图像占用近1.2M字节,本系统的通信环境为无线网络,其带宽限制大数据量的传输,必须对视频单帧图像进行压缩。JPEG格式压缩是将图像中的高频信息进行压缩,对一般色彩信息丰富的图像具有较好的压缩效果,普遍应用于无线网络传输,不仅可以减少图像的网络传输时间,而且提高了传输服务质量。对于单帧720*560像素的图像,JPEG编码的压缩率能够达到几十倍,以30倍压缩率为例,图像则可以压缩到40KB左右,而且图像压缩质量也可在保证在50%以上,既保证了图像质量,也满足了图像对无线传输带宽要求。系统采用开源库IJG(Independent JPEG Group[3])完成图像的JPEG编码。JPEG图像压缩程序流程图如图5所示。
(1)图像传输。压缩后的图像数据存储在内存缓冲区中,在嵌入式Linux操作系统下通过网络服务访问服务器文件系统中的资源,系统采取mount命令挂载服务器的NFS文件系统来实现。
在PC机Linux 操作系统中,在/nfs/usr/下通过mkdir pls 命令新建一个名为pls的文件夹,进入pls文件夹,通过mkdir pls_init新建一个pls_init文件夹用来存放我们将要编写的pls_init.c脚本程序,其代码如下:
#include
#include
main()
{
while(fopen("mnt2/PLS_PICS/001/pls_node","rb")==NULL)
{
system("mount -o tcp -o nolock 192.168.1.151:PLS01 mnt2")//挂载文件
}
system("mnt2/PLS_PICS/001/pls_node");
}
宿主机通过命令arm_v5t_le-gcc pls_init.c –o pls_init交叉编译,生成可执行文件并下载至目标板,同时在初始化文件rc.loca中添加上述脚本文件,DVS357上电启动初始化时会自动执行该应用程序,从而完成与服务器文件系统的挂载。其中参数说明如下:tcp规定NFS使用TCP协议;nolock表示禁用文件锁;61.155.106.89 指明了NFS文件服务器的主机IP地址;PLS01是服务器的一个文件共享;mnt2是嵌入Linux系统中的文件,它指定该文件系统在本地计算机上的挂载文件。在嵌入式Linux系统内通过操作mnt2来访问服务器Windows系统指定的共享文件。
挂载至服务器PLS01文件夹后,然后在节点程序可以通过读取内存缓冲区中的数据向服务器文件夹直接写数据,完成图像的传输过程。由于服务器时刻读取该文件夹下的图片进行显示,这会造成写文件与读取文件冲突,为避免出错,通过调用flock()函数建立互斥锁定。在打开文件后,需要在对文件读写之前进行flock锁定,在对图像完全写至目标文件后再进行flock解锁。不过注意的是flock不提供锁检查,即在用flock之前需要用户自己去检查一下是否已经上锁,读写文件之前必须检查判断flock文件是否上锁,若上锁则flock将会阻塞在那里,必须等待解除解锁。
4.控制命令的传输与解析
服务器与节点之间的控制命令传输采用了Socket通信模式。服务器发送命令至节点,节点通过对命令的解析判断执行相应的操作。为保证对节点控制过程的正确性,定义相应的通信协议数据帧,包括命令字1和+命令字2两部分,分别都用3个字节,如表1。将监控节点作为Socket的客户端,服务器作为Socket的服务端,服务器与节点之间从建立连接到最后通信的步骤如下:
(1)服务端必须首先启动调用socket(int af,int type,int protocol)函数创建一个套接字,其中第一个参数af是一个地址描述,支持AF_INET和AF_UNIX格式,第二参数type指定套接字类型,第三个参数是所有协议,实现函数如下:
if((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
printf(“failed to create socket!”);
}
创建成功后会返回文件描述符,失败时返回-1,可以查看错误信息记录文件查找错误原因。
(2)绑定本机地址和端口号,将套接字描述符和一个指针传递给一个地址结构,同时也传递结构的长度,bind函数如下:
int bind(Socket s,const struct sockaddr *locadr,,int namelen);
其中s是没有绑定的套接字描述符,该描述符就是调用socket()函数的返回值,locadr是地址结构,通常随着网络的不同而不同,需要在绑定前对其初始化。系统采用TCP/IP网络协议,对协议族、端口和IP初始化后进行绑定,实现代码如下:
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.s_addr = inet_addr(IP);
if(bind(sockfd,(structsockaddr*)&servadr,sizeof(struct sockaddr))==-1)
{ printf(“failed to bind socket!”);
}
(3)将相应的套接字设置成侦听方式,不断探测客户机的连接请求,通过调用listen函数在套接字上监听,函数原型是int listen(SOCKET s,int backlog),第一个参数是进行侦听的套接字描述符,第二个参数backlog则是告知应用程序能够接收多少个连接请求,设置成功后返回0。
(4)一旦服务器的套接字设置成侦听状态,就可以接收客户机的连接请求,客户端通过connect()函数发起连接,而服务器由accpet()函数接收连接,函数实现原型如下:
int connect(Socket s,const struct sockaddr*servaddr,socklen_t addrlen);
int accept(Socket s,struct sockaddr*addr,int*addrlen);
其中参数s是服务器应用程序中调用了listen()函数的那个侦听套接字的描述符,后两个参数返回所连接的客户机套接字的地址,由于事先知道服务器IP地址,客户端程序不需要保存。当客户端发送的连接请求被服务器成功接收时,accept()函数将返回一个新的套接字描述符,这个新的套接字将用来处理客户机与服务器之间的连接和数据传输工作,而原来的侦听套接字将继续侦听新的连接请求,若连接错误则返回INVALID_SOCKET的错误信息。服务器必须保证对所有客户机的侦听,必须将accept()函数设置为非阻塞模式,否则服务器会一直等待侦听,系统不能进行其它操作,耗费了服务器的资源,通过调用fcntl(sockfd,F_SETFL,O_NONBLOCK)函数设置。
(5)当客户机套接字和服务器套接字建立连接之后,就可以通过send(Socket s,,const char *buf,int len,int flag)和recv(Socket s,,const char *buf,int len,int flag)函数进行数据传输。本系统服务器向客户机发送6字节控制命令,而客户机则接收控制命令并解析执行相应的动作。
(6)执行完命令动作后调用close(int sockfd)函数关闭套接字,服务器继续监听等待客户端连接请求。
将该部分功能代码通过单独的一个消息线程去实现,以保证节点的实时响应[4],节点接收解析服务器命令后执行音频报警和云台控制等相应操作。
5.音频报警
音频的播放软件设计主要是在DVS357提供的SDK基础上集成实现,其中inputBuffer和outputBuffer作为音频输入和输出接口的缓冲区,通过inputBuffer接口读取需要播放的音频信息,再通过outputBuffe接口输出音频内容。本系统采取方式是通过将5秒钟录音写成文件,存储在节点嵌入式平台文件中,通过接收服务器指令解析后打开该文件,并将该文件的句柄传到设备文件的入口,可以通过该方法实现播放声音,在程序中可以通过修改宏设置采样频率调节声音的品质,音频线程函数的核心代码段如下:
void *audio_thread_fxn(void *envByRef)
{
if((int)read(outfile,inputBuffer,blksize)< blksize){
// 读取文件
ERR("Error reading the data from file descriptor %d ",inputFd);
status = AUDIO_THREAD_FAILURE;
goto cleanup;
if(write(outputFd,outputBuffer,blksize)== -1)
{
//写入设备
ERR("Error writing the data to file descriptor %d ",outputFd);
status = AUDIO_THREAD_FAILURE;
goto cleanup;
}
}
close(outfile);
}
二、软件功能分析
为了验证软件设计的有效性和可靠性,在服务器端编写展示软件用于显示通过嵌入式端采集、压缩、传输至服务器端的图像数据,系统的通行环境选择3G网络,嵌入式端将采集的模拟视频信号经过JPEG编码压缩后,通过网络传输至服务器端,如图6所示。同时,监控中心可以正常控制云台上下左右转动。
三、结语
本文介绍了输电线路视频监控系统嵌入式平台的软件总体构成,并对各个部分的设计方案实现方式进行了详细的分析。实验结果表明,本文所述的视频监控系统的嵌入式端软件运行良好,为该系统的应用奠定了技术基础。
参考文献:
[1]Karim Yaghmour.构建嵌入式LINUX系统[M].北京:中国电力出版社,2004:21-95.
[2]韦东山.嵌入式Linux应用开发完全手册[M].北京:人民邮电出版社,2008:58-73.
[3]汤霄峰.基于Internet的嵌入式远程监控系统的研究与实现[D].长沙:湖南大学,2009.
[4]杨锋,桂卫华,陈峰.Win32环境下基于VC++ 6.0串口通信编程方法[J].计算机技术与自动化,2004,23(2):70-73.
(责任编辑:刘辉)