祝夏雨,熊九龙,王志虎,王晓明
(国防科技大学 机电工程与自动化学院,长沙 410073)
达芬奇平台的嵌入式Linux图像采集与显示
祝夏雨,熊九龙,王志虎,王晓明
(国防科技大学 机电工程与自动化学院,长沙 410073)
在模式识别等领域,需要进行实时快速的图像处理。本文设计了基于达芬奇系列芯片TMS320DM6446的硬件平台,介绍了建立Linux开发环境的方法,利用Video4Linux和framebuffer实现了基于嵌入式Linux的USB摄像头图像采集与显示,采集到的图像可以直接送给DSP内核,进行高速的图像处理。
达芬奇;Linux;图像采集;DM6446;Video4Linux;framebuffer;USB摄像头
嵌入式图像采集系统具有体积小、成本低、稳定性高等优点,在远程可视电话、计算机视觉、网络会议等领域应用广泛。然而,一些图像处理领域,如无人驾驶、模式识别,对运算速度、运算量要求较高,传统的基于ARM芯片的嵌入式图像采集系统往往无法满足这一要求。
TI公司的达芬奇技术集成了DSP内核和ARM内核,是典型的基于共享存储的嵌入式多处理器环境[1]。它既具有ARM对外设强大的管理能力,又拥有DSP对数据信号的高速处理能力,因而可以很好地满足图像处理对运算速度和运算量的要求。
Linux操作系统具有内核稳定、功能强大、支持多种硬件平台、源代码开放、可裁剪和低成本等众多优点,使其在嵌入式领域备受青睐。
本文在基于达芬奇技术的嵌入式linux平台上,利用OV511为控制芯片的网眼2000 USB摄像头为采集模块,使用Video4Linux内核API接口函数以及framebuffer编写相应的程序,实现了图像的采集与显示,为DSP内核后续的图像处理奠定了基础。
本文使用的系统硬件平台采用TI公司的TMS320DM6446处理器(简称DM6446),它是一款双核嵌入式处理器,内部集成了ARM926EJS内核和C64x+DSP内核,DSP的数据处理能力达到4752 MIPS。该款芯片的ARM子系统是采用管道流水线的32位RISC处理器,工作频率高达297 MHz,带有独立的16 KB的指令Cache,8 KB的数据Cache,16 KB RAM,16 KB ROM[2]。其片上外设还包括USB接口、10M/100M以太网卡、UART接口、SPI接口。在处理器丰富资源的基础上,还进行了扩展,配置了128 MB 32位的SDRAM和128 MB的FLASH。另外,还配有分辨率为320×240的256色LCD。系统框图如图1所示。
图1 系统框图
2.1 主机开发环境的建立
ARM的开发一般需要三个系统,即Windows系统、PC-Linux系统、ARM-Linux系统。其各自的功能如图2所示。
图2 三系统功能图
三系统的搭建有两种方法:一种是三台分立的单系统机器组合,一种是一台双系统PC机和一台单系统ARM开发板。本文采用后一种方式,一可以节约硬件资源,二可以使开发流程、开发环境的搭建更加简单。
本系统PC机采用WindowsXP+VMware虚拟机+Linux的开发环境。其中VMware采用的是6.0版本,Linux采用的是较为成熟的Redhat9,内核版本是2.4.20。
2.2 交叉编译环境的建立
在进入嵌入式开发之前,还需要建立一个交叉开发环境,这是一套编译器、连接器和libc库等组成的开发环境[3]。其开发模型如图3所示。
图3 交叉开发模式
图3中,TARGET是目标板,HOST是开发主机。在开发主机上,可以安装开发工具,编辑、编译目标板的Linux引导程序、内核和文件系统,然后在目标板上运行。这种在主机环境下开发,在目标板上运行的开发模式叫做交叉开发。
构建交叉开发环境,首先要安装交叉编译工具链。Linux使用GUN的工具,社区的开发者已经编译出了常用体系结构的工具链,从因特网上下载ARM体系结构的编译器,安装即可。安装后需要在环境变量PATH中添加路径,该路径必须是工具链的安装路径,这样就可以直接使用arm-linux-gcc命令了。
2.3 内核定制
嵌入式系统的存储空间有限,要将Linux用于嵌入式系统就得对Linux操作系统进行定制(或叫裁剪),使整个Linux系统能够存放到容量较小的开发板FLASH中[4]。
由于本系统采用OV511芯片的USB摄像头进行图像采集,所以在定制内核时,一定要使内核支持USB总线和OV511摄像头。此外,视频采集设备的正常使用依赖于对 Video4Linux驱动程序的支持,所以在定制内核时也要添加这一项支持。
在定制内核时,应该选中:
[*]Video for Linux
[*]support for usb
[*]USB ov511 Camera Support
Video4Linux(简称V4L)是Linux中关于视频设备的内核驱动,它为针对视频设备的应用程序编程提供一系列接口函数,这些视频设备包括TV卡、视频捕捉卡和USB摄像头等。在Linux环境下,利用V4L应用程序接口获取视频图像,可以通过调用open()、ioctl()等函数,像操作普通文件一样,进行视频硬件初始化、硬件属性设置和硬件中断调用等操作。
视频采集程序的基本流程如图4所示。
图4 视频采集流程
V4L模块提供的主要API函数有:VIDIOCGCAP函数,以数据结构video_capability返回视频采集设备的基本信息,包括设备名称、设备类型、信道数、最大及最小像素高度和宽度等;VIDIOCSPICT函数,使用数据结构video_picture来获取和设置采集图像帧的属性,如亮度、色调、对比度、调色板等[5];VIDIOCGMBUG函数,使用数据结构video_mbuf获得摄像头设备图像存储的相关信息;VIDIOCMCAPTURE函数用于视频采集。以上函数都可以在videodev.h文件中查看定义。
首先必须声明两个头文件sys/types.h、linux/videodev.h,接着利用open函数打开视频设备,其中设备文件为/dev/video0。随后,调用ioctl(fd, VIDIOCGCAP, &capability)函数的VIDIOCGCAP宏命令,获取有关视频设备的基本信息。接着,调用ioctl(fd, VIDIOCGPICT, &picture)函数的VIDIOCGPICT宏命令,获取所采集图像的属性。至此,图像采集的前期准备工作已经完成。接着就是关键的图像采集部分。
图像采集有两种方法:一种是用内存映射方式读取图像,一种是直接读取视频设备。本文采用前者,获取图像的关键代码如下:
struct video_mmap mmap;
/*定义video_mmap型结构变量mmap*/
/*以下为设置图像缓冲区信息*/
mmap.frame=1;
/*采集帧数为2帧,交替出现,以完成显示图像的连续性*/
mmap.height=320; /*图像高度*/
mmap.width=480; /*图像宽度*/
mmap.format= picture.palette; /*图像的调色板格式*/
struct video_mbuf mbuf;
ioctl(fd, VIDIOCGMBUG ,& mbuf);
/*获取存储图像的内存大小*/
unsigned char *map = mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0) /*内存映像*/
ioctl(fd, VIDIOCMCAPTURE, & mmap) /*采集图像*/
截取图像后还要调用函数ioctl(fd, VIDIOCSYNC, &frame)进行同步操作,函数返回0表示图像已经获取完毕。图像存储在以map为起始地址,长度为mbuf.size的存储空间中。map +mbuf.offsets[frame_current]处。其中frame_current=0,即为第一帧的位置,frame_current=1,为第二帧的位置。由于DSP内核和ARM内核是共享DDR内存的,所以ARM可以直接传递该数据地址指针给DSP内核进行图像处理,无需大块的数据搬移。
Framebuffer(帧缓冲),它作为基础图形设施,是出现在Linux2.2内核当中的一种驱动程序接口,是作为其他高级图形或者图形应用程序的基本函数库。这种接口将显示设备抽象为帧缓冲区。用户可以将它看成是显示内存的一个映像,而不必关心物理显存的位置、换页机制等等具体细节,这些都是由Framebuffer设备驱动来完成的。只要将其映射到进程地址空间之后,就可以直接进行读/写操作,而写操作可以立即反应在屏幕上。该设备使用特殊的设备节点,通常位于/dev目录,如/dev/fb*。用户若要使用它,需要在编译内核时选中FrameBuffer[6]。其简单的使用程序如下:
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
int fb = open("/dev/fb0", O_RDWR);
ioctl ( fb, FBIOGET_FSCREENINFO, &finfo) ;
/*获取与Framebuffer有关的固定的信息*/
ioctl( fb, FBIOGET_VSCREENINFO, &vinfo) ;
/*获取与Framebuffer有关的可变信息*/
从vinfo和finfo中取得显存起始地址、分辨率、色深等信息,然后根据这些计算出需映射的显存的大小。
screensize=vinfo.xres*vinfo.yres*vinfo.bits_per_pixel/8;
/*计算显存所需的字节数,其中xres,yres,bits_per_pixel分别为x、y轴分辨率和色深*/
char * fbp = mmap ( 0 , screensize ,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
/*通过调用mmap()用来实现内存映射IO*/
由此便可以直接操作大小为screensize,起始地址为fbp的内存空间,利用Video4Linux采集的图像数据映射到Framebuffer的内存区域中,便可以直接显示到LCD上了。
如前所述,DaVinci是DSP和ARM双核架构的SOC芯片,ARM核负责芯片与外界的交互,DSP核处理相关算法,它们之间的通信和交互是通过引擎(Engine)和服务器(Server)来完成的[7],其框架如图5所示。
图5 Codec框架
Codec Engine是连接ARM和DSP的桥梁,是介于应用层(ARM端的应用程序)和信号处理层(DSP端的算法)之间的软件模块。ARM应用程序调用Codec Engine的VISA(Video, Image, Speech, Audio)API,以VIDENC_process(a、 b、 c)为例。首先,Codec Engine的stub(ARM端)会把参数a、b、c以及要调用DSP端process函数这个信息打包;随后,通过Engine SPI、OSAL和DSP Link传递给DSP;接着,Codec Engine的skeleton(DSP端)会解开这个包,把参数a、b、c转换成DSP端对应的参数x、y、z(比如ARM端传递的是虚拟地址,而DSP只能认物理地址);最后,DSP端的Codec server(优先级较低,负责和ARM通信的任务)会根据process这一信息创建一个DSP端的process(x, y, x)任务,最终实现VIDENC_process(a、b、c)的操作。
Linux代码完全开源,系统具有良好的移植性,可方便地进行各种扩展,利用嵌入式Linux进行的图像采集和显示运行稳定,效果良好。本文利用达芬奇平台实现了图像采集和显示,采集到的图像可以给DSP内核进行高速处理,为后续的工作奠定了基础,可广泛应用于对
Embedded Linux Image Acquisition and Display Based on DaVinci
Zhu Xiayu, Xiong Jiulong, Wang Zhihu, Wang Xiaoming
(School of Mechatronics Engineering and Automation, National University of Defense Technology, Changsha 410073,China)
Real time and fast image processing are needed in some field such as Pattern Recognition. This paper first designs the hardware platform based on TMS329DM6446, then introduces a method of building Linux development environment, finally achieves image acquisition and display of the USB camera based on Embedded Linux. The DSP kernel can realize image processing directly with high-speed.
DaVinci SoC; Linux; image acquisition; DM6446; Video4Linux; framebuffer; USB camera
TP391.41
A