gdtyy 发表于 2007-3-16 10:12 ZLG-ARM ←返回版面 ****************************************** ecos增值包应用举例---视频监控终端方案 ****************************************** 2007/03/15 asdjf@163.com www.armecos.com ecos增值包提供了多线程调度、文件系统、TCP/IP协议栈、图形用户界面等完整功能,裁减配置能力强,特别适合中高端嵌入式应用开发。税控机、行驶记录仪、视频监控终端、网络传输设备等都可以考虑使用ecos平台简化设计,减少代码量。 下图是一个视频监控终端示意图: 键盘、烟雾/温度/红外传感器、I/O输出控制 ------------------------------- | DMA/中断 |--------->蓝牙模块 四路视频输入--------->| SAA7111 视音频 |--------->以太网Ethernet 一路音频输入/输出---->| A/D、D/A 编解码器 MCU |--------->GPRS、CDMA串口 | RTC | ------------------------------- 硬盘/CF卡/SD卡/USB存储设备 此系统包括四路视频输入(一路选通,支持CMOS摄像头、PAL/NTSC/用户自定义制式);一路音频输入输出;多种大容量存储外设,满足配置文件和视频文件存储;输入输出I/O设备;各种传感器探测;网络通信部分,满足远近距离音视频传输。 系统内部由A/D、D/A转换器,视音频编解码器,MCU子系统组成。 对于这么一个小系统,使用ecos增值包来设计是非常方便的。 存储设备:直接挂装文件系统,mount /hd、/cf、/sd、/usb,然后利用标准的文件操作函数读写各种介质上的数据。(项目进度可控) 输入输出设备:采用《第二讲硬件IO操作》和《第三讲ecos中断操作》可以非常容易地实现输入输出控制。键盘中断结构直接抄模板,I/O操作使用宏,便于移植。(项目进度可控) 网络传输设备:采用《第六讲串口操作》,将GPRS/CDMA的MODEM串口挂装到/dev/ser1上,ecos自动枚举串口,会自动识别出MODEM串口和各种版本的16C55x工业标准,编译时已经配置好是否需要RAM缓冲区及其大小(带缓冲区的自动基于中断驱动),用户只要操作抽象的串口文件即可。ecos自带完整协议栈,支持PPP、UDP、TCP,用户只要使用标准的socket编程(多播、组播、RTP/RTCP)即可。(项目进度可控) A/D、D/A设备:视频数据量大,采用DMA能大大减少压栈、出栈操作,提高效率。中断操作参考《第三讲》。SAA7111采用I2C接口,操作复杂,适宜使用C++编程,参考《第十三讲 宏、汇编、C和C++混合编程》。抽象I2C、EEPROM和SAA7111为C++对象: //====================================================== class CIICBus { private: //for video iic //for eeprom iic public: CIICBus(int who ); void SCLOut( IIC_LEVEL Level ); void SDAOut( IIC_LEVEL Level ); IIC_LEVEL SCLIn( void ); IIC_LEVEL SDAIn( void ); void BusDelay( int Count ); BOOL CheckBusState( void ); void BusStart( void ); void BusRepeatStart( void ); void BusStop( void ); void WriteByte( unsigned char Data ); void ReadByte( unsigned char &Data ); BOOL GetAck( void ); void SetAck( IIC_LEVEL ); static void Init(); static void Lock(); static void Unlock(); };//====================================================== class CEeprom : public CIICBus { private: cyg_mutex_t hMutex; public: CEeprom(); //:CIICBus( 0 ) { BusStop(); } public: void Init(); int Write( unsigned char *buf, unsigned char pos, unsigned char size ); int Read( unsigned char *buf, unsigned char pos, unsigned char size ); };//====================================================== class CSAA7111 : public CIICBus { private:#ifdef __ECOS__ //寄存器地址#endif protected: unsigned int m_BusTimeout; public: CSAA7111( unsigned int DelayConst = 10, unsigned int BusTimeout = 3 ) :CIICBus(1), m_BusTimeout( BusTimeout ) {} #ifdef __ECOS__ void Reset( void ); void PowerSave( BOOL Enable ); void ForbidOutput( BOOL Enable ); // operate CE, not FEI##endif public: BOOL Initialize( void ); BOOL WriteReg( unsigned char Reg, unsigned char Data ); BOOL ReadReg( unsigned char Reg, unsigned char &Data ); BOOL SetVideoSource( int CamNo ); BOOL GetVideoSource( int &CamNo ); BOOL CheckVideoSingal( ); void SetBusTimeout( unsigned int BusTimeout ) { m_BusTimeout = BusTimeout; } void GetBusTimeout( unsigned int &BusTimeout ) { BusTimeout = m_BusTimeout; } }; 对象化的SAA7111操作接近人类的思维习惯,初始化、读写寄存器、设置视频源、检测视频信号等思路非常清晰。利用《第十二讲 多目录下makefile的通用写法》中介绍的宏定义可以根据实际情况调节代码,如“#ifdef __ECOS__”。 视音频编解码器:采用自行设计的ASIC芯片HJV进行H.264视频压缩,视频编码器寄存器种类繁多,采用面向对象的设计方法可以保证代码质量。 class CHJVCodec { private: // HJ602 status // Video input // Display generation // Video output // Codec operation // Chip operation // video buffer management public: void WriteDecBuf void WriteDecBuf int ReadDecBuf private: void ValueBitrate void ValueChunkThreshold public: CHJVCodec // Chip IO#ifdef _ECOS_ void ReadReg void WriteReg void WriteRegNoMask void ReadDram void ReadDram void WriteDram void WriteDram void Vstrm_Out void GetStatus int CheckHW#endif void ReadTLB void WriteTLB void RegDump // Chip Initialization#ifdef _ECOS_ void HwReset void SwReset#endif void Initialize void InitReg void InitTLB // Clock Setting void SetClock void PowerSave // Video Input void SetViControl void SetViFilter void SetViSource void SetViTvFormat BOOL SetViScaling BOOL SetEncImgSize void SetDecImgSize // Codec Operation void SetIPFrame void SetAlgorithm void EncFastUpdate void SetEncVideoMode void SetEncPolicy void SetEncBitRate void SetStatisticsCtl void SetMBFresh // Display Generation void SetDeBlock void SetPipSrc void SetPipBorder void SetPipPos void SetPipScaling void SetPipBitmapSize void SetPipMirror void MainMirror void SetOSDCtl void SetFrameBufSize void SetDispScaling void SetDispUpdate void ManualUpdate // Display Interface void SetVoTvFormat void SetRGBDAC void SetDvOut void SetDoubleImgSize void SetPixelFetch void SetDispTiming void SetDispMode void SetDispLayout // Chip Operation#ifdef _ECOS_ void SetOperationMode#endif void SetHwIntLoop // Member data retrievel void GetDramSize void GetClock void GetViSource void GetViControl void GetViFilter void GetViScaling void GetEncImgSize void GetDecImgSize void GetIPFrame void GetAlgorithm void GetEncVideoMode void GetEncPolicy void GetEncBitRate void GetStatisticsCtl void GetDeBlock void GetPipCtl void GetMirror void GetOsdCtl void GetFrameBufSize void GetDispUpdate void GetVoCtl void GetOperationMode void GetHwIntLoop void SetEncodeMode void StartEncoding void SetVideoFormat void SetFrameRate void SetEncQuality void SetIFrameInterval void ResetBuffer }; 经过H.264和g.723.1/g.729压缩的视音频数据加上H.245控制经H.223合路,就可以实现串型码流的音频、视频、数据同时传输,Windows上的DirectX可以直接解码此音视频流数据。ecos库里带有H.264、MP4、MP3、G系列音视频编解码库,但软件运行太慢,即使DSP也显得芯片面积太大了,这里使用一小颗视音频编解码ASIC芯片。不过合路时的数据量仍然很大,对MCU速率有较高要求。 因为网络传输速率可变,所以需要实时调整视频源编码速率,以保证视频的连续实时,此时,要用到《第十讲 时间管理》里介绍的时间相关函数辅助计算编码速率,按照码源速率控制算法控制数据生成。 在访问一些临界资源时要采用《第十一讲 同步原语》介绍的同步函数进行控制。 好了,这只是ecos增值包的一个简单应用例子,介绍它的目的主要是让使用者明白文档中各章节的讲解是如何与实际项目联系起来的。以后再介绍行使记录仪的方案、路由器方案、VPN/防火墙方案等。 总之,ecos是一个不错的平台,学习和使用ecos增值包很有益处。