1 引言
随着计算机技术及网络技术的迅猛发展,视频监控系统的发展趋势必然 是全面数字化、网络化,即采用嵌入式网络摄像机,利用网络进行传输,并充分利用大规模集成电路和网络的科技成果,及体积小巧、性能稳定、通讯便利等特点, 将使监控无处不在成为现实。而目前,我国基于嵌入式技术的网络视频监控系统刚刚起步,所以研究并开发一种基于嵌入式系统的网络视频监控系统具有很大的工程实际意义。
本文针对网络视频监控设备的实际应用需求,有机的结合图像采集和嵌入式系统两方面的新技术,设计了基于arm 32位单片机系统和图像采集存储系统的嵌入式网络视频监控设备,并实现了视频数据的采集、压缩与网络传输。
2 arm与嵌入式网络视频监控设备
32位嵌入式处理器中有mips、 arm、m-core等等。arm(advanced risc machines)处理器本身是32位系统,其内核具有性能高、成本低和能耗省的特点。
支 持arm的嵌入式操作系统主要有:windows ce、vxworks、uclinux等[1]。uclinux是“micro-control-linux”缩写,意即“针对微控制领域而设计的 linux系统”[2]主要是面对没有mmu并且资源很少的嵌入式系统。高性能、高集成度将是嵌入式系统的发展方向[3]。“嵌入式网络视频监控设备”是 第三代数字监控设备,系统结构如图1:

图1 嵌入式网络视频监控设备系统结构
嵌入式网络视频监控设备体积小巧,具有图像采集、图像处理功能,带有以太网接 口,tcp/ip协议栈,性能比较稳定,可直接与internet互连,系统的扩展性很好,监控区域几乎无限,并且由于设备传输到网络上是数字化视频信 号,可直接利用软硬件进行处理。同时因为设备本身带有操作系统,因此可以方便的进行后续开发,增加用户所需功能,提高设备的智能程度。
3 嵌入式监控系统硬件模块的设计
3.1 系统总体设计
硬件系统可以分为三个模块:arm集成开发模块、图像采集模块、图像存储 控制模块。其中arm集成开发模块模块的cpu采用三星的s3c4510b;图像采集模块中的cmos图像采集芯片采用ommvision公司的 ov7620,镜头采用桑来斯公司生产的dsl103镜头;图像存储模块主要包括74ls244(八进制3状态线缓冲器),4040(12位二进制串行计数器),512k的sram cy7c1049。功能原理框图如图2所示。

图2 嵌入式网络监控设备原理框图
系统工作过程可分为主要两个步骤:图像数据存储和图像数据读出过程。系统上电之后,单片机将通过 i2c总线对cmos图像传感器的工作寄存器进行初始化设置,以便使图像传感器进入正常的工作状态,如开窗口位置、逐行扫描方式、自动曝光、自动平衡等。如果上位机需要调整cmos图像传感器的工作参数,则可以通过地址端口写入;随后,cmos图像传感器输出的8位图像数据在逻辑控制电路的协调控制下,顺 序存入静态ram构成的图像数据缓冲器。如果上位机没有发出读数据的命令,则此过程一直进行下去,新的图像数据不断地覆盖原有的数据;如果上位机发出读取 图像数据的命令,则等待一帧完整的图像写入后,单片机将cmos图像传感器的图像输出通道关闭,然后将sram中的数据顺序从io读入。读完一帧图像后, 再将cmos图像传感器的图像输出通道打开重新开始新的一帧图像的采集。
3.2 arm集成开发模块模块的设计
系统硬件结构框图如图3:

图3 arm集成开发环境硬件结构框图
本系统cpu s3c4510b是基于以太网应用系统的高性价比16/32位risc微控制器,内含一个由arm公司设计的16/32位arm7tdmi risc处理器,arm7tdmi为低功耗高性能的16/32位核。该cpu最适合用于对价格及功耗敏感的应用场合[3]。
系统中采用的 flash存储器mbm29f016在本系统中用来存放uclinux操作系统程序代码。sdram是高速的动态随机存取存储器,在系统中主要用作程序的 运行空间、数据及堆栈区。rtl8201是一种全双工以太网控制器,当系统中主处理器要向网上发送数据时,先将一帧数据通过远程dma通道送到 rtl8201中的发送缓存区,然后发出传送数据命令。rtl8201在完成了上一帧的发送后,再完成此帧的发送。rtl8201接收到的数据通过mac 比较,crc校验后,由fifo存到接收缓冲区,收满一帧后,以中断的方式通知主处理器。
3.3 ov7620摄像头模块电路设计
由于ov7620集成度高,外围电路设计非常简单,仅由石英晶体和一些电阻、电容等元件组成。
3.4 图像存储模块的硬件设计
图像存储模块采用两个计数器4040作为ram的地址信号,分别采集和读取利用pclk或arm的io脉冲信号作为计数器的时钟信号。本模块利用max+plusⅱ软件仿真了硬件时序,分析组合逻辑电路及时序逻辑 电路,验证了数字系统设计的准确性。
4 嵌入式系统控制软件的设计与实现
4.1 系统控制流程
系统软件模块主要在嵌入式操作系统uclinux下用c语言实现。其主要作用在于控制硬件设备,完成预定的图像采集、压缩、传输功能。按控制时序方向依次为i2c驱动程序、图像数据采集程序、图像压缩程序、网络传输程序四部分 组成。系统控制流程图4如下:

图4 系统控制流程图
如上图所示,当将要采集图像数据时,嵌入式系统通过i2c驱动程序设置ov7620内部寄存器的值,配置合适的图像格式。当一帧图像完全存储到sram后,启动图像采集程序,将sram中的数据读取到嵌入式系统内存中,并进行压缩,最后打包发送到网络上。
4.2 i2c驱动程序的原理与实现
系统上电之后,单片机将通过i2c总线对cmos图像传 感器的工作寄存器进行初始化设置,以便使图像传感器进入正常的工作状态,如开窗口位置、逐行扫描方式、自动曝光、自动白平衡等。如果上位机需要调整 cmos图像传感器的工作参数,则可以通过地址端口写入,虽然s3c4510b提供了i2c bus。但是目前市面上的uclinux则没有针对s3c4510b的i2c bus的驱动。
uclinux下i2c驱动程序主要数据结构及函数描述如下:
#define device_name "i2c"
/* 定义设备的名称 */
#define i2c_major 89
/* 定义主设备号 */
static volatile u8 priv_buf[128];
static struct semaphore i2c_samsung_sem;
static struct file_operations i2c_ops ;
/* iic 参数设置 */
typedef struct
{ int i2c_speed;
u8 i2c_slave;
u8 i2c_addrlen;
u8 i2c_operate;
int i2c_pagesize;
spinlock_t lock;
u8 *buf;
} i2c_private_t;
int __iNIt i2c_samsung_init( void );
/* 初始化函数 */
static ssize_t i2c_read (struct file * file ,char * buf, size_t count, loff_t * f_ops); /* 读数据函数 */
static ssize_t i2c_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops);/* 写数据函数 */
static ssize_t i2c_ioctl (struct inode * inode ,struct file * file,
unsigned int cmd, u32 data); /* 控制函数 */
static ssize_t i2c_open (struct inode * inode ,struct file * file);/* 打开设备函数 */
static ssize_t i2c_release(struct inode * inode ,struct file * file);/* 释放设备函数 */
static void s3c4510_i2c(int irq, void *dev_id, struct pt_regs *regs);/* i2c 中断句柄函数 */
int init_module(void)
/* 安装驱动程序模块函数 */
void cleanup_module( void )
/*卸载驱动程序模块函数 */
4.3 图像采集程序原理与实现
s3c4510b提供了18个可编程的通用i/o端口,用户可将每个端口配置为输入模式、输出模式或特殊功能模式,由片内的特殊功能寄存器iopmod和iopcon控制。
端口0-7的工作模式仅由iopmod寄存器控制,但通过设置iopcon寄 存器,端口8-11可用作外部中断请求intreq0-intreq3的输入,端口12、端口13可用作外部dma请求xdreq0、xdreq1的输入,端口14、端口15可作为外部dma请求的应答信号xdack0、xdack1,端口16可作为定时器0的溢出tout0,端口17可作为定时器1的 溢出tout1。
本设备图像采集程序源代码主要部分描述如下:
unsigned char image[40000];
//图像 大小为40000像素
#define iopmod(*(volatile unsigned *)0x03ff5000) #define iopcon (*(volatile unsigned *) 0x03ff5004) #define iodata (*(volatile unsigned *) 0x03ff5008) #include
void delay(unsigned int);
int main()
{int pix_no,x,i;
iopmod=0xffffff00;
//




