第一篇:嵌入式视频采集系统的设计与实现_韩相军
嵌入式视频采集系统的设计与实现
首都师范大学% 韩相军关永王万森王雪立
Han,Xiangjun Guan,Yong Wang,Wansen Wang,Xueli 摘要!较为理想的嵌入式视频采集系统是基于!“# 的视频采集系统 & 本文重点阐述了嵌入式视频采集系统的硬 ’
软件设计
环节以及开发中的一些关键技术问题(首先以
$%”&’()%*+’
构建视频采集的硬件系统 & 详细介绍了 $,#-.-(’“//0.’.以
及所设计的视频采集系统原理 & 该系统在 12’3&((控制下能实时将视频像进行采集 ’
编码和传输)最后提出嵌入式系统的开
发流程并分析嵌入式系统开发中的一些问题 * 关键词!视频采集)嵌入式系统)”#$%&’(#)*& 中图分类号 +“,%-./* 文献标识码!0 01234563!45678 69:65565;<56= 27>?@A6 3B3?69 <3 ?C6;<56= 27>?@A6 3B3?69 :7365 =D!”EF ?C6 >7>6A
+.’’FG’HI’J&’’)K’.G&G’’&)G’% 引言
视频采集系统是数字图像获取的最基本手段 & 是
进行数字图像处理 + 多媒体和网络传输的前提 & 它可
为各种图像处理算法提供待处理的原始数字图像和 算法验证平台 & 随着人们对视频图像需求的激增和各 种图像和视频新的压缩标准相继提出 & 如
QP’*&’QP
’*+’REST’’REST+ 和
UEST’(((等 & 对高性能视频
采集系统的研究将成为一个热点 * 按系统的处理器不 同嵌入式视频采集系统大致可分为三类 VW.X 基于专用
视频图像芯片的视频采集系统)W’X 基于 EY 的视频采 集系统)W&X 基于)”E 的视频采集系统 * 基于专用视频图像芯片的视频采集系统其核心 处理单元为专用图像芯片 & 该图像芯片决定系统的功 能 & 其应用主要针对某一类产品 $ 如数码摄像机 %& 所
以具有一定的局限性 * 而基于 EY 机的视频采集系统
最为普遍的就是基于视频采集卡获取数字化视频信 息 & 通过运行相应的 EY 程序实现视频的采集 ’ 显示与 存储 & 但是目前基于 EY 的算法程序通常处理时间较 长 & 很难实现实时的图像处理应用 * 相比基于专用视频图像芯片和基于 EY 的视频采 集系统而言 & 嵌入式视频采集系统可完成视频的实时 采集 ’
传输以及各种视频压缩算法和图像处理算法的 实现 & 根据不同的应用 & 可以编制不同的图像处理程 序 & 所以具有更大的灵活性 & 并且设计与实现简单 & 硬
件设计一般采用基于)“E 的视频采集系统 F 即 ,YY)Z 视频信号处理芯片 ZYE[)]E^/SE_)Z)”E-的模式 实现 * 其中 & 视频信号处理芯片进行信号的 /)转换 & YE_)或 SE_)或 ]E^/ 用于视频采样控制 &)“E 对采
集的数据进行处理 * 嵌入式视频图像采集系统主要包 括硬件设计 ’
软件设计和操作系统 & 个部分 *.嵌
入式视频采集系统的硬件设计.P.视频采集系统的基本构成 基于)”E 的视频采集系统要求对视频信号具备 采集 ’
实时显示 & 对图像的处理和分析功能 * 因此 & 一
个视频采集系统通常可由如下五部分构成 V 视频图像 的采集 ’
视频图像的显示输出 ’
各种同步逻辑控制 ’ 视
频图像的分析和处理 ’
视频数据的存储 * 因此 & 对于视
频采集系统的基本构成可用图.所示框图描述 * 图.视频采集系统的基本框图
韩相军 # 硕士研究生
北京市自然科学基金资助项目 $*’)&’’-%)北京市教委
科技发展计划面上项目 $7E&’’).’’&F’.%%)北京市高 等学校 &’’H
年度教育教学改革立项项目 $&’’H’IH% 嵌入式系统应用 中文核心期刊!微计算机信息 “(嵌入式与 SOC)2006 年第 22 卷第 1-2 期 360元 / 年邮局订阅号 # 82-946!!”# 格式输出 $ 数据输出格式是通过 $%& 总线编程来 选择的 $’()*+,-的内部寄存器初始化也通过 $.& 串
行接口来完成 % 对于不同的输入制式 & 不同的采集要
求和不同的处理要求 $ 其帧缓存要求是不相同的 $ 如 对于)/012 制
$’314 5’67-+ 视频输入 $ 采样后按 89.9.格式输出 $ 一帧数据为
:.-!*:7!.“-6;<=>?@A$ 若
缓存三帧图像 $ 则需要 <=>?@A 空间的采集帧缓存 $ 若 按 89+9+ 格式输出 $ 则只需.=>?@A 的帧缓存 % 系统可选 择
;=!<.1>B@ 的 C24/= 在系统中即作为采集帧缓存 和处理后的数据帧缓存 $ 也可作下载程序的存储器使 用 % 系统提供串行接口 $ 可与外部设备进行通信和传 输图像数据 % 其中
DBEBFG DH.I<--J)K/ 实现以下四 点功能 # L+M 完成系统中视频采集和输出部分的同步信号 和消隐信号的控制 $ 其中主要包括 ’(),+,-和
C//:+%+ 的行同步信号 & 场同步信号 & 消隐信号 ’ L%N 将部分逻辑单元设计为 J$JO 作数据缓存 $ 完 成外接 J$JO 的同步读写控制 $ 承担 ’#),+,-与 2C)的数据传送工作 ’ P ’=C<.-2=78.与计 算机的数据通信工作以及从计算机加载各种图像处 理算法 ’ L8N 对 ’#)*+*-输出的数字图像进行预处理 $ 其中 主要包括图像数据的色度空间转换如!3# 到 4K5 的 转换 $ 数据格式转换如将 89.9.转换为 89.9-’ L*N 作数据总线接口 $ 实现数据的驱动传输等功能 % ’=C<.-2=78.在系统中是各类算法实现的核心 器件 $ 根据不同的应用场合 $ 可以编制不同的算法处 理程序 $ 使得该系统具有了很强的灵活性与通用性 % 值得强调的一点是为了便于操作系统中的其它外设 $ 在该系统中 $’=C<.-2=78.的外部存储器接口控制 寄存器必须配置为优先使用外部存储器模式 %!嵌 入式视频图像采集系统的软件 设计 一个完整的嵌入式系统由图 < 所示的 8 部分来 组成 % 图 < 嵌入式系统组成 图 < 中的底层是硬件系统 $ 核心是嵌入式处理器(嵌入芯片)$ 通常这样构成的系统又被称为是 CO& LC?I@AQ RF &SBTN 系统 % 在硬件系统的上面是 5C)L 板级 支持包 N$ 包括各种必要的对底层硬件系统的屏蔽 $ 引 导上层操作系统在硬件系统上的正确运行 % 操作系统 正确运行之后还需要开发各种设备驱动程序 $ 目的是 给用户的应用程序开发提供对底层设备的屏蔽 $ 提供 一个统一的用户开发接口 L/)$N% 5C)是指系统内核在特定的硬件系统上面运行所 需要的初始化代码和各种设备驱动程序 % 它主要包 括 # 系统初始化 $ 初始化 &)3 寄存器和测试 &)3 的型 号版本等 $ 它和 5RR@ERUVAW 中的初始化部分共同完成 所有的系统准备工作 $ 使得系统处于预期的稳定工作 状态 ’ 内存管理 $ 在没有 ==”L 内存管理单元 N 的系统 里面主要是数据 HUHSA 和程序 HUHSA 的管理 $ 在具有 ==“ 单元的系统中还要包括 ==” 的各种表的管理 $ 它主要用来实现内存的映射 ’ 中断控制器管理 $ 对于 一个 4’OC 来说 $ 中断是不可缺少的部分 % 嵌入式操作系统相关技术已经成熟 $ 由于 0BFXG 具有源码开放 & 开发工具丰富 & 技术支持广泛等特点 $ 视频图像采集系统选用嵌入式 0BFXG 操作系统 LYQ# >AVVAV 0BFXG OTAWU@BRF C?I@AQN% 0BFXG 中的中断管理 包括中断号的申请和释放 & 中断屏蔽和中断服务 & 中 断向量分配等 $ 时钟和设备驱动程序 % 驱动程序是利用操作系统提供的接口 $ 完成对底 层硬件的操作 % 驱动程序的开发 $ 是在操作系统提供 的接口基础上编写对底层硬件的操作和控制程序 $ 然 后加入到操作系统的内核 % 用户对某一个设备的访 问 $ 首先是将用户的各种操作传递给操作系统 $ 然后 由操作系统调用设备的驱动程序 $ 完成对硬件的各种 数据传输 $ 所以驱动程序必须要告诉操作系统该硬件 的各种操作程序的入口地址 % 特别对于 0BFXG 下的驱 动程序开发 $ 经过调试通过的驱动程序可以编译为一 个模块动态地装载入操作系统内核或者从操作系统 内核中删除 Z 因此驱动程序在 0BFXG 中是可以作为内 核的一部分来编写 % 对于用户程序开发 $ 与通用)& 上面开发应用程 序类似 % 但是在嵌入式应用中 $ 应用程序一般是作为 文件系统的一部分加入到操作系统的内核 $ 然后重新 编译内核 $ 最后生成一个可以执行的二进制压缩映像 文件加载到系统的存储空间 % 加载的加入了用户应用 程序的操作系统一般还必须固化 $ 烧到系统的 JEUIS 中 % 在系统运行时 $ 根据操作系统的 $*$’ 函数转到用 户程序执行 % “结 论 基于 2C)的视频采集系统 $ 由于可以灵活的修改 其图像处理算法 $ 它的应用主要面向用户的特定需求 和对实时性有较高要求的场合 % 随着技术的 L 见 +8;页 N BSP 嵌入式系统应用!现场总线技术应用 200 例.;”!“# 基于 $%& 的视频采集系统 图 # 给出了基于 ’(%)#*$(+,# 与 ’-&.!./ 构 成的视频采集系统 ”’(%)#/$(+,# 可以直接和视频 编解码器接口 “ 该系统可同时完成四路视频图像的实 时采集 # 传输以及各种视频压缩算法和图像处理算法 的实现 ” 根据不同的应用 “ 可以编制不同的图像处理 程序 $ ’(%)#/$(+,# 有自己的图像处理库函数 ” 可以 实现各类图像处理算法 $ 因此 “ 该系统具有更大的灵 活性与通用性 $ 图 # 基于 ’-&.!./ 与 $%& 的视频采集系统!”#“!’(%)#/$(+,# 简介 ’(%)#/$(+,# 是 ’0 推出的一款面向数字多媒体 应用的 $%&” 它在 ’0 的 1+,2 $%& 内核基础上进一步 集成了完备的视频 3 音频输入 3 输出接口 % 以太网接口 # &104++ 总线等片上外设 “ 不仅能使用户很方便地对音 频 5 视频等各种复杂的运算进行高速处理 ” 还能为方 便 # 无缝地接口视频 3 音频编解码器件和以太网 3&10 总 线等数据传输接口 & 因此 “ 它非常适用于-60&% 数字视 频服务器 % 多通道数字视频录像机 7$-89% 多通道数字 视频监控等应用 & $(+,# 的程序 3 数据空间以字节为单位进行统一 编址 ” 整个寻址空间为 ,:8& 其片上存储器 % 片上外 设 % 及外部存储器接口 7;(0<9 均映射到此 ,:8 的空间 中 & $(+,# 通过外部存贮器接口 7;(0<9 访问片外存储 器 7<=>?@%%$AB(%CBA’%B’B9“ 如图 # 所示 ”$(+,# 共有三个视频口 “ 分别为-&/%-&!和 -&-&/ 与-&!则与 (D8%&%(DB%& 复用引脚的 ” 其功能选择由 $(+,# 上的外设配置寄存器 7&;A1<:9 进行配置的 & $(+,# 支持多种外部接口!&10 接口 %E&0 接口和以太 网(B1 接口 “ 这些接口信号复用相同的引脚 ” 它们的 功能选择和配置是在上电复位时通过检测 $(+,# 上 的特殊引脚 7&10F;G%(B1F;G%E$.%&10F;;B09 的状 态来实现的 &!H#“# 视频 B3$ 采样电路!’-&.!./ 在图 # 系统中 ”’-&.!./ 是由 ’0 公司推出的一款 高性能视频解码器 “ 可将 G’%1%&BI 视频信号转换成 数字色差信号 7JC-,K#K#9” 支持两个复合视频或一个 % 端子输入 & 输出格式为 0’C 4A 8’L+.+“ 并支持 (>DM6NO?O6P ’(复制保护以及高级的-80 功能 & 不仅如 此 ”’-&.!./ 还具备了封装小 7)# 脚的 ’Q<&9% 功耗小 的特点 7R!./ST9& 因此 “ 它非常适用于便携 % 批量大 % 高质量和高性能的视频产品 & ’-&.!./ 可接受 # 路复 合视频信号 71-8%9 输入和!路超级视频信号 7%U-OVW6 即 %XYWMU-OVW6”J319 输入 & 该芯片包含一个扩展端口 ’ZU 端口(用于数字视频 ’ 双向半双工(“ 它可直接连接 倒(&;: 或视频电话进行编解码 $ ’-&.!./ 的图像端 口 ’0U 端口(支持 [ 位或!+ 位的输出数据并带辅助参 考数据可直接与-:B 控制器接口 $ ’-&.!./ 提供 0 # 1 总线接口 ” 其最高传输速率为 ,//]O^?_?“ 通过它可以 完成芯片的初始化以及设置修改等操作 $ ’-&.!./ 作 为 0 # 1 总线的从设备 ” 最多可配置为 # 个不同的从设 备地址 “ 一条 0 # 1 总线只能同时访问 # 个 ’-&.!./ 配 置口 ” 所以 $(+,# 可以连接 , 个 ’-&.!./“ 进行 , 路 视频输入 $!H#H)视频 $_B 电路!%BB‘!#!图 # 系统中视频 $_B 由视频编码器 %BB‘!#!完 成 $ %BB‘!#!支持 &BI 与 G’%1 格式的视频编码 ” 其 输入支持 8’H+.+ 格式的数字视频 $ %BB‘!#!有!路 复合视频 71-8%9 输出和!路超级视频 7%U-OVW6“J_19 输 出 ” 其系统像素时钟频率为!)H.(Ea“ 它可以直接接收(&;: 解码数据和采用 ,K#K# 格式每行 ‘#/ 有效像素 的 110A 兼容 JC-数据 ” 其内部包含同步 _ 时钟产生 器和数模转换器两部分电路 $ %BB‘!#! 同样需要通过 0 # 1 总线进行初始化和设置修改等操作 $ 从图 # 中可看出 “-&/ 既要做视频输入口 ” 也要支 持视频输出口 “ 即-&/ 可以工作在 1>Y^XMW 与 $O?Y=>b 两种作模式 $ 但这两种工作模式不能同时使用作模式 不能同时使用 $ 当-&/ 作为 [U 位的 8’H+.+ 视频采集 口时 ” 仅需视频数据流串行时钟和采集使能控制信 号 “ 串行数据流串行时钟由 ’-&.!./ 的 %1Ic” 采集使 能控制信号则由 ’-&.!./ 的 0G’A;Q_:&1I_-8Ic 引 脚配置为通用输出引脚来控制 “ 此时 %BB‘!#!E 不起 作用 $ 当-&/ 作为 [U 位的 8’H+.+ 显示口时 ”%BB‘!#!需要 E%JG17 行同步信号 9%-%JG17 场同步信号 9%II1 7#‘(Ea 的行锁存号 9 控制 $!H#H, 系统原理 图 # 系统其主要功能是完成视频图像的采集 % 处 理 % 存储和传输 $ 系统的视频输入可以是 G’%1%&BI 和 %;1B(制式的任何一种 “ 或者采用 % 端子输入 $ ’-&.!./ 完成视频信号的 B_$ 转换 ” 为后续处理提供 数字视频数据 “ 同时它还分离出行 % 场同步信号并输 出系统时钟供视频 $_B 芯片和 <0 EMAC/MDIO TVP5150 EMIF64 HPI16/HPI32 TMS320DM642 (600MHz 4800MIPS) EDMA 64 Channels L1P Cache 16KB L1D Cache 16KB L2 Cache 256KB Parallel executive Units 32 bit Timers 66MHZ PCI32 20/10b VP0 20/10b VP1 20/10b VP2A TVP5150 TVP5150 TVP5150 20/10b VP2B Xilinx XC2S300 FPGA SAA7121 嵌入式系统应用)变频器与软启动器应用 200 例 * #‘中文核心期刊!微计算机信息 ”(嵌入式与 SOC)2006 年第 22 卷第 1-2 期 360元 / 年邮局订阅号 # 82-946!!模糊量 $ 可归纳一系列控制规则 $ 例如规则!“ #$ %&!’(!)* +,-.&/!’ +!0* 1234 5!’ 6!7 %!8)909%%9:* : 为规则数 $+!)&+;0&% 及 6!为语言变量 $ 则由第;条规则构成的模糊关系为 # 6!* >.+!0 > 6!* 而对于一定 &? 和 &/?$ 相应的输出为 # 5!8@&?>.+!= >6!*A > @&/?>.+!B > 6!*A 则 #585!.!8)$0$%$:* 图 C 模糊控制框图 根据控制经验 $ 将其中将语言变量分成七级 # 正 大.D6*$ 正中.DE*$ 正小.DFG$ 零.H*$ 负小.,F*$ 负中.,E*$ 负大.,6*’ 在实际控制中 $ 由于被控对象只能接受一个 确定的控制信号 $ 而模糊推理是一个模糊集合 $ 因此 $ 必须建立精确量和模糊量之间的转换关系 9 即从输出 的模糊集合中 $ 判决出一个精确量(在此采用固定量 化因子 & 比例因子及隶属度最大原则 $ 进行离散推理 $ 求出各相应的控制表 $ 并将数据存入-FD 内存 $ 以便 在线使用 $ 实施实时控制(图 I 1J 中断采样子程序 软件采用定时器 1J 中断方式 9 中断服务子程序如 图 I 所示(系统每隔一个时间段进行一次中断 9 启动!K ” 转换 9 同时完成数据采集 & 数字 #$“ 控制 & 控制量输 出 & 温度显示及数据保存等功能(定时器 1)中断 $ 为-FD 处理器和计算机通讯 $ 发送数据 $ 便于计算机绘制 温度跟踪曲线 $ 键盘中断 $ 完成键盘扫描和获取键值(此外 9 为了减小系统在平衡位置的振荡 9 在软件上采取 了数据滤波 & 设定死区等措施(!结 语 基于-FD0LJM 模糊 N 数字 D;O 差热天平采用计算 机控制技术 $ 能够实现温度发控制 $ 并在液晶屏和计 算机上实时显示温度及温度跟踪曲线(实验中对控制 算法进行多次实验和调整 9 取得了很好的控制效果 $ 达 到了预期的设计目的(参考文献 @)A 安颖 9 刘丽娜 P 基于-FD 的高速信号采集与处理系统的设计)Q*% 微计 算机信息 $0JJC9)RCMNCS @0A 孙增圻 $ 等 P 智能控制理论与技术 @EAP 北京 # 清华大学出版社 $)SSMP @TA 于海生 $ 等 P 微型计算机控制技术 @EAP 北京 # 清华大学出版社 $)SSSP @LA 张念淮 $ 等 P 5F6 总线接口开发指南 @EAP 北京 # 国防工业出版社 $0JJ)作者简介 # 李智强 $ 男 $)SMI&$ 河南工业大学电气工程 学院 $ 硕士(籍贯 # 山东 + 郭广灵 $ 女 $)SM)&$ 河南工业 大学电气工程学院 $ 高级实验师(,!”###$ 河南郑州河南工业大学电气工程学院韩相军 关永王万森王雪立 %<166’7’ 12 F(21-G)/+1(H(7+(’’-+(78 <)I+/)6 J1-!G)6 *(+,’-.+/08K’+L+(78D###E$= &)(8M+)(7L;(@;)(8 N1(7 O)(78O)(.’(O)(78M;’6+ U 投稿日期 R0JJCPIP)IG U 修稿日期 R0JJCPIP0VG e α dt d ec E EC e c α U u D/A y D/A u α T0 A/D ADC FIFO 《 #’(技术应用)** 例》 DSP 开发与应用)LV 嵌入式远程视频采集系统的设计与实现(基于S3C2410) 发 布 时 间 : 2008-11-19 来 源 : 中电网 作 者 : 张永强,赵永勇,李崇德 浏 览 : 984 多媒体通信技术的发展为信息的获取和传输提供了丰富的手段,视频采集是其中不可缺少的重要组成部分,该系统基于S3C2410的ARM9芯片和嵌入式Linux操作系统,采用USB摄像头捕捉视频,经MPEG-4算法压缩编码,系统直接与网络相连,用户使用标准的网络浏览器和流媒体播放程序即可查看远程视频影像。硬件系统 系统硬件平台选用基于ARM9架构嵌入式芯片S3C2410,稳定工作在202MHz主频,板载64MB SDRAM 64MB FLASH,主板资源包括:主USB口、从USB口、10M/100M以太网口,触摸屏、彩色LCD、键盘、8个用户自定义LED数码管,A/D,RTC电路,2个串口、1个JTAG通用接口,音频模块,支持MPEG4,MP3编解码,3个168PIN的扩展插座,32位的数据总线,保留充分扩展空间。 其中标配模块包括:IC卡+PS2模块、IDE硬盘+CF卡模块、PCMCIA+SD/MMC模块。另外可选配模块有:GPS模块,GPRS模块,FPGA模块,CAN+AD+DA模块、红外模块、蓝牙模块、摄像头模块。软件系统 2.1 内核配置与USB摄像头驱动 假定已经搭建好嵌入式Linux的开发环境,下面第一步工作就是USB摄像头的安装与驱动。首先检查Linux Kernel中是否已经添加了USB模块的支持,并且加入Video4Linux支持。 Multimedia devices→Video For Linux Video For Linux→[*]V4L information in proc filesystem 在主菜单的USB Support下还有各种摄像头的驱动,选中将要使用的摄像头芯片类型。 <>USB IBM(Xirlink)C-it Camera support<*>USB OV511 Camera support<>USB Philips Cameras <>USB SE401 Camera support<>USB STV680(Pencam)Camera support<>USB 3com HomeConnect(akavicam)support 在USB摄像头选购时,优先考虑Linux内核公开支持的摄像头芯片,不然要额外编写相应的USB摄像头驱动程序,然后进行编译、安装。在此选用网眼公司的V3000产品,他采用了OV511的芯片。 确定USB摄像头被正常驱动后,下一步就是使用Video4Linux提供的API函数集来编写视频采集程序。 2.2 基于V4L设计的视频采集模块 在Linux下,所有外设都被看成是一种特殊的文件,称为设备文件。系统调用是内核和应用程序之间的接口,而设备驱动程序则是内核和外设之间的接口。他完成设备的初始化和释放、对设备文件的各种操作和中断处理等功能,为应用程序屏蔽了外设硬件的细节,使得应用程序可以像普通文件一样对外设进行操作。 Linux系统中的视频子系统Video4Linux为视频应用程序提供了一套统一的API,视频应用程序通过标准的系统调用即可操作各种不同的视频捕获设备。Video4Linux向虚拟文件系统注册视频设备文件,应用程序通过操作视频设备文件实现对视频设备的访问。 Linux下与Video4Linux相关设备及用途如表1所示。 这里主要针对设备文件/dev/video进行视频捕捉方面的程序设计。 Linux下视频采集流程如图2所示。 其中用到的主要函数有: Camera_open():用来开启视频设备文件,使用前需要首先声明一个video_device类型的设备文件。 Camera_get_capability():通过调用ioctl()函数取得设备文件的相关信息,并存放到video_capability结构里。 Camera_get_picture():通过调用ioctl()函数取得图像的相关信息,并且存放到video_picture结构里。 Camera_close():用来关闭设备文件。Camera_grab_image():用来抓取图像,采用mmap方式,直接将设备文件/dev/video0映射到内存,加速文件I/O操作,还可以使多个线程共享数据。 剩下的还有设备初始化、参数设备等相关函数,不再详述。 2.3 视频压缩编码模块 获取图像数据后,可以直接输出到FrameBuffer进行显示,由于本系统要将采集到的视频影响通过网络传输出去,所以在传输之前要对原始的图像数据进行压缩编码,在此选用MPEG-4视频编解码方案。和其他标准相比,MPEG-4压缩比更高,节省存储空间,图像质量更好,特别适合在低带宽条件下传输视频,并能保持图像的质量。 MPEG-4中基于对象的视频编码过程可以分为3步进行: (1)从原始视频流中分割视频对象。 (2)对视频对象进行编码,对不同视频对象的运动信息、形状信息、纹理信息分配不同的码字。对输入的任意形状的VOP序列,用基于块的混合编码技术编码,处理顺序是先IVOP后PVOP,BVOP。在对VOP的形状信息编码后,取得任意形状VOP的采样,每个VOP划分为不相交的宏块,每个宏块含有4个8×8象素块进行运动补偿以及纹理编码,已编码的VOP帧保存在帧存中,在当前VOP帧和已编码VOP帧之间的计算运动矢量;对将编码的块和宏块,计算他们的运动补偿预测误差;运动补偿预测后的IVOP及误差用8×8块DCT变换,并进行DCT系数的量化,然后是游程编码和熵编码。 (3)对各个视频对象的码流进行复合,每个视频对象的形状、运动纹理信息复合成VOL比特流,各视频对象视频流复合成统一的码流输出。对视频流进行压缩编码以后,接下来就要实现网络传输部分的功能。 2.4 JRTPLIB网络传输模块 流媒体指的是在网络中使用流技术传输的连续时基媒体,RTP是目前解决流媒体实时传输问题的好办法,JRTPLIB是一个面向对象的RTP库,他完全遵循RFC1889设计,下面讲述如何在Linux平台上运用RTP协议进行实时流媒体编程。 2.4.1 初始化 在使用JRTPLIB进行实时流媒体数据传输之前,首先应该生成RTPSession类的一个实例来表示此次RTP会话,然后调用Create()方法来对其进行初始化操作。RTPSession类的Create()方法只有一个参数,用来指明此次RTP会话所采用的端口号。 2.4.2 数据发送 当RTP会话成功建立起来之后,接下来就可以开始进行流媒体数据的实时传输了。首先需要设置好数据发送的目标地址,RTP协议允许同一会话存在多个目标地址,这可以通过调用RTPSession类的AddDestination()、DeleteDestination()和ClearDestinations()方法来完成。目标地址全部指定之后,接着就可以调用RTPSession类的SendPacket()方法,向所有的目标地址发送流媒体数据。 2.4.3 数据接收 对于流媒体数据的接收端,首先需要调用PollData()方法来接收发送过来的RTP或者RTCP数据报。由于同一个RTP会话中允许有多个参与者(源),因此既可以通过调用GotoFirstSource()和GotoNextSource()方法来遍历所有的源,也可以通过调用GotoFisstSourceWithDat()和GotoNextSourceWithData()方法来遍历那些携带有数据的源。在从RTP会话中检测出有效的数据源之后,接下去就可以调用RTPSession类的GetNextPacket()方法从中抽取RTP数据报,当接收到的RTP数据报处理完之后,要及时释放。 JRTPLIB为RTP数据报定义了3种接收模块,通过调用RTPSession类的SetReceiveMode()方法可以设置下列这些接收模式: RECEIVEMODE_ALL:缺省的接收模式,所有到达的RTP数据报都将被接受;RECEIVEMODE_IGNORESOME:除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝的发送者列表可以通过调用AddToIgnoreList(),DeleteFromIgnoreList()和ClearIgnoreList()方法来进行设置;RECEIVEMODE_ACCEPTSOME:除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList(),DeleteFromAcceptList和ClearAcceptList()方法来进行设置。 2.4.4 控制信息 JRTPLIB是一个高度封装后的RTP库,只要PollData()或者SendPacket()方法被成功调用,JRTPLIB就能够自动对达到的RTCP数据报进行处理,并且还会需在要的时候发送RTCP数据报,从而能够确保整个RTP会话过程的正确性。 在本系统中,使用RTPSession JRTPLIB类库提供的方法来实现底层的RTP/RTCP操作,并且把他封装在CrtpTransmitter类中,该类从Media Sink类继承而来,接收到相应的媒体帧数据,使用RTPSession类库的操作把数据发送到网络上。结语 本系统基于S3C2410平台和Linux操作系统,利用Video4Linux设计采集程序,使用MPEG-4压缩编码算法,通过实时流媒体传输技术实现了网络传输,整个系统具有稳定可靠、安装简便、成本低廉等特点,可扩展应用在工业控制、视频会议系统、可视电话、远程监控系统等诸多领域。 基于ARM的视频采集系统的设计与实现 摘要 本文根据家庭视频采集系统的要求,提出一种基于ARM的网络视频采集方案。方案要求视频的实时传输、实时监控。本系统以Intel Xscale 芯片和嵌入式Linux系统为平台,在平台中搭建网络视频服务器,并以它为中介,负责将USB摄像头采集到得视频数据传输到网络服务器中,最后发送到申请监控的远程PC机中,远程PC只需在网页中便能实时的看到监控端的视频图像。 论文首先阐述了嵌入式网络视频采集技术的发展、现状和前景,然后介绍了嵌入式硬件系统结构和嵌入式Linux操作系统的特点,阐述了嵌入式硬件整体结构,使大家大体的完整的对系统硬件有详细的了解,实际记录了嵌入式操作系统内核的编译和移植,介绍了Bootloader的基本原理和启动过程,实现了视频采集程序的编译和移植,研究了嵌入式一般驱动程序的使用。随后,本文详细描述了视频采集程序的整体结构框图和具体功能代码块、网络通信编程技术、图像编解码、嵌入式视频服。 关键词:ARM;嵌入式;Linux;视频采集 I 目录 摘 要.............................................................................................................................I 第1章 引言.................................................................................................................1 1.1 课题的背景和来源..........................................................................................1 1.2本文的内容及主要工作..................................................................................1 第2章 嵌入式ARM系统硬件结构简介..................................................................3 2.1 视频监控系统结构简介..................................................................................3 2.2 ARM处理器简介.............................................................................................3 2.3 XSCALE体系结构............................................................................................4 2.4 主要硬件电路说明..........................................................................................7 第3章 嵌入式ARM系统软件结构..........................................................................9 3.1 LINUX操作系统简介.......................................................................................9 3.2 交叉编译环境的建立....................................................................................10 3.3 嵌入式LINUX操作系统移植........................................................................11 3.3.1 BootLorder移植...................................................................................11 3.3.2 Linux 内核移植...................................................................................12 3.3.3 嵌入式文件系统.................................................................................13 3.4 LINUX下的程序调试.....................................................................................14 第4章 USB设备驱动程序设计...............................................................................15 4.1 设备驱动程序简介........................................................................................15 4.2 LINUX下驱动程序的实现.............................................................................18 4.3 USB摄像头驱动程序设计............................................................................20 第5章 视频采集功能的设计...................................................................................23 5.1 基于V4L的编程...........................................................................................24 5.1.1 摄像头相关数据结构.........................................................................24 5.1.2 摄像头基本功能实现.........................................................................25 5.1.3 视频数据采集.....................................................................................29 5.2 图像编解码....................................................................................................32 5.2.1 编解码介绍.........................................................................................32 5.2.2 系统压缩技术.....................................................................................33 第1章引言 1.1课题的背景和来源 二十一世纪的网络化、数字化让人们的生活每天都发生着翻天覆地的变化,获取信息的方便和快捷可以使人们在信息化的今天领先一步创造出巨大的利益,而获取信息的重要途径就是眼睛。据统计,人类采集信息的80%来自视觉。图像和视频是对客观事物生动、形象的描述,是一种最直观的表现方式。而视频监控技术因为它方便快捷、生动形象、信息丰富等特点日益受到人们的青睐,并在各行各业得到广泛的应用。与此同时,现代网络和数字技术的快速发展也为视频监控技术的发展奠定了坚实的基础。 二十一世纪,嵌入式技术、多媒体处理技术进一步发展,为视频监控系统的发展提供了新的出路——嵌入式视频监控系统。嵌入式系统是以应用为中心,软硬件可以剪裁,具有高稳定、低成本、功耗低、速度快、实时好的专用计算机系统,它由嵌入式微处理器,配以周边硬件设备,接口电路组成。嵌入式系统内部使用嵌入式操作系统,安装专用的功能软件。嵌入式技术把硬件和软件集于一体,独立工作。嵌入式视频监控系统比其他视频采集系统在布局区域范围上要广泛;由于使用IP技术,嵌入式视频监控技术比其他视频采集系统更具紧密的结合度,能够充分利用现代网络技术的成果,并能构成复杂的视频监控网络;性能上,嵌入式视频采集系统继承了嵌入式技术的优点,非常适合自动化的环境。 因此,嵌入式视频采集技术正在我国快速的发展,积极的研究会加强我们在这方面技术的学习,也会为视频监控技术的发展贡献力量。 1.2本文的内容及主要工作 根据毕业设计的初衷,我们需要设计基于ARM的网络视频采集系统。在监控系统中,视频采集、传输、播放的功能不是由专门视频处理芯片完成,而是由软件实现。 论文首先介绍了嵌入式ARM系统的硬件结构和软件结构,方便大家熟悉ARM和Linux系统,包括嵌入式设备的硬件结构,逻辑框图和Linux的基本操作、安装方法;第二,研究了嵌入式的一些驱动程序,主要是摄像头驱动程序 V4L,系统中选用的摄像头芯片——中星微301;第三,研究了视频监控的具体流程和实现方式,让大家在总体上对整个系统有一个大概的认知。 本次设计的目的只有一个,就是实现视频的实时监控。围绕它,不管是硬件结构还是软件流程,都需要学习和研究,不断调试,决不放弃。 总之,论文的内容都是围绕如何建立一个视频采集系统。无论是从哪个方面,我们都是为这个目标而努力。2 第2章嵌入式ARM系统硬件结构简介 2.1视频监控系统结构简介 网络视频监控系统是基于嵌入式技术设计的。嵌入式并没有统一的定义,但目前有一个广泛而又被认可的规范:将软件产品固化到硬件平台上,完成应有的功能既是嵌入式。 基于嵌入式ARM技术的视频监控系统服务器端采用摄像头不断的采集图像,压缩成视频流,然后通过网络发送到申请监控的客户端。监控系统的使用者可以在远程实现网页上的实时监控和一些简单的功能操作。系统整体结构如图2.1所示[1]。 LCDJTAG摄像头ZC301CPU单元Intel Xscale以太网控制器远程PC客户端SDRAMFLASH 图2.1 系统整体结构图 该系统中CPU采用基于ARM的PXA270微处理器,通过在其上运行Linux操作系统,执行Boa视频服务器,接受并处理来自摄像头的图像信号,通过以太网控制器发送至远端,实现视频数据的远程传输和接受,达到视频监控的目的[2]。 2.2ARM处理器简介 ARM,既是一个公司的名字,也是对一类微处理器的通称。ARM嵌入式微处理器是全球领先的16/32位RISK处理器芯片知识产权设计供应商ARM(AdvancedRISKMachines)公司的产品。ARM公司本身不直接从事芯片生产,而是依靠转让设计许可,由合作公司生产各具特色的芯片。 ARM处理器以其完整的体系结构,极小的体积、极低的功耗、极低的成本、极高的性能,及时根据嵌入对象的不同进行功能上的扩展的优势,在众多种类的嵌入式微处理器中脱颖而出。基于ARM技术的微处理器应用占据了32位RISC微处理器75%以上的市场份额,ARM技术正在逐步渗入到我们生活的各个方面。 采用RISC架构的ARM微处理器一般具有如下特点: (1)采用固定长度的指令格式,指令规整、简单、基本寻址方式有2~3种;(2)使用单周期指令,便于流水线操作执行; (3)大量使用寄存器,数据处理指令只对寄存器进行操作,以提高指令的执行效率; (4)所有的指令都可根据前面的执行结果决定是否被执行,从而提高指令的执行效率; (5)可用加载/存储指令批量传输数据,以提高数据的传输效率;(6)可在一条数据处理指令中同时完成逻辑处理和移位处理;(7)在循环处理中使用地址的自动增减来提高运行效率。 目前,ARM处理器有ARM7、ARM9、ARM9E、ARM10、ARM10E、SecurCore、StrongARM和XScale等系列。每个系列除了具有ARM体系结构的共同特点以外,都有各自的特点和应用领域。 2.3XScale体系结构 Xscale核是采用ARM V5TE架构的处理器,是Intel公司的StrongARM的升级换代产品,它具有高性能、低功耗等特点,并在流水线设计、DSP处理和指令设计中有很大改进[3]。ARM的体系结构是基于RISK的,XScale是ARM处理器的一种,所以XScale具有RISK的基本特性。而且针对嵌入式系统,XScale构架还引入了Pentium处理器工艺和系统结构技术,实现了Pentium微处理器体系结构的一系列高性能技术,达到了高性能、低功耗和小体积等嵌入式系统要求的特性。它的特点有:超流水线、高主频、存储体系、分支预测和指令集体系结构。本设计采用的就是基于英特尔Xscale构架的一种32位嵌入式处理器,它除了应用于掌上电脑之中外,还可以应用于智能手机、网络存储设备、骨干网路由器等电子设备。 PXA27x系列处理器是英特尔当前最新推出的嵌入式处理器。它的时钟频率从312到624MHz不等,并内建64MB的堆栈型Intel StrataFlash内存。内置了英特尔的无线MMX技术,能够显著提升多媒体性能。 OURS-PXA270-EP是一款基于INTEL XSCALE PXA270处理器,针对高效 嵌入式系统教学和实验科研的平台。这款设备主要包括核心板与底版两个部分,核心板主要集成了高速的PXA270 CPU,配套的存储器,网卡等设备;底版主要是各种类型的接口与扩展口。 核心板(8层PCB电路)系统包括: CPU: INTEL PXA270(520M),支持GDB调试; SDRAM: 64M 工作在104M外频上; FLASH: 32M INTEL Nor FLASH;Net: 10/100M Ethernet controller(LAN91C111);SUPERIO: WINBOND 83977;CPLD: XILINX 95144(117USER IO);总线驱动器: 若干;核心板正面如图2.2所示,核心板背面如图2.3所示。 SDRAMCPUdrvdrvCPLDdrvFLASHdrvdrvFLASHLDOdrv 图2.2 核心板正面图 SDRAMdrvEthernetdrvdrvdrv100PIN CONNECTORSuperIOLDO 图2.3 核心板背面图 底版(4层PCB电路)如图2.4所示。包括: Ethernet: 10/100接口1个 UART: 6个(包括RS232,RS485,IRDA,全功能串口)USB1.1:2个(1个host 一个device)PS2:2个(KEYBOARD&MOUSE)标准并口:1个 PCMCIA: 1个 IDE:1个 SD/MMC: 1个 SMC:1个 CAMERA:1个 96PIN功能扩展口:2个 4X5 小键盘 CPU_JTAG CPLD_JTAG LED SHARP LQ080V3DG01 8寸真彩LCD 640X480 VGA 640X480 LED 8X8点阵 一组7段LED数码管 4个 串口irda串口串口串口LCD接口LCD接口并口VGALED点阵音频1音频2音频3PCMCIA 卡LED数码管SMC 卡核心板SDPSPSUSBUSB485NET键盘 图2.4 底版图 2.4主要硬件电路说明 嵌入式设备除了以ARM芯片为主要控制单元,也有很多周边电路和外围设备,它们有的帮助ARM处理信号、有的负责存储数据、有的进行网络连接、有的用来数据通信,这些周边设备缺一不可,不能替代。 首先介绍CPU核心总线[4],总线是CPU和其他设备的桥梁。CPU是通过总线信号来控制SDRAM ,FLASH,网卡,SUPERIO等外部设备的,无论是低速还是高速,只要是与总线相关的芯片,都要和CPU总线信号有关。其次,研究嵌入式系统内存——SDRAM。SDRAM是嵌入式系统的内存,具有单位空间存储容量大和价格便宜的优点,已广泛应用在各种嵌入式系统中。当系统启动时,CPU首先从复位地址0x0处读取启动代码,在完成系统的初始化后,程序代码一般应调入SDRAM中运行,以提高系统的运行速度。同时,系统及用户堆栈、运行数据也都放在SDRAM中。SDRAM的存储单元可以理解为一个电容,总是倾向于放电,为避免数据丢失,必须定时刷新(充电)。因此,要在系统中使用SDRAM,就要求微处理器具有刷新控制逻辑,或在系统中另外加入刷新控制逻辑电路。PXA270芯片在片内具有独立的SDRAM刷新控制逻辑,可方便地与SDRAM接口。除了SDRAM,FLASH也是一种存储媒介。FLASH一般具有NOR型和NAND型。NAND型FLASH单元密度高,写入和擦除速度非常快,而且一般NAND型FLASH的存储容量很大。NOR型FLASH的优点是芯片内执行命令,这样应用程序可以直接在FLASH内运行,不用进入内存,使得它的传输效率很高。嵌入式设备最大的优点就是网络功能强大,它能像PC一样方便地连接到互联网上,这些功能都是网络控制器的作用。也就是Ethernet Controller,本系统采用SMSC公司的单芯片的网络控制器,LAN91C111。它可以工作在两种速度下,10M以太网或者100M以太网。LAN91C111的工作流程是,驱动程序将要发送的数据包按指定格式写入芯片并启动发送命令,LAN91C111会自动把数据包转换成物理帧格式在物理信道上传输;反之芯片收到物理信号后自动将其还原成数据,并按指定格式存放在芯片RAM中以便主机程序取用。就是LAN91C111完成数据包和电信号之间的相互转换。最后,说明一下串口电路,在嵌入式视频监控系统中,串口起到了很重要地作用,嵌入式系统启动的信息都可以通过串口传到PC上,极大地方便了系统的移植和软件的调试。大多数情况下,嵌入式CPU的串口0会作为CPU的一个终端,为用户与CPU交互提供基本的输出输入信息。当CPU运行BOOT代码时,通常只有这个终端 ;运行LINUX内核时,如果有LCD显示,串口0与LCD终端会同时有效。串口0终端的交互 方式是命令行的模式,在BOOT阶段,支持简单的BOOT命令。8 第3章嵌入式ARM系统软件结构 3.1Linux操作系统简介 Linux是一个类似Unix的操作系统,它起源于芬兰一个名为LinusTorvaldS的业余爱好者,现已成为最流行的一款开放源代码的操作系统。Linux从问世至今,短短时间内已发展成为一个功能强大、设计完善的操作系统。Linux系统不仅能够运行于PC平台,还在嵌入式系统方面大放光芒。由于Linux的源码开放,内核精简且性能强悍,不依赖于具体厂商,能广泛适用于各种硬件设备,系统二次开发成本极低,因此在IT业界已经达成共识,即采用嵌入式Linux作为嵌入式操作系统是大势所趋[5]。 嵌入式Linux是目前嵌入式系统领域中发展势头非常迅猛的系统。嵌入式Linux是指对Linux经过小型化裁剪后,能够固化在容量只有几百K字节或几M字节的存储器芯片或单片机中,应用于特定嵌入式场合的专用操作系统。目前正在开发的嵌入式系统中,49%的项目选择嵌入式Linux作为操作系统。嵌入式Linux现已成为嵌入式操作系统的理想选择[6]。目前基于嵌入式Linux的应用已经遍布很多领域,比如移动多媒体设备、手持设备、车载导航系统、机械控制等。嵌入式Linux分为两种类型:在没有使用MMU的平台上(无内存虚实地址转换和映射)的一般为uCLinux;而在有MMU平台上,则使用原本地嵌入式Linux版本。由于在目前的主流嵌入式ARM中大多不具有MMU,因此只用IM左右的内核就能实现网络功能和任务调度的Linux系统就可以适用于从高端服务器到嵌入式应用的各级平台。ARM技术和Linux成功地结合,应用于数以千计的商业产品中。从便携式消费品、网络和无线设备,到自动化设备、医疗设备和存储产品,这一应用列表与日俱增。ARM和Linux的结合充分满足了各类应用对嵌入式平台高性能、低功耗和低价格的要求,通过开发环境、开源社区和ARM的商业伙伴的优势为嵌入式开发提供了更灵活的选择。 本次设计的开发环境为redhat9.0系统,在Windows XP 下安装虚拟机,在虚拟机中安装Linux系统,这样可以屏蔽底层差别,避免硬件驱动带来的麻烦,而且还能方便的使用串口、并口、USB接口,快速的进入实验环境。图3.1为虚拟机下Linux系统启动后的情况。 图3.1 虚拟机下Linux操作系统 3.2交叉编译环境的建立 通常嵌入式系统的软件编译和执行是在两个不同平台上进行的。编译是在宿主机,一般为装有Linux的pc;执行是在目标机,即嵌入式系统的硬件平台。一般是在宿主机上通过跨平台交叉编译器把源文件编译成目标平台上可执行的文件,再通过串口、并口或者网络下载至目标平台上的FLASH或者其它存储介质,然后由目标机来运行这些软件。这里所说的跨平台编译器和一般的编译器功能类似,都是把源代码通过编译器编译成目标文件,然后通过链接器、可重定位器程序和定位器把目标文件重新定位成可执行文件。和通用的编译器之间最大的差别就在于跨平台编译器编译出来的可执行程序通常只能在特定CPU所属平台上运行。所以一般来说每种CPU都对应有不同的跨平台编译器。 本系统采用基于XScale的PXA270,可以使用常用的ARM-LINUX-GCC交叉编译器。要成功构建完整的交叉编译环境需要在宿主机上创建一系列的工具包括C/C++编译器、汇编器、链接器、嵌入式系统的标准C库和GDB代码级调试器。成功建立好开发环境后便可以运用这些工具进行嵌入式系统开发[7]。 3.3嵌入式Linux操作系统移植 3.3.1BootLorder移植 BootLoader是系统加电后运行的第一段代码。一般只是在启动时运行很短的时间,然而对一个嵌入式系统来说,这一部分却是整个系统的一个无比重要的组成部分,不可缺少。在一般嵌入式系统中,系统复位或者加电后通常从地址0x00000000处开始执行,而这个地址一般正是存放的BootLoader启动代码。通过这段程序,可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终加载操作系统内核准备好正确的环境。 BootLoader一般情况下需要包含以下几个必备的功能 :(l)初始化处理器。这个动作都是用汇编语言完成的,称为重置码(resetcode)或者称为bootcode,而且对于每个CPU都不一样的,当电源接通后就会执行这个动作,通常只有两三个汇编指令,目的是将CPU的控制权转给硬件初始化的程序。 (2)初始化一些必要的硬件。这个动作也大都由汇编语言来完成,主要是初始化CPU、SDRAM等,其他的硬件,例如串口,可以由c语言等比较高级的程序语言来完成后续动作。 (3)设置处理器的寄存器以及内存,关掉所有的输入管脚(包括中断管脚),以防止突然有信号进入妨碍接下来的硬件初始化动作。然后初始化串口,以便后续运行的程序能够同HOST端进行通信,便于调试。 (4)从特定的位置把操作系统和文件系统调入内存,并设置一些操作系统所必需的参数,然后把CPU控制权交给操作系统。有的BootLoader会先从串口或者网络等其他途径得到内核的映像文件,然后把这些文件写入目标系统的FLASH或者其它存储介质,最后再把内核载入RAM执行,交出控制权。 一般BootLoader都包含两种不同的操作模式:“启动加载”模式和“下载”模式,这种区别仅对于开发人员才有意义。从最终用户的角度看,BootLoader的作用就是用来加载操作系统,而并不存在所谓的启动加载模式与下载模式的区别。 (l)启动加载(Bootloading)模式:这种模式也称为“自主”(Autonomous)模式,即BootLoader从目标机上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。这种模式是BootLoader的正常工作模式,因此在嵌入式产品发布的时候,BootLoader显然必须工作在这种模式下。 (2)下载(Downloading)模式:在这种模式下,目标机上的BootLoader将通过串 口连接或者网络连接等通信手段从主机(HOST)下载文件,比如下载内核映像和根文件系统映像等。从主机下载的文件通常首先被BootL0ader保存到目标机的RAM中,然后再被BootLoader写到目标机上的FLASH类固态存储设备中。BootLoader的这种模式通常在第一次安装内核与根文件系统时被使用,此外,以后的系统更新也会使用BootLoader的这种工作模式。工作于这种模式下的BootLoader通常都会向它的终端用户提供一个简单的命令行接口。 BootLoader的实现依赖于CPU的体系结构,一般来说启动过程分为两个阶段。 第一阶段依赖于CPU体系结构的代码,比如设备初始化代码等,通常都放在第一阶段中,而且通常都用汇编语言来实现,运行效率比较高。这个阶段完成的任务一般如下:(l)硬件设备初始化(屏蔽所有的中断、关闭处理器内部的指令/数据cache);(2)为第二阶段准备RA.M空间;(3)复制BootLoader的第二阶段代码到RAM空间中;(4)设置好堆栈并跳转到第二阶段的C程序入口点。 第二阶段则通常用C语言来实现,这样可以实现复杂的功能,而且代码会具有更好的可读性和可移植性。这个阶段主要任务有:(l)初始化本阶段要使用的硬件设备;(2)检测系统内存映射;(3)将内核映像和根文件系统从FLASH读到RAM中;(4)为内核设置启动参数;(5)调用内核文件运行。 本设计中的Bootloader采用Blob,Blob是Boot Loader Object的缩写,是一款功能强大的Bootloader。Blob最初是由Jan-Derk Bakker和Erik Mouw两人为一块名为LART(Linux Advanced Radio Terminal)的开发板写的,该板使用的处理器是StrongARM SA-1100,现在Blob已经被成功移植到许多基于ARM的CPU上了。本设计中的Intel Xcale就是采用Blob作为Bootloader[8]。 3.3.2Linux 内核移植 选用嵌入式Linux作为目标机操作系统,一方面由于Linux是一款免费的操作系统,能很好的降低成本,同时Linux的开发应用现在已经成为热门,有大量的资源可用于学习与重复应用,并且Linux系统具有良好的可移植性和可裁剪性,能自动支持多任务管理。一般常用的GUI如QT/E,MiniGUI等都支持Linux。 Linux的开发工具也都可以很方便的免费获得。 系统采用的嵌入式Linux内核为随实验平台光盘中的Linux内核,它是针对这套实验平台所配置的Linux内核,内核版本为Linux2.4.20[9]。在实验过程中,只需要在这个内核的基础上进行添加和删减所需要和不需要的功能,编译后就可以使用了。 在编译内核之前,需要对内核进行必要的配置,通过虚拟机进入/pxa270_linux/linux/目录后在终端执行make menuconfig[10]命令,就可以可视化的配置内核需要的功能和要求,本次试验,主要是针对视频方面,选择了对V4L的静态加载、对spca5xx摄像头驱动的动态加载,这样就结束了对内核的配置。编译内核需要创建内核依赖关系、创建内核镜像文件和创建内核模块。首先执行makedep命令,读取配置过程生成的配置文件,来创建对应于配置的依赖关系树,从而决定哪些需要编译而哪些不需要;接着需要makeclean删除前面步骤留下的文件,以避免出现一些错误;然后便可以生成所需要的内核文件了,用make zlmage来实现得到可移植的内核。内核文件通过并口下载线烧写入开发板中,便可以通过BootLoader加载运行。 3.3.3嵌入式文件系统 嵌入式Linux操作系统一般采用FLASH作为存储介质。FLASH具有独特的物理特性,所以必须使用专门的嵌入式文件系统。嵌入式系统对文件的操作是通过层次结构实现的。对于用户程序来说,文件是有结构的文件,用户程序通过对文件IO函数操作文件。嵌入式文件系统是嵌入式操作系统的一部分,它的任务是对逻辑文件进行管理,其工作包括提供对逻辑文件的操作(复制、删除、修改等)接口,方便用户操作文件和目录。在文件系统内部,根据存储设备的特点,使用不同的文件组织模式来实现文件的逻辑结构。此外,文件系统要对管理文件的安全性负责。文件系统不能直接控制物理设备,它是通过FLASH驱动实现控制的[11]。 目前FLASH支持的文件系统技术主要有JFFS2,YAFFS2,TrueFFS,FTL/NTFL,RAMFS,CRAMFS和ROMFS等等。本系统采用的是JFFS2文件系统。 JFFS2文件系统是专门为NAND闪存设计的嵌入式文件系统,根据NAND闪存以页面为单位存取的特点,将文件组织成固定大小的数据段。利用NAND闪存提供的每个页面16B的备用空间来存放ECC(ErrorCorrectionCode)和文件系统的组织信息、,不仅能够实现错误检测和坏块处理,也能够提高文件系统的加 载速度。JFFS2采用一种多策略混合的垃圾回收算法,结合了贪心策略的高效性和随机选择的平均性,达到了兼顾损耗平均和系统开销的目的。它是日志结构的文件系统,提供了损耗平衡和掉电保护,可以有效地避免意外掉电对文件系统一致性和完整性的影响。JFFS2文件系统是按层次结构设计的,分为文件系统管理层接口、JFFS2内部实现层和NAND接口层,这样就简化了其与系统的接口设计,可以方便地集成到系统中去。与YAFFS相比,它增加了一些功能,因此功能更强。 3.4Linux下的程序调试 调试是程序开发过程中必不可少的一个重要环节,通用PC机的程序调试与嵌入式操作系统的调试环境上有着明显的区别,前者调试器和被调试的程序往往是运行在同一台机器上,是相同操作系统下的两个不同的进程,调试器通过操作系统专用调用接口控制被调试进程,后者通常为远程调试,调试器一般运行于桌面操作系统上,而被调试的程序则运行在嵌入式系统之上,因此需要协调这两个程序之间的通信。Linux下的调试工具非常的少,gdb是Linux下最著名的调试工具,它是GNUC自带的调试工具,它可以使开发人员了解程序运行的详细细节,从而消除程序的错误,达到调试的目的,gdb还具有远程调试功能,可以满足嵌入式系统调试的要求,在调试过程中PC机也称为宿主机和嵌入式系统通过串口协议或者TCP/IP协议连接起来,远程主机上运行被gdb规范断点改造过的内核,当条件成立时,断点被激活,然后等待本地宿主机的连接命令,一旦连接成功,宿主机就可以向远程嵌入式系统发送调试命令了。在调试过程中gdb通过调试stub来完成通信功能,调试stub是嵌入式操作系统中的一小段代码,它提供了运行gdb的宿主机和嵌入式系统进程之间交互的一个媒介。 除了使用调试器外还可以直接在程序中使用printf()或printk打印函数,这种方法功能比较弱,效率低下,但在内核模块调试时这是唯一的方法。14 第4章USB设备驱动程序设计 4.1设备驱动程序简介 Linux系统中,设备驱动程序扮演着特殊的角色。它就像一个独立的黑盒子一样,使某个特定的硬件可以相应一个定义良好的内部编程接口并且完成隐藏设备的作用。用户只需调用一组标准化的函数完成操作,而且这些操作与特定的驱动程序无关。驱动程序的任务就是将这些函数映射到作用硬件的具体操作上。这样的模块化的驱动程序结构使得Linux系统中的驱动程序可以独立于内核的其他部分,可以在需要使用的时候将驱动“插入”内核。 从系统运行顺序来看,硬件平台启动运行Linux后,启用了MMU单元即内存管理单元,在这种模式下系统不能直接对物理地址进行访问。若要对某一硬件外设进行读写,需要通过内核调用该硬件的驱动来实现。 上面已经说过,驱动程序的作用在于向应用程序提供访问硬件设备的接口,驱动程序屏蔽了硬件实现上的细节操作,于是应用程序可以像操作普通文件一样对硬件设备进行操作。Linux以模块的形式加载设备类型,通常是一个模块对应实现一个设备驱动。模块是内核的一部分,它们没有被编译到内核中,而是分别被编译并链接成一组目标文件。可以根据用户的需要在不需要对内核进行重新编译的情况下动态载入正在运行的内核,或从正在运行的内核中卸载。利用这种机制,内核尺寸可以保持在最小,并具有最大的灵活性,也便于检验新的内核代码,而不需要重新编译内核并重新引导。设备驱动程序一般需要完成以下功能:(l)对设备初始化和释放;(2)把数据从内核传送到硬件和从硬件读取数据;(3)读取应用程序传送给设备文件的数据和回送应用程序的请求数据;(4)检测和处理设备出现的错误。 在Linux操作系统下有两类主要设备文件类型:块设备、字符设备。用户进程正是通过设备文件来与硬件打交道。每个设备文件都有其文件属性,表示是字符设备还是块设备。另外每个文件都有2个设备号,第一个是主设备号,标识驱动程序;第二个是从设备号,标识使用同一个设备驱动程序的不同硬件设备。设备文件的主设备号必须与设备驱动程序在登记时申请的设备号一致,否则用户进程将无法访问驱动程序。 Linux驱动程序可以分为三个主要部分: 15 (l)自动配置和初始化子程序,负责检测所要驱动的硬件设备是否存在和能否正常工作。如果该设备正常,则对这个设备及其他必需的条件位口中断、DMA通道)进行申一请并初始化。这部分驱动程序仅在初始化时被调用一次。 (2)服务于I/O请求的子程序,又称为驱动程序的上半部分。调用这部分程序是由于系统调用的结果。这部分程序在执行时,系统仍认为是与进行调用的进程属于同一个进程,只是由用户态变成了核心态,但仍具有进行此系统调用的用户程序的运行环境,因而可以在其中调用与进程运行环境相关的函数。 (3)中断服务子程序,又称为驱动程序的下半部分。在Linux操作系统中,并不是直接从中断向量表中调用设备驱动程序的中断服务子程序,而是由Linux系统来接收硬件中断,再由系统调用中断服务子程序。中断可以在任何一个进程运行时产生,因而在中断服务子程序被调用时,不能依赖于任何进程的状态,也就不能调用任何与进程运行环境有关的函数。因为设备驱动程序一般支持同一类型的若干设备,所以一般在系统调用中断服务子程序时,都带有一个或多个参数,以唯一标识请求服务的设备。 在系统内部,I/O设备的存取通过设备驱动程序提供的一组固定的入口点来进行,这组入口点在驱动程序初始化时向系统进行登记,以便在系统适当的时候调用。一般来说,字符型设备驱动程序能够提供如下几个入口点:(1)open入口点:打开设备准备I/O操作,对字符特别设备进行打开操作,都会调用设备的open入口点。open子程序必须对将要进行的I/O操作做好必要的准备工作,如清除缓冲区等。如果设备是独占的,即同一时刻只能有一个程序访问此设备,则open子程序必须设置一些标志以表示设备的状态。 (2)close入口点:关闭一个设备,当最后一次使用设备结束后,调用dose子程序。独占设备必须标记设备可再次使用。 (3)read入口点:读取设备,对于有缓冲区的I/0操作,一般从缓冲区里读取设备数据。 (4)write入口点:向设备写数据,对于有缓冲区的I/O操作,一般向缓冲区里写入数据。 (5)ioctl入口点:执行读写之外的操作。 USB(Universal Serial Bus)即“通用串行外部总线”,用途广泛,可以外接硬盘、键盘、鼠标、打印机等多种设备,USB能够使用尽可能少的接口支持尽可能多的外设,尤为适合在嵌入式设备中使用,是嵌入式接口标准的一个很好的选择。 USB总线规范有1.1版和2.0版。USB1.1支持两种传输速率:低速1.5Mbit/s、全速12Mbit/s,这样的速率完全满足鼠标、键盘、CD-ROM等设备,但是在嵌入式视频监控系统中,这样的速度还是很慢。所以,USB2.0提供了一种更好的传输速率:高速,它可以达到480Mbit/s。USB2.0向下兼容USB1.1,可以将遵循USB1.1规范的设备连接到USB2.0控制器上,也可以把USB2.0的设备链接到USB1.1控制器上。 USB总线的硬件拓扑结构[12]如图4.1所示。 USB主机控制器USB设备根集线器USB设备USB设备集线器USB设备集线器USB设备集线器USB设备USB设备USB设备USB设备 图4.1 USB总线硬件拓扑图 USB主机控制器通过根集线器与其他USB设备相连。集线器也属于USB设备,通过它可以在一个USB接口上扩展出多个接口。除根集线器外,最多可以层叠5个集线器,每条USB电缆的最大长度是5m,所以USB总线的最大距离为30m。一条USB总线上可以外接127个设备,包括根集线器和其他集线器。整个结构图是一个星状结构,一条USB总线上所有设备共享一条通往主机的数据通道,同一时刻只能有一个设备与主机通信。 通过USB主机控制器来管理外接的USB设备,USB主机控制器共分3种:UHCI、OHCI和EHCI。在配置Linux内核的时候,看到的“HCD”字样表示“Host Controller Drivers”,即主机控制器驱动程序。 USB驱动程序分为两类:USB主机控制器驱动程序(Host Controller Drivers)、USB设备驱动程序(USB device drivers)。它们在内核中的层次如图4.2所示。 UserUSB Device DriversUSB Host Controller DriversHardware 图4.2 USB驱动程序层次结构 在试验中,教学平台上的Linux嵌入式内核已经配置了USB主机控制器驱动程序,只需要添加需要的USB设备驱动程序,就能实现USB设备的正常使用。 4.2Linux下驱动程序的实现 Linux操作系统下对硬件设备进行驱动开发的一般步骤如下:(l)注册设备 在系统启动时或者在模块加载的时候需要将设备和重要的数据结构登记到内核的设备数组中,并确定该设备的主次设备号。在Linux系统中,对于字符设备一般通过调用register_chrdev向系统注册设备驱动程序,register_chrdev在fs/deviees.c文件中的定义如下:int register_chrdev(unsigned int major,const char*name,struct file_operations fops)定义中的major是设备驱动程序向系统申请的主设备号,如果major为O,则系统为该驱动程序动态的分配一个主设备号,不过此设备号是临时的;name是设备名:fops是各个调用入口点的说明。函数返回O表示注册成功,返回-INVAL表示申请的主设备号非法,返回-EBUSY表示申请的主设备号正在被其它设备驱动程序使用。 以后对设备驱动程序的file_operations的操作都可以通过该主设备号的索引来完成。register_chrdev函数操作成功后,设备名便出现在/proc/devices文件目录中,使用命令cat/proc/devices可以查看设备的工作状态。 (2)定义操作集 驱动程序中要通过一系列函数完成对设备的不同操作,这些操作在面向对象编程术语中也称为方法,该操作集通过数据结构file_operations实现。内核内部通过file结构识别设备,通过file_operations数据结构提供的文件系统的入口点函数访问设备。 file_operations定义在 int(*release)(struct inode*, struct file*);int(*fsync)(struct file*, struct dentry*, int datasync);int(*fsyne)(int, struct file*, int);int(*lock)(struct file*,int, struct file_lock*);ssize_t(*readv)(struct file*, const struct iovec*, unsigned long, loff_t*);ssize_t(*writev)(struct file*, const struct iovec*, unsigned long, loff_t*);ssize_t(*sendpage)(struct file*, struct page*, int, size_t, loff_t*, int);unsigned long(*get_unmapped_area)(struct file*, unsigned long, unsigned long,unsigned long, unsigned long);} 这个结构的每一个成员的名字对应一个系统调用,在用户程序利用系统调用对设备文件进行诸如读/写操作时,系统调用会通过设备文件的主设备号找到相应的驱动程序,然后读取这个数据结构的相应函数指针,把控制权交给该函数。对于具体的设备驱动并不需要实现结构中所有的例程,只要完成设备功能就可以了。例如对于一个常见的字符设备驱动来说,可能只有操作open(),write(),read(),ioctl()和close(),当用户程序通过系统调用访问设备时,最终要通过这些操作集来完成。 (3)卸载模块 当不再需要使用一个模块或设备时,需要将其从内核中卸载下来,这时会动态调用模块中的module_exit()函数,并需要在该函数中调用modul_unregister_chrdev()或module_unregister_blkdev()释放挂入内核的数据结构同时释放该设备号。 4.3USB摄像头驱动程序设计 摄像头属于视频设备,在Linux内核中,VideoforLinux(简称V4L)是关于视频设备的驱动标准。这个标准为应用程序定义了一系列的接口函数,内核、驱动和应用程序都是依靠这个标准来进行交流。本系统所使用的USB摄像头正是基于该标准来编写驱动和应用程序的。 Linux内核是依据设备号来操作设备文件的,在内核中,摄像头对应的设备文件名为/dev/video0,主设备号是81,次设备号根据摄像头数目来确定,本系统中仅使用一个摄像头,所以可以通过mknod/dev/video0 c 81 0来创建节点。USB摄像头驱动程序实现原理如图4.3所示。 USB摄像头的驱动和通用设备的驱动准则一样,但需要与内核提供的视频驱动挂钩。即首先在驱动中声明一个 video_device结构,并为其指定文件操作函数指针数组fops,向系统注册。在应用程序发出文件操作的相关命令时,核心根据这些指针调用相应函数,并将该结构作为参数传递给它们。这样,就完成了驱动和核心之间的通信。 例如: Static struct video_devie vdev_template={……}; 声明 video_deviee,指出挂接驱动 用户进程系统调用摄像头驱动文件操作接口接收缓冲区发送缓冲区中断服务程序摄像头 图4.3 摄像头驱动实现框图 Static Struct file_operation spcasxx_fops= {……}; 声明本驱动的文件操作函数指针 Struct video_device*vdev=video_devdata(file);从文件指针中提取出 video_deviee结构 在video_deviee结构中,有一个私有指针priv,可以将它指向一块保留内存。在这块内存中,保存着本驱动、本设备的相关初始化信息。这块内存的申请、初始化、指针指向等工作都是在USB驱动的枚举函数probe中完成。这样,在枚举函数将控制权返还给系统后,因为内核不销毁保留内存,所以驱动仍然保留着自己的信息。在驱动卸载函数中需要将申请的各块内存全部释放。 Linux系统中任何USB传输都通过URB实现。为提高速度,可以考虑扩大URB的缓冲,这样可以降低每个USB事务中握手信息所占比例,提高有效数据的输速度。但是受限于总线带宽和具体的USB设备芯片,单纯扩大URB的缓冲不能无限制地解决问题。USB在操作系统中每次传输都要包括URB的建立、发出、回收、数据整理等阶段,这些时间不产生有效数据。因此可以建立两个URB,在等待一个URB被回收时,也就是图像正在被传感器采集时,处理、初始化另一个URB,并在回收后立刻将其发出。两个URB交替使用,大大减少了额外时间。 由于嵌入式平台上运行的Linux2.4.20内核,内部已经集成了对USB2.0的支持,所以无需移植相应的USB驱动。 在设计中,摄像头芯片采用中星微的Z301系列芯片,Linux2.4内核并不支持这种芯片,所以我们通过移植芯片驱动程序来达到目的。芯片的驱动程序是spca5**系列,如果不重新编译内核的话,将驱动程序动态加载就可以正常使用。设计中动态加载的命令使用insmod命令,它和modprobe命令在使用上有所不同,modprobe在加载模块时不用指定模块文件的绝对路径,也不用带模块文件的后缀.o或.ko;而insmod需要的是模块的所在目录的绝对路径,并且一定要带有模块文件名后缀的.o或者.ko。但是在功能上,它们所达到的效果基本相同[13]。22 第5章视频采集功能的设计 视频采集程序是基于V4L开发的,包括摄像头的初始化、打开/关闭、参数设置和数据读取等操作,视频采集程序流程图如图5.1所示[14]。 开始初始化摄像头init_videoIn()打开摄像头open_v4l()获取摄像头参数icotl(int->vd,int cmd,..)设置摄像头参数ioctl()获取一帧图像N一帧是否截取完毕Y存储并准备传输N是否终止视频采集Y关闭摄像头终止 图5.1 视频采集程序流程图 5.1基于V4L的编程 5.1.1摄像头相关数据结构 摄像头的组成部分是传感器、DSP、镜头、外壳、USB连线、电路板和周边电路构成,其中最重要的是传感器和DSP(数字信号处理器)。本系统选用的摄像头采用了CMOS传感器和中星微301处理器。 V4L[15]提供了一系列的接口应用程序,可以利用这些程序实现对摄像头的调用,其中有read、open、ioctl等。V4l同时将这些函数和参数封装成一个数据结构vdIn。struct vdIn { int fd;char *videodevice;struct video_mmap vmmap;struct video_capability videocap;int mmapsize;struct video_mbuf videombuf;struct video_picture videopict;struct video_window videowin;struct video_channel videochan;struct video_param videoparam; int cameratype;char *cameraname;char bridge[9];int sizenative;int sizeothers;int palette;int norme;int channel;int grabMethod;unsigned char *pFramebuffer;unsigned char *ptframe [4]; };int framelock [4];pthread_mutex_t grabmutex;int framesizeIn;volatile int frame_cour;int bppIn;int hdrwidth;int hdrheight;int formatIn;int signalquit; int fd :打开摄像头时,open函数返回的文件描述符,其他函数使用这个描述符对摄像头进行操作。 struct video_mmap vmmap: 用于内存映射的结构体。 struct video_capability videocap :描述摄像头基本信息,如设备名称、支持的最大分辨率、信号源信息、信道数等。 struct video_mbuf videombuf :在进行内存映射时读取帧的信息,实际上是输入到摄像头存储缓存中的帧信息。 struct video_picture videopict :摄像头采集图像的属性,如亮度、色调、对比度、色度、深度等。 struct video_window videowin :表示采集窗口参数,如分辨率等。struct video_channal videochan :关于信号源的属性。 5.1.2摄像头基本功能实现 (1)初始化摄像头参数 在对摄像头进行操作之前,要对摄像头进行初始化,即对vdIn这个结构进行初始化。使用init_videoIn 函数。 int init_videoIn(struct vdIn *vd, char *device, int width, int height, int format, int grabmethod){ int err =-1;int i;if(vd == NULL || device == NULL)return-1; } if(width == 0 || height == 0)return-1;grabmethod = 1;//read by default;if(grab method < 0 || grabmethod > 1)// check format vd->videodevice = NULL;vd->cameraname = NULL;vd->videodevice = NULL;vd->videodevice =(char *)realloc(vd->videodevice, 16);vd->cameraname =(char *)realloc(vd->cameraname, 32);snprintf(vd->videodevice, 12, “%s”, device);if(debug)printf(“video %s n”,vd->videodevice);memset(vd->cameraname, 0, sizeof(vd->cameraname));memset(vd->bridge, 0, sizeof(vd->bridge));vd->signalquit = 1;vd->hdrwidth = width;vd->hdrheight = height;vd->formatIn = format; vd->bppIn = GetDepth(vd->formatIn);vd->grabMethod = grabmethod;vd->pFramebuffer = NULL;err = init_v4l(vd);for(i = 0;i < OUTFRMNUMB;i++){ } vd->frame_cour = 0;pthread_mutex_init(&vd->grabmutex, NULL);return err;vd->ptframe[i] = NULL;(unsigned char *)realloc(vd->ptframe[i], sizeof(struct frame_t)+(size_t)vd->framelock[i] = 0;vd->framesizeIn); (2)打开摄像头 在Linux中,类似摄像头的设备是作为文件来看待的,叫做设备文件。我们可以使用open函数来对设备进行打开操作,open带有两个参数,第一个为设备文件名称,本实验的摄像头设备名称是/dev/video0,第二个则是打开的类型。 在使用open函数打开摄像头之前,要判断是否有摄像头设备,即检查参数videodevice是否为空。Open函数执行结束后会返回摄像头的文件描述符,如果返回值为-1,则说明打开设备出错。 int open_v4l(char *vd->videodevice){ if(!vd->videodevice){ printf(“No device file, ERROR opening V4L interface”); return-1;} if((vd->fd=open(vd->videodevice, O_RDWR))==-1){ printf(“ERROR opening V4L interface”); return-1;} return vd->fd;}(3)获取摄像头参数 成功打开摄像头后,需要获取摄像头的一些参数,利用ioctl函数控制I/O通道来实现。Ioctl函数的使用是ioctl(int->fd, int cmd,……),fd代表文件描述符,cmd表示用户对设备的控制命令,第三个参数是一个其他的参数。其中,cmd包括VIDIOCGCAP(获得video_capbility中有关摄像头的信息)、VIDIOCGPICT(获取图像信息)、VIDIOCSPICT(改变图像信息)、VIDIOCGMBUF(获取摄像头存储缓冲区帧信息)、VIDIOCAMCAPTURE(获取视频图像)、VIDIOSYNC(判断摄像头是否截取成功)等。 读取video_capability中有关摄像头的信息 if(ioctl(vd->fd, VIDIOCGCAP, &(vd->videocap))==-1){ printf(“Fail to get video_capability!/n”);return-1;} 读取video_picture中的图像信息 printf(“Fail to get video_picture!/n”);return-1;} if(ioctl(vd->fd, VIDIOCGPICT, &(vd->videopict))==-1){ 读取video_window信息 if(ioctl(vd->fd,VIDIOCGWIN,&(vd->videowin))==-1){ printf(“Fail to get video_window!/n”); return-1;}(4)设置摄像头参数 在对摄像头参数进行设置的时候,应该按照以下步骤:比如更改图像信息,首先,先给video_picture结构中所要修改的变量赋值,如vd->videopict.palette=vd->formaIn;vd->videopict.depth=GetDepth(vd->formatIn);然后通过ioctl函数的VIDIOCSPICT来设置,如if(ioctl(vd->fd,VIDIOCSPICT,&(vd->videopict))<0){ printf(Fail to set videopict params with VIDIOCSPICT!/n“);return-1;} 在设置好了之后可以通过VIDIOCGPICT命令来查询图像信息设置是否成功。(5)关闭摄像头 在Linux编程过程中,必须养成一个好的编程习惯,就是在开启一个设备后一定要关闭它,这样可以避免很多诸如内存泄露等严重的问题。 本系统支持两种读取方式来获得视频流,它们是内存映射和直接读取,所以首先需要判断视频采集的方式,如果是内存映射,则在系统任务完成后关闭内存映射,然后关闭摄像头设备。同样道理,如果采用的是直接读取,则在任务完成后关闭直接读取,然后在关闭摄像头设备。在代码中,采用了一个判断语句,判断vd->grabMethod的值来判断系统采用哪种读取方式。int close_v4l(struct vdIn *vd){ int i;if(vd->grabMethod){ } else { free(vd->pFramebuffer);vd->pFramebuffer = NULL;if(debug)printf(“unmapping frame buffern”);munmap(vd->pFramebuffer, vd->mmapsize); } } if(debug)printf(“close video_devicen”);close(vd->fd);/* dealloc the whole buffers */ if(vd->videodevice){ } if(vd->cameraname){ } for(i = 0;i < OUTFRMNUMB;i++){ } pthread_mutex_destroy(&vd->grabmutex);if(vd->ptframe[i]){ } free(vd->ptframe[i]);vd->ptframe[i] = NULL;vd->framelock[i] = 0;if(debug)printf(“freeing output buffer %dn”, i); free(vd->cameraname);vd->cameraname = NULL;free(vd->videodevice);vd->videodevice = NULL;5.1.3视频数据采集 视频数据的采集是系统实现的第一步,是所有工作的前提。嵌入式Linux系统支持两种视频数据采集的方式:内存映射、直接读取视频。 (1)内存映射 内存映射方式是通过mmap系统调用函数来实现的。mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间 后,进程可以像访问普通内存一样对文件进行访问,不必再调用read()、write()等操作。 首先,使用ioctl系统调用的VIDIOCSFBUF命令获得摄像头存储缓冲区的帧信息,之后初始化video_mbuf,修改video_mmap中的设置,重新设置图像信息,如帧的垂直及水平分辨率、彩色显示格式等。为了防止缓冲区的内容与有用信息叠加产生干扰,在初始化之前可以先调用memset(&(vd->videombuf),0,sizeof(vd->videombuf)来清零缓冲区。然后使用函数vd->map=(unsigned char*)mmap(O,vd->mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd->fd,ff_t offset)使设备内容映射到内存区,其中第一个参数为共享内存的起始地址,一般设为0,表示由系统分配;第二个参数为映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起;第三个参数指定共享内存的访问权限(PROT_READ(可读),PROT_WRITE(可写),PROT_EXEC(可执行));第四个参数可以是MAP_SHARED或者MAP_PRIVATE;第五个参数为设备描述符。mmap()成功调用后返回系统实际分配的起始地址。 内存映射方式下真正进行视频截取的是ioctl系统调用的VIDIOCMCAPTURE命令,若函数成功调用,再用VIDIOCSYNC命令来判断图像截取是否己经完毕,若该函数调用成功,则表明一帧图像的截取已完成,便开始下一帧图像数据的截取,并将当前截取的帧号按缓冲区总帧数的模加上l。 vd->vmmap.height=vd->hdrheight;vd->vmmap.width=vd->hdrwidth;vd->vmmap.format=vd->formatln;/*判断图像截取是否完成*/ if(ioctl(vd->fd,VIDIOCSYNC,&vd->vmmap.frame)<0){ perror(„‟cvsync errn);erreur=-I;} while((vd->framelock [vd->frame_cour]!=0)&&vd->signalquit)usleep(1000);temps=ms_time(); pthread_mutex_lock(&vd->grabmutex);jpegsize=convertframe(vd->ptframe[vd->frame_cour]+sizeof(struct frame_t),vd->pFramebuffer+vd->videombuf.offsets[vd->vmmap.frame],vd->hdrwidth,vd->hdrheight,vd->formatln,vd->framesizeIn);headerframe=(struct frame_t*)vd->ptframe [vd->frame_cour]; snprintf(headerframe->header, 5,”%s”.”SPCA”); headerframe->seqtimes=ms_time();headerframe->w=vd->hdrwidth;headerframe->h=vd->hdrheight;headerframe->size=((jpegsize<0)? 0: jpegsize);headerframe->format=vd->formatln;headerframe->nbframe=frame++;pthread_mutex_unlock(&vd->grabmutex);/*截取视频帧*/ if((ioctl(vd->fd,VIDIOCMCAPTURE,&(vd->vmmap)))<0){ perror(“cmcapture”); if(debug)printf(“>>cmcapture err n”);erreur=-l;} vd->vmmap.frame=(vd->vmmap.frame+1)%vd->videombuf.frames;vd->frame_cour=(vd->frame_cour+l)%OUT FRMNUMB;(2)直接读取方式 直接读取视频数据是通过read系统调用函数来实现。read是一个用来从指定的文件或设备中读取数据的系统调用。参数表为read(fd,(void*)pFramebuff,(size_t)framesizeln)。其中fd为文件描述符,pFramebuffer为指向存放数据的内存的指针,framesizeln为需要读取的数据的长度。对于摄像头设备的读取,需要先分配内存空间,用来存储从摄像头读取过来的视频数据,然后直接调用read系统调用读取视频数据,返回值为实际读取的视频帧大小,也正是在视频传输过程中发送的视频数据大小。 size=vd->framesizeln;vd->pFramebuffer=(unsigned char*)realloc(vd->pFramebuffer,(size_t)size);Len=read(vd->fd, vd->pFramebuffer, size);if(len<0){ if(debug)printf(“v41 read errorn”); if(debug)printf(“len %d asked %dn”, len, size);return 0;} /*是否有其他进程正在使用该视频帧*/ while((vd->framelock [vd->frame_cour]!=0)&&vd->signalquit) headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant); usleep(1000);temps=ms_time(); pthread_mutex_lock(&vd->grabmutex);jpegsize=convertframe(vd->ptframe[vd->frame_cour]+sizeof(structframe_t),vd->pFramebuffer,vd->hdrwidth,vd->hdrheight,vd->formatln,vd->framesizeln);headerframe=(struct frame_t*)vd->ptframe [vd->frame_cour];snprintf(headerframe->header, 5,”%s”,”SPCA”);headerframe->seqtimes=ms_time();headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant);headerframe->w=vd->hdrwidth;headerframe->h=vd->hdrheight;headerframe->size=((jpegsize<0)? 0: jpegsize);headerframe->format=vd->formatln;headerframe->nbframe=frame++;vd->frame_cour=(vd->frame_cour+1)%OUTFRMNUMB;pthread_mutex_unlock(&vd->grabmutex);5.2图像编解码 5.2.1编解码介绍 通过摄像头采集到数据后,还并不能把它们直接通过网卡传输,因为这样的数据很大,网络不能承担如此庞大的数据传输。所以,必须将采集到得数据进行编码,压缩数据大小。通过这样的操作,我们采集到得数据就会变得很小,然后再把这些数据通过网络传输。同样的道理,在输出端我们还要把接收到的已经压缩的数据还原回来,这就涉及到解码的内容。通过这一系列的操作,图像和视频数据就实现的远程的传输。如果没有编解码,远程传输就是实际上不可能的事情,所以图像的编解码是非常重要的。 现在普遍使用的编解码技术。对于静态图像,普遍使用静态压缩JPEG标准;对于动态视频,普遍使用动态压缩MPEG标准。 JPEG是由ISO和CCITT为静态图像压缩所建立的国际上第一个静态图像压缩标准,JPEG有着较高的压缩比,复杂度适中,既可以用硬件实现,也可以用软件实现,实用性强,被广泛使用于计算机和通信行业。 MPEG中文译名为动态图像专家组。到目前为止,MPEG标准主要有五个,32 MPEG- 1、MPEG- 2、MPEG- 4、MPEG-7和MPEG-21。它是由ISO/IEC1172压缩编码标准得出的视频压缩格式,MPEG的出现使视听传播进入数码化时代。MPEG标准的视频压缩编码技术主要利用了具有运动补偿的帧间压缩编码技术以减少时间冗余度,利用DCT技术以减少图像的空间冗余度,利用熵编码技术在信息表示方面减少了统计冗余度。通过一系列技术,极大的体现了压缩性能[16]。 5.2.2系统压缩技术 由于本系统要求实现远程视频传输,为了达到预计的设计要求,设计采用基于MJPEG算法的压缩技术进行视频压缩。MJPEG和MPEG的不同点在于MJPEG不使用帧间编码。可是MJPEG与MPEG仍然是一脉相承的,它对MEPG进行了一些改进和发展,功能更加强大,能发送高质图片、清晰视频,编码容易实现。但MJPEG也有一些缺点,由于功能的提升,MJPEG对带宽的要求很高,编码效率低。 参考文献 1.张永强,赵勇勇,李崇德.嵌入式远程视频采集系统的设计与实现[J].现代电子技术,2006,05(02):57-60.2.Jing Li, Weidong Hao.Research and Design of Embedded Network Video Monitoring System Based on Linux[C].The 2008 International Conference on Embedded Software and Systems Symposia, 2008, 1310-1313.3.陈章龙,唐志强,涂时亮.嵌入式技术与系统——Intel Xscale 结构与开发[M].北 京:北京航空航天大学出版社,2004,143.4.奥尔博公司.PXA270嵌入式实验开发系统——Linux实验指导[M],2007.5.Seon Gyu Kim and Sung Ho Cho.Implementation of an Embedded Software Modem Platform[J].Division of Electrical & Computer Engineering,2006,04(2):5-9 6.杜春雷.ARM体系结构与编程[M].北京:清华大学出版社,2003.7.朱珍民,隋雪青.嵌入式实时操作系统及其应用开发[M].北京:北京邮电大学出版社,2006.8.李亚峰 欧文盛.ARM嵌入式Linux系统开发从入门到精通[M].北京:清华大学 33 出版社,2007,51-54.9.李善平.Linux内核2.4版源代码分析大全[M].北京:机械工业出版社,2002.10.廖日坤.ARM嵌入式应用开发技术白金手册[M].北京:中国电力出版社,2007, 284-290.11.刘昆.Linux环境下宿主机与ARM开发板NFS服务的配置[J].科技资讯,2008,05(04):65-80.12.韦东山.嵌入式Linux应用开发完全手册[M].北京:人民教育出版社,2008.13.孙纪坤,张小全.嵌入式Linux系统开发技术详解——基于ARM[M].北京:人民邮电出版社,2006.14.李冰,孙建平,谭悦,张启勤.基于嵌入式Linux与S3C2410的网络视频监控[J].河北:华北电力大学学报,2006,2(4):15-30.15.董玲,朱宏,杨忠孝.基于ARM的嵌入式Linux应用程序开发研究[J].电子测试,2008,05(06):40-60.16.Yongqiang Zhang, Bing Zhang.Design of Embedded Audio and Video Compression System[J].Workshop on Intelligent Information Technology Application,2007,12(8):76-90.17.Xing Zhang, Li-Ming Song.Implementation of Video Data Transmission Between ARM and DSP Through Embedded Linux[C].The 2008 International Conference on Embedded Software and Systems Symposia,2008,292-295.18.张跃进,谢昕.嵌入式网络数字视频监控系统的设计[J].计算机工程与设计,2009,12(9):70-100.19.Yi Wu, Jiangyong Cai, Xiao Lin, Lianfeng Shen.The Design and Realization of the Wireless Video Monitoring System Based on Embedded Linux and CDMA1X[C].The 2008 International Conference on Embedded Software and Systems Symposia, 2008, 179-184.20.王先春,郭杰荣,胡惟文,樊希平.基于ARM_Linux的嵌入式Web服务器的设计与实现[J].微计算机信息,2007,14(7):90-95.34 ARM9嵌入式系统课程设计 --嵌入式系统语音采集与播放程序设计 班级: 学号: 姓名: 指导老师: 课程设计时间:2011.6.29---2011.7.8 江苏大学 目录 第一章 引言.........................................................1 1.1 设计目的......................................................1 1.2 设计任务与要求................................................1 第二章 课程设计平台构建与流程.......................................2 2.1 嵌入式系统平台构建............................................2 2.2 课程设计流程..................................................3 2.3 课程设计硬件结构与工作原理...................................3 第三章 BOOTLOADER移植与下载.......................................11 3.1 VIVI源代码安装...............................................11 3.2 VIVI源代码分析与移植.........................................11 3.3 VIVI编译与下载...............................................12 第四章 LINUX内核移植与下载........................................14 4.1 LINUX内核源代码安装..........................................14 4.2 LINUX内核源代码分析与移植....................................14 4.3 LINUX内核编译与下载..........................................15 第五章 课程设计功能模块程序设计与交叉编译..........................24 5.1 课程设计模块功能.............................................24 5.2 功能模块驱动程序设计.........................................24 5.3 功能模块交叉编译.............................................28 第六章 根文件系统建立与文件系统下载................................29 6.1 根文件系统分析...............................................29 6.2 文件系统映像文件生成.........................................30 6.3 文件系统下载.................................................31 6.4 功能模块运行与调试...........................................32 第七章 课程设计总结与体会..........................................34 7.1 得出的结论...................................................34 7.2课程设计过程中遇到的问题及解决方法...........................34 7.3 心得体会.....................................................34 参考文献...........................................................36 第一章 引言 1.1 设计目的 分析Linux操作系统下音频设备驱动的结构,编写应用测试程序,实现UDA1341芯片的实时录音及放音功能,进一步熟悉vivi、Linux内核和根文件系统的编译和烧写至开发板的开发流程。 1.2 设计任务与要求 在Samsung公司S3C2410处理器的edukit-Ⅲ开发板上,在嵌入式linux操作系统环境下,根据语音芯片UDA1341的驱动程序和语音数据的特点编写语音采集与播放的应用测试程序,实现语音数据的采集和实时播放功能。1.要求本系统实时的采集与播放 2.通过麦克风录制一段语音信息,对其进行播放 第二章 课程设计平台构建与流程 2.1 嵌入式系统平台构建 2.1.1软件部分 1)Linux或Windows 98/2000/NT/XP 2)cygwin cygwin是一个在windows平台上运行的unix/Linux模拟环境,是cygnus solutions公司开发 3)Embest IDE 英蓓特提供的一个嵌入式开发的集成环境。4)windows中的超级终端 5)Embest online Flash Programmer for ARM 烧写相关文件到NorFlash中的工具。 6)建立linux的交叉编译环境,各项源代码的安装等 2.1.2硬件部分 1)EduKit-II实验平台 2)S3C2410核心子板 3)PC机 2.2 课程设计流程 图2.1 设计流程 2.3 课程设计硬件结构与工作原理 2.3.1硬件模块(1) SCLLRCIIS控制器SDOSDIMCL 图2.2 典型的IIS总线上的设备 (2)IIS总线结构 IIS总线只处理声音数据,其他控制信号等则需单独提供。IIS总线使用3根串行总线,分别是:提供分时复用功能的SD线(Serial data,串行数据),WS线(Word select,字段选择(声道选择))和SCK线(Continuous Serial clock,连续的时钟信号)。 音频编解码4 ADDRTxFIFODATASFTRBRFCRxFIFOSDCNTLCHHCSCLKIPSR_APCLKIPSR_BSCLKGLRCKCDCLK 图2.3 IIS总线接口内部结构 S3C2410A IIS总线接口各模块的功能描述如下: ● BRFC 表示总线接口、寄存器区和状态机。总线接口逻辑和FIFO访问由状态机控制。 ● IPSR 表示两个5位的前置分频器ISPR_A和ISPR_B,一个前置分频器作为IIS总线接口的主时钟发生器,另一个前置分频器作为外部音频编解码器CODEC的时钟发生器。 ● TxFIFO和RxFIFO 表示两个64字节的FIFO。在发送数据时,数据写到TxFIFO,在接收数据时,数据从RxFIFO读取。 ● SCLKG 表示主IISCLK发生器。在主设模式时,由主时钟产生串行位时钟。● CHNC 表示通道发生器和状态机。通道状态机用于产生和控制IISCLK和IISLRCK。 ● SFTR 表示16位移位寄存器。在发送模式时,并行数据移入SFTR并转换成串行数据输出;在接收模式时,串行数据移入SFTR并转换成并行数据输出。具体的相关寄存器的位功能描述请参观相关资料。2.3.2 工作原理 常用的数字音频处理集成电路包括A/D、D/A、DSP、数字滤波器和数字音频I/O接口及设备(麦克风、话筒)等。麦克风输入的模拟音频信号经A/D转换、音频编码器实现模拟音频信号到数字音频信号转换,编码后的数字音频信号通过控制器送入DSP或微处理器相应的处理。音频输出时,数字音频信号(音频数据)经控制器给音频解码器,经D/A转换后由扬声器输出。 数字音频涉及概念很多,重要的是理解:采样和量化。采样就是每隔一定时间读一次声音信号的幅度,而量化则是将采样得到的声音信号幅度转换为数字值。从本质上讲,采样是时间上的数字化,而量化则是幅度上的数字化。 根据奈奎斯特(Nyquist)采样理论采样频率应高于输入信号的最高频率两倍。为了保证声音不失真,采样频率应该在40kHz左右。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,要达到DVD的音质需要采用更高的采样频率。 量化是对模拟音频信号的幅度数字化,量化位数决定模拟信号数字化以后的动态范围,常用的有8位、12位和16位。量化位越高,信号的动态范围越大,数字化后的音频信号就越接近原始信号,但所需要的存储空间也越大。 声道有单声道、双声道和多声道。双声道又称立体声,在硬件中有两条线路,音质和音色都优于单声道,但数字化后占据的存储空间的大小要比单声道多一倍。多声道能提供更好的听觉感受,不过占用的存储空间也更大。 数字音频数据有PCM、MP3、WMA、WAV、Ogg Vorbis、RA、AAC、ATRAC 3等多种不同的文件格式。 1)IIS总线 IIS总线(IIS,Inter-IC Sound Bus,数字音频集成电路通信总线)是Philip公司提出的音频总线协议,它是一种串行的数字音频总线协议,是音频数据编码或解码常用的串行音频数字接口。 (1)IIS总线的传输模式 数据的发送方和接收方需要采用相同的时钟信号来控制数据传输,数据传输方(主设)必须产生字段选择信号、时钟信号和需要传输的数据信号。在一个复杂的数字音频系统中,可能会有多个发送方和接收方,通常采用系统主控制模式,主控制模块控制数字音频数据在不同集成电路(设备)间的传输,数据发送方就需要在主控制模块的协调下发送数据。IIS总线的三种传输模式如图2、3、4所示,这些模式的配置一般需通过软件来实现。 clock SCKTRANSMITTERword select WSdata SDRECEIVERTRANSMITTER=MASTER 图2.4发送器为主设时的传输模式 clock SCKTRANSMITTERword select WSdata SDRECEIVERRECEIVER=MASTER 图2.5 接收器为主设时的传输模式 CONTROLLERclock SCKTRANSMITTERword select WSdata SDRECEIVERCONTROLLER=MASTER 图2.6 控制器为主设时的传输模式(2)IIS总线时序 1串行数据(SD)○串行数据的传输由时钟信号同步控制,且串行数据线每次传输1字节的数据。当音频数据被数字化成二进制流后,传输时先将数据分成字节(如8位、16位等),每个字节的数据传输从左边的二进制位MSB(Most Significant Bit)开始。当接收方和发送方的数据字段宽度不一样时,发送方不考虑接收方的数据字段宽度。如果发送方发送的数据字段宽度小于系统字段宽度,就在低位补0;如果发送方的数据字段宽度大于接收方的宽度,则超过LSB(Least Significant Bit)的部分被截断。 2字段选择(WS)○音频系统一般包含有左右两个声道,字段选择(WS)用来选择左声道或者右声道,WS=0表示选择左声道;WS=0表示选择左声道。如果不在外部加以控制,WS会在MSB传输前的一个时钟周期发生变化,使数据接收方和发送方保持同步。此外,WS能让接收设备存储前1字节,并且准备接收后1字节。 3时钟信号(SCK)○在IIS总线中,任何一个能够产生时钟信号的电路都可以称为主设备,从设备从外部时钟输入得到时钟信号。IIS的规范中制定了一系列关于时钟信号频率和延时的限制。 图2.7 IIS总线时序 (3)IIS总线接口的工作方式 IIS总线接口是用来连接外部的标准编解码器(CODEC)的接口。S3C2410A提供一个IIS总线接口,能用来连接一个外部8/16位立体声音频CODEC,支持IIS 总线数据格式和MSB-justified数据格式。该接口对FIFO的访问提供DMA传输模式,而不是采用中断模式。它可以同时发送数据和接收数据,也可以只发送或只接收数据。在只发送和只接收模式,S3C2410A的IIS总线接口有以下三种工作方式。 1正常传输方式 ○在正常传输方式,对于发送和接收FIFO,IIS控制寄存器有一个FIFO就绪标志位。当FIFO准备发送数据时,如果发送FIFO不空,则FIFO就绪标志位为“1”;如果发送FIFO为空,该标志为“0”。在接收数据时,当接收FIFO是不满时,FIFO就绪标志位为“1”,指示可以接收数据;若接收FIFO满,则该标志为“0”。通过FIFO就绪标志位,可以确定CPU读/写FIFO的时间。 2DMA传输方式 ○在DMA传输方式,利用DMA控制器来控制发送和接收FIFO的数据存取,由FIFO就绪标志来自动请求DMA的服务。 3发送和接收方式 ○在发送和接收方式,IIS总线接口可以同时发送和接收数据。(4)S3C2410A IIS总线接口的音频串行接口格式 S3C2410A的IIS总线接口支持IIS总线数据格式和MSB-justified数据格式。IIS总线格式 ○IIS总线有IISDI(串行数据输入)、IISDO(串行数据输出)、IISLRCK(左/右通道选择)和IISCLK(串行位时钟)4条线,产生IISLRCK和IISCLK信号的为主设备。串行数据以2的补码发送,首先发送是MSB位。首先发送MSB位可以使发送方和接收方具有不同的字长度,发送方不必知道接收方能处理的位数,同样接收方也不必知道发送方正发来多少位的数据。 当系统字长度大于发送器的字长度时,数据发送时,字被切断(最低数据位设置为0)发送。接收器接收数据时,如果接收到的数据字长比接收器的字长更长时,则多的数据位被忽略。另一方面,如果接收器收到的数据位数比它的字长短时,则缺少的位设置为0。因此,MSB有固定的位置,而LSB的位置与字长度 有关。在IISLRCK发生改变的一个时钟周期,发送器发送下一个字的MSB位。 发送器发送的串行数据可以在时钟信号的上升沿或下降沿同步。然而,串行数据必须在串行时钟信号的上升沿锁存到接收器,所以发送数据使用上升沿进行同步时会一些限制。 左右通道选择线指示当前正发送的通道。IISLRCK可以在串行时钟的上升沿或者下降沿改变,不需要同步。在从模式,这个信号在串行时钟的上升沿被锁存。IISLRCK在MSB位发送的前一个时钟周期内发生改变,这样可以使从发送器同步发送串行数据。另外,允许接收器存储前一个字,并清除输入以接收下一个字。 2MSB-justified数据格式 ○MSB-justified总线格式在体系结构上与IIS总线格式相同。与IIS总线格式唯一不同的是,只要IISLRCK有变化,MSB-justified格式要求发送器总是发送下一个字的最高位。 2)音频编解码芯片UDAl341TS UDA1431TS可把通过麦克风音频输入通道输入的立体声模拟信号转化为IIS格式的数字信号,传送给S3C2410的IIS控制器,然后CPU使用DMA控制器把得到的数字信号存放的一块内存空间上;同样DMA控制器也能把已存的数字信号通过IIS格式发送给UDAl341TS芯片,由该芯片转换成模拟信号,通过耳机音频输出通道输出。利用UDA1341TS内部的PGA(可编程增益放大器)、AGC(自动增益控制)功能对模拟信号进行处理。对于数字信号,UDA1341TS提供DSP(数字音频处理)功能。 S3C2410A的IIS接口线分别与UDA1431TS的BCK、WS、DATAI、SYSCLK相连。当UDA1431TS芯片工作在微控制器输入模式时,使用UDA1431TS的L3总线(L3DATA、L3MODE和L3CLOCK)。L3DATA、L3MODE和L3CLOCK分别表示与微处理器接口的数据线(L3DATA)、模式控制线(L3MODE)和时钟线(L3CLOCK)。微控制器通过对UDA1431TS中的数字音频处理参数进行配置。S3C2410A没有与L3总线配套的专用接口,可以利用通用I/O口进行控制。第三章 Bootloader移植与下载 3.1 Vivi源代码安装 进入cygwin,Vivi源代码的安装: $> source /tmp/edukit-2410/set_env_linux.sh// Linux编译环境变量设置,第一次打开Cygwin必须设置。 $> cd $WORKDIR $> tar-xvjf /tmp/edukit-2410/source/vivi/vivi-20030929.tar.bz2 $> ls „ vivi „ „为$WORKDIR目录下其他内容 正确解压后,可以看到多了一个vivi目录,即vivi源代码的安装目录,后面的vivi配置及编译都得进入vivi目录进行。再为EduKit2410实验系统打入vivi源代码的补丁文件: $> cd vivi $> patch-p1 vivi的代码包括arch,init,lib,drivers和include等几个目录,共200多条文件。 Vivi主要包括下面几个目录: arch:此目录包括了所有vivi支持的目标板的子目录,例如s3c2410目录。drivers:其中包括了引导内核需要的设备的驱动程序(MTD和串口)。MTD目录下分map、nand和nor三个目录。 init:这个目录只有main.c和version.c两个文件。和普通的C程序一样,vivi将从main函数开始执行。lib:一些平台公共的接口代码,比如time.c里的udelay()和mdelay()。include:头文件的公共目录,其中的s3c2410.h定义了这块处理器的一些寄存器。Platform/smdk2410.h定义了与开发板相关的资源配置参数,我们往往只需要修改这个文件就可以配置目标板的参数,如波特率、引导参数、物理内存映射等。 3.3 Vivi编译与下载 1)Vivi源代码的编译 然后执行以下命令进行编译: $> source /tmp/edukit-2410/set_env_linux.sh Linux编译环境变量设置 $> cd $WORKDIR/vivi $> make clean 图3.1 vivi编译 $> make menuconfig输入配置smdk2410-amd:Nor Flash boot smdk2410:Nand boot 或 图3.2 图形界面下配置内核文件 其中,运行make menuconfig后,选择Load an Alternate Configuration file,配置文件名称如下: smdk2410:编译 vivi 在 Nand Flash(K9S5608)中运行; smdk2410-amd:编译 vivi 在 Nor Flash(AM29LV160DB)中运行。这两个配置文件在usrlocalsrcedukit-2410viviarchdef-configs中,须复制 到usrlocalsrcedukit-2410vivi中;或者可以在 menuconfig 中输入全部路径。配置好后,输入:$> make 图3.3 vivi映像文件生成 如果编过程中没有出现错误,则编译后的执行文件存放于 vivi 目录下。2)下载: 在下载模式下,vivi为用户提供一个命令行人机接口,通过人机接口可使用vivi提供的一些命令。如嵌入式系统没有键盘和显示,可以利用vivi中的串口,将其和宿主机连接起来,利用宿主机中的串口软件(如Windows中的超级终端或Linux中的minicom)来控制。第四章 Linux内核移植与下载 4.1 Linux内核源代码安装 linux源代码安装 运行cygwin,执行以下命令完成cygwin 环境下的Linux源代码的安装: $> source /tmp/edukit-2410/set_env_linux.sh Linux编译环境变量设置 $> cd $WORKDIR $> tar –xvjf /tmp/edukit-2410/linux-2.4.18-rmk7-pxa1-mz5-i2c.tar.bz2 $> ls „ kernel „ „为$WORKDIR 目录下其他内容 图4.1 linux内核安装 正确解压后,相比之前可以看到多了一个kernel目录,即kernel源代码的安装目录,后面的Linux配置及编译都得在kernel目录进行。 实验中提供的linux内核已经包含了Linux源代码的补丁文件、I2C和网络驱动模块 4.2 Linux内核源代码分析与移植 4.2.1 Linux源代码分析 Linux内核由5个主要的子系统组成。这5个子系统分别是进程调度(SCHED)、内存管理(MM)、虚拟文件系统(Virtual File System,VFS)、网络接口(NET)和进程间通信(IPC)。 进程调度控制着进程对CPU的访问。当需要选择下一个进程运行时,由调度 程序选择最值得运行的进程。可运行进程实际是仅等待CPU资源的进程,如果某个进程在等待其它资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。 内存管理允许多个进程安全地共享主内存区域。Linux的内存管理支持虚拟内存,即在计算机中运行的程序,其代码、数据和堆栈的总量可以超过实际内存的大小,操作系统只将当前使用的程序块保留在内存中,其余的程序块则保留在磁盘上。必要时,操作系统负责在磁盘和内存之间交换程序块。内存管理从逻辑上可以分为硬件无关的部分和硬件相关的部分。硬件无关的部分提供了进程的映射和虚拟内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。 虚拟文件系统隐藏了各种不同硬件的具体细节,为所有设备提供了统一的接口,虚拟文件系统还支持多达数十种不同的文件系统,这也是Linux较有特色的部分。虚拟文件系统可分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2、fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。 网络接口提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序两部分。网络协议部分负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备进行通信,每一种可能的硬件设备都有相应的设备驱动程序 4.2.2 Linux内核及硬件模块驱动移植 内核和文件系统、图形用户系统(GUI窗口系统)可以分开,它们的开发、移植、下载甚至运行都是可以分开的。内核移植是一个比较复杂的任务,也是嵌入式系统开发中非常重要的一个过程。内核移植一般包括内核配置、内核编译和内核下载3大步骤。 4.3 Linux内核编译与下载 4.3.1 Linux内核源代码安装 运行cygwin,执行以下命令完成cygwin环境下的Linux内核源代码的安装: $> source /tmp/edukit-2410/set_env_linux.sh //Linux 编译环境变量设置 $> cd $WORKDIR $> tar –xvjf /tmp/edukit-2410/linux-2.4.18-rmk7-pxa1-mz5-i2c.tar.bz2 $> ls „ kernel „ //„为$WORKDIR 目录下其他内容 正确解压后,可以看到多了一个kernel目录,即kernel内核源代码的安装目录,后面的Linux内核配置及编译都得进入kernel目录进行。实验中提供的linux内核已经包含了Linux源代码的补丁文件、IIC和网络驱动模块。4.3.2 Linux内核的编译 $> cd kernel 图4.2 $> make mrproper 清除所有的旧的配置和旧的编译目标文件等 $> make xconfig 在图形界面下对内核进行配置(配置方法之一)执行make xconfig 后,弹出如图4.3的内核定制界面: 图4.3 内核定制界面 选择按钮”Load Configuration from File”,如图4.4输入smdk2410: 图4.4 内核配置文件 选择配置sound ,设置Sound support为y: 设置BT878 audio dma为y: 设置SMDK-2410 audio support为y: 设置OSS sound modules为y: 根据提示加载配置文件后,点击按钮”Store Configuration to File”,如图4.5输入audio1: 图4.5 存储配置文件 保存,Save and Exit。如图4.6 图4.6 $> make dep //搜索Linux编译输出与源代码之间的依赖关系并生成依赖文件。 图4.7 $> make clean //清除构造内核时生成的目标文件、模块文件和临时文件。$> make zImage //生成压缩的内核映像文件。 图4.8 编译通过后,在/usr/local/src/edukit-2410/kernel/arch/arm/boot/目录下生成内核的压缩映像文件为“zImage”,此文件是最后要烧写到开发板的内核映像文件。 4.3.1 Linux内核下载 内核下载: 1)启动超级终端(波特率为115200),连好串口线,在开机瞬间快速按空格键,进入vivi控制台命令行下;打开S3C2410&NandFlash_vivi.cfg,在Flash Programmer的Progarm页中选择:vivi.bon&load.bin文件进行烧写。如图4.9 图4.9 烧写界面 点击按钮Progarm开始烧写,直到烧写成功;连接串口到PC机COM1,运行成功;连接串口线到 PC 机 COM1,运行光盘中提供的 Windows 超级终端 Hyper Terminal.ht;开发板重新加电,程序运行后,在超级终端上可以看到串口输出类似以下信息: 图4.10 超级终端界面 看到以上信息后,表示正在等待用户从超级终端下载文件。这时,请点击超 级终端菜单“传送”选择 Xmodem 方式下载 vivi.nand 文件,点击 OK 后等待下载烧写结束即可。 图4.11 添加传送文件 图4.12 下载vivi nada 2)在vivi启动等待中,敲入空格键进入vivi界面环境,并输入以下命令: vivi> load flash kernel x <回车> 烧写更新内核约4分钟即可烧写完毕,如图4.13 图4.13 等待下载 3)立即选择要发送的文件,比如zImage文件,这里Linux环境下源代码arch/arm/boot目录下的zImage内核映像文件已转移到 windows某目录下。要选择合适的xmodem协议。以上操作完成 后,单击“发送,几分钟后即可发送完毕。 图4.14 发送zImage 图4.15 下载成功 第五章 课程设计功能模块程序设计与交叉编译 5.1 课程设计模块功能 5.1.1 三个模块: I2S音频总线接口电路 ;音频编解码器芯片udal41; DMA控制器; 5.1.2工作过程: 麦克风输入的模拟音频信号在音频编解码器中经过A/D转换和编码将模拟信号转换成数字信号,将这些数字信号先传给I2S音频总线接口电路中的FIFO,再由DMA控制器送入DSP中做相应的处理,这是录音的过程;DMA控制器将DSP中存储的信号传送给I2S音频总线接口电路中的FIFO,再发送给音频编解码芯片进行D/A转换,通过耳机输出模拟信号。 5.2 功能模块驱动程序设计 5.2.1 关于驱动结构体 由于目前许多硬件厂商在出售各种产品时,一般都不带Linux下的设备驱动程序,而且编写驱动程序的工作量占整个系统工作量的很大的一部分,这使得Linux下设备驱动程序的开发变得越来越重要。 本课程设计不要求自己编写驱动程序,但要求分析UDAl341TS驱动程序,以便编写出语音采集与播放的应用测试程序,同时为以后编写驱动程序打好基础。嵌入式Linux系统下的IIS音频驱动程序是在/usr/local/src/edukit-2410/drivers/sound 中,3c2410-uda1341.c 文件即是。 关于结构体: 在音频驱动程序中有2个比较重要的结构体: typedef struct { int size;/* buffer size */ char *start;/* point to actual buffer */(内存虚拟地址起始地址)dma_addr_t dma_addr;/* physical buffer address */(内存物理地址起始地址) struct semaphore sem;/* down before touching the buffer */ int master;/* owner for buffer allocation, contain size when true */(内存大小) } audio_buf_t;typedef struct { audio_buf_t *buffers;/* pointer to audio buffer structures */ audio_buf_t *buf;/* current buffer used by read/write */ u_int buf_idx;/* index for the pointer above */ u_int fragsize;/* fragment i.e.buffer size */(音频缓冲区片大小) u_int nbfrags;/* nbr of fragments */(音频缓冲区片数量)dmach_t dma_ch;/* DMA channel(channel2 for audio)*/ } audio_stream_t;audio_stream_t是一个管理多缓冲区的结构体,为音频流数据组成了一个环形缓冲区。audio_buf_t管理一段内存,audio_stream_t管理N个audio_buf_t。 音频驱动的两个file_operations结构定义如下: static struct file_operations smdk2410_audio_fops = { llseek: smdk2410_audio_llseek, write: smdk2410_audio_write, read: smdk2410_audio_read, poll: smdk2410_audio_poll, ioctl: smdk2410_audio_ioctl, open: smdk2410_audio_open, release: smdk2410_audio_release };static struct file_operations smdk2410_mixer_fops = { ioctl: smdk2410_mixer_ioctl, open: smdk2410_mixer_open, release: smdk2410_mixer_release };这里定义了两种类型设备的file_operations结构,前者是DSP设备,后者是混频器设备。Linux 内核内部通过file结构识别设备,通过file_operations数据结构体提供文件系统的入口点函数,也就是访问设备驱动程序里的函数。file_operations结构体原型是在 read()、write()、open()和ioctl()是struct file_operations结构体中的接口函数。 1)read()函数:由已打开的文件读取数据,即播放。 (1)函数定义:ssize_t read(struct file *file, char *buffer, size_t count, loff_t * ppos);(2)函数说明:把参数file所指的文件传送count个字节到buffer指针所指的内存中;若参数count为0,则read()不会有作用并返回0;(3)返回值:返回值为实际读取到的字节数,如果返回0,表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动。如果正确会返回实际读到的字节数,最好能将返回值与参数count作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read()被信号中断了读取动作。当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期;2)write()函数:将数据写入已打开的文件内,即录音。 (1)函数定义:ssize_t write(struct file *file, const char *buffer, size_t count, loff_t * ppos);(2)函数说明:把参数buffer所指的内存写入count个字节到参数file所指的文件内。当然,文件读写位置也会随之移动;(3)返回值:若正确会返回实际写入的字节数;当有错误发生时则返回-1,错误代码存入errno中。 3)open()函数:打开音频设备。 (1)函数定义:int(*open)(struct inode *inode, struct file *file);(2)函数说明:参数inode为设备特殊文件的incode(索引结点)结构的指针,参数file是指向这一设备的文件结构的指针。open()的主要任务是确定硬件是否处在就绪状态,验证次设备号的合法性,控制使用设备的进程数; (3)返回值:如果打开文件成功,open会返回一个文件描述符,以后对文件的所有操作就可以对这个文件描述符进行操作。比如程序中open()函数的返回值赋给了应用程序中的devfd,后面则可以对其进行操作;若打开失败返回负数。 4)ioctl()函数:用于设置编码比特、采样频率和选择声道。(1)函数定义:int ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg);(2)函数说明:设备驱动程序中对设备的I/O通道进行管理的特殊控制函数,可以通过它向设备传递控制信息或从设备取得状态信息,实现用户程序命令和驱动命令的相互联系; (3)返回值:执行成功返回正数,失败返回-1。 5)s3c2410_uda1341_init()函数:动态加载驱动模块时的初始化函数。(1)函数定义:int __init s3c2410_uda1341_init(void); (2)函数说明:该函数首先会初始化I/O和UDA1341 芯片,然后申请2个DMA 通道用于音频传输。将输出音频缓冲区的DMA通道设为通道2,输入音频缓冲区的DMA 通道设为通道1。最后调用register_sound_dsp()和register_sound_mixer()两个函数来分别注册驱动设备; (3)返回值:初始化成功,返回0;DMA 通道初始化设置失败,返回负数。6)void __exit s3c2410_uda1341_exit()函数:动态卸载驱动模块时调用的函数。 (1)函数定义:void __exit s3c2410_uda1341_exit(void); (2)函数说明:注销音频设备,分两次调用audio_clear_dma()函数来分 别释放已申请的音频输入和音频输出的DMA 通道; (3)返回值:无。 5.3 功能模块交叉编译 用命令Makefile来编译: 图5.1 编译测试文件 将test文件拷贝到D:cygwinusrlocalsrcedukit-2410rootbin中 执行以下命令生成新的文件系统映象: $>cd $WORKDIR/ $>$SOURCEDIR/mkcramfs root root.cramfs.new 图5.2 生成系统映像文件 生成文件系统映象文件root.cramfs.new。第六章 根文件系统建立与文件系统下载 6.1 根文件系统分析 6.1.1 cramfs 目录结构 一个完整的根文件系统通常包含以下几个目录: /bin 应用程序存放目录。 /sbin 系统管理员服务程序,其中最重要的就是供内核初始化之后执行的/sbin/init 进程。 /lib 存放程序运行所需要的动态库。/proc 系统状态文件目录。/dev 驱动程序存放目录。 /etc 系统配置文件及用户数据存放目录。 /mnt 用于设备安装的目录,通常包含etc 子目录和为块设备安装保留目录。/usr 用于存放用户程序和配置文件的目录,可以根据需要进行设置。一般情况下都要把已经规划好的目录结构转换成一个映象文件,即使用命令工具mkcramfs(cygwin下为mkcramfs.exe),把相应的cramfs 目录树压缩为单一的映象文件。其命令格式为: mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile 使用mkcramfs.exe 在cygwin 下编译生成文件系统映象文件root.cramfs,再固化到开发系统FLASH 上运行。6.1.2 构建cramfs 文件系统 按照本节实验原理中自行构建一个cramfs 文件系统。运行cygwin,执行以下命令解压安装: $> source /tmp/edukit-2410/set_env_linux.sh //Linux 编译环境变量设置 $> cd $WORKDIR/ 图6.1 构建文件系统 $> tar-xvjf /tmp/edukit-2410/root.cramfs.tar.bz2 $> ls „ root „ root 文件夹中就是我们想要的cramfs 文件系统 6.2 文件系统映像文件生成 6.2.1 编译一个应用测试程序test.c 按设计原理要求编写一个应用程序test.c,存放在/home/app/audio目录下,进入该目录后执行以下命令编译链接测试程序: $> cd /home/app/audio $> make(也可以编写Makefile 来编译) 图6.2 编译test文件 6.2.2 拷贝测试程序到文件系统中,并编译生成文件系统映象 把刚才编译输出的test文件拷贝到文件系统所在的工作目录 root/usr/audio 目录下,执行以下命令生成新的文件系统映象: $> cd $WORKDIR/ $> $SOURCEDIR/mkcramfs root root.cramfs.new 图6.3 生成映象 刚刚编译生成的文件系统映象root.cramfs.new 中已经包含测试程序。 6.3 文件系统下载 (1)首先SW104 设为短接(从Nand Flash 启动),确定已经成功烧写vivi 和linux kernel,加电运行可以看到vivi 启动信息,输入空格进入命令状态; (2)双击运行Download.pjf 工程文件(将启动Embest IDE 环境),点击连接Remote connect,程序应该正在运行(此时命令按钮STOP 为红色);在超级终端输入help 看看有没有反应,如果没反应,点击IDE 按钮:Reset->Start(F5);再输入help 测试,直到有反应为止; (3)如果超级终端可以输出一些信息,再点击IDE 中的Stop,配置Debug 的Download 地址为0x30000000,并点击IDE 菜单Project 选择Settings 项,在Download 页下拉Category 到Download 项,在Download File 选择root.cramfs.new 文件,路径为d:Cygwinusrlocalsrcedukit-2410点击确定后: 图6.4 选择加载的文件 首先点击IDE 菜单DEBUG 选择Download 下载文件系统映象 约1-2 分钟 图6.5 下载成功 其次下载完毕后,点击Start(F5)然后在超级终端里输入:load flash root j(烧写更新文件系统) 图6.6 烧写 注意:只能在“vivi的烧写”和linux内核操作完成后,才可以按以上方法正确烧写root映象到NandFlash。重起实验板,观测超级终端窗口提示信息,引导整个系统启动到linux行命令输入状态。在超级终端输入一些linux命令查看执行结果是否正确。 6.4 功能模块运行与调试 重新加电,在超级终端根据提示启动Linux,按提示输入cd bin、./test指令。 图6.7 输入指令 图6.8 在控制台下运行测试程序 程序执行完后。如图6.9。 图6.9 程序运行时超级终端的输出 第七章 课程设计总结与体会 7.1 得出的结论 通过按上述步骤执行相关应用程序,可以实现对语音的实时采集和播放。需改进的地方:通过录制一段语音信息,录制完成后再播放 7.2课程设计过程中遇到的问题及解决方法 1.在给vivi打补丁时,$> patch-p1 2.在图形界面下进行内核配置时按实验指导书配置导致少了sound这一步导致出错。 3.重新在图形界面下配置后,发现无法生成压缩映像文件。请教研究生后解决了。原来之前配置错误生成了boot文件夹,要把之前boot删掉后重新编译。4.在调试时输入cd bin,./test指令后超级终端无反应。查找后发现,原来在根文件系统编译时没把生成的test文件复制到文件系统所在的工作目录root/bin目录下。重新编译后把生成的test文件复制后在调试后可以进行录放测试。 7.3 心得体会 课程设计刚开始的时候,思绪全无,我真的感到 “书到用时方恨少”,所以又重新把书和实验指导看了几遍,对知识系统而全面进行了梳理,对许多不理解的地方通过上网搜索翻阅图书弄懂,终于熟练掌握了基本理论知识,而且领悟诸多平时学习没有注意到的细节步骤,学会了如何思考的思维方式,找到了设计的灵感。 虽然每天要顶着30多度的高温在宿舍跟实验室之间往返,流了不少汗水,感觉确实不舒服,可最后看到自己的成果后心里很充实很高兴。 在课程设计过程中遇到了这样那样的困难。有时候是电脑出问题了,有时候 是实验箱出毛病,有时候是自己在操作过程中操作错误无法继续,可在研究生学长和其他同学的帮忙下都一一解决。使我深深感觉到团队力量的强大。 最后再次感谢陈老师这学期兢兢业业地给我们传授知识,感谢三位研究生牺牲自己的时间在炎热的夏天帮助我们解决遇到的问题! 参考文献 [1]徐英慧,等.ARM9嵌入式系统设计——基于S3C2410与Linux[M].北京:北京航空航天大学出版社,2007.[2]于明,等.ARM9嵌入式系统设计与开发教程[M].北京:电子工业出版社,2006.[3]田泽.ARM9嵌入式开发实验与实践[M].北京:北京航空航天大学出版社,2006.[4]孙天泽,等.嵌入式设计及Linux驱动开发指南——基于ARM9处理器[M].2版.北京:电子工业出版社,2007.[5]周立功,等.ARM9&WinCE实验与实践——基于S3C2410[M].北京:北京航空航天大学出版社,2007.[6]Samsung Electronics.S3C2410A-200MHz & 266MHz 32-Bit RISC Microprocessor USER’S MANUAL Revision 1.0.http://www.xiexiebang.com [7]魏洪兴.嵌入式系统设计师教程[M].北京:清华大学出版社,2006.[8]张纪坤,等.嵌入式Linux系统开发技术详解——基于ARM[M].北京:人民邮电出版社,2006.[9]吴明辉,等.基于ARM的嵌入式系统开发与应用[M].北京:人民邮电出版社,2004.[10]王田苗.嵌入式系统设计与实例开发[M].2版.北京:清华大学出版社,2003.[11]俞建新,等.嵌入式应用程序开发综合实验9例[M].北京:清华大学出版社,2004.[12]许海雁,等.嵌入式系统技术与应用[M].北京:机械工业出版社,2002.36 基于A8的嵌入式Linux远程视频监控系统的设计与实现 摘 要:将网络技术和嵌入式技术相结合的远程视频监控系统是视频采集技术的发展趋势,文中提出了一种基于对等网络模型的嵌入式远程视频监控系统的设计方案。该方案将嵌入式系统和Web开发技术相结合,再利用USB摄像头作为视频监控系统的终端进行图像采集,并使用网络TCP协议将其远程发送给服务器终端。相较于传统的Client/Server网络模型,本系统实现采用对等网络模型,即确定发送命令的控制程序既可以是客户端,又可以是服务端。文中选择嵌入式开发平台ARM系列A8处理器进行研究和设计,并采用PC机下的Linux系统作为主机开发环境。 关键词:嵌入式;视频监控;网络远程控制;对等网络 中图分类号:TP39 文献标识码:A 文章编号:2095-1302(2016)05-00-03 0 引 言 网络远程控制(Network Remote Control,NRC)是利用计算机网络对远程计算机进行操作的一种控制方式。计算机技术和网络技术目前都在高速发展,现在监控系统已经发展到网络视频监控系统[1]。网络视频监控具有数字视频监控和网络传输技术的优点,其具有不受地理位置约束、扩展方便简单、信息处理较容易等特点,可以使远程的管理和维护变成现实,只要是网络覆盖的地方,就能实现网络监控[2]。嵌入式系统向网络发展已成必然趋势,目前嵌入式系统对网络协议如TCP/IP协议和HTTP协议的支持也越来越广泛。系统硬件设备选择与配置 系统硬件设备选择凌阳嵌入式A8教学实验系统进行设计与实现。该实验箱基于ARM CortexTM-A8内核的处理器S5PV210,该芯片又名“蜂鸟”(Hummingbird),是三星公司推出的一款适用于智能手机和平板电脑等多媒体设备的应用处理器[3]。本系统使用了人机交互模块的USB接口、多媒体模块摄像头接口及通信模块以太网接口。 1.1 USB摄像头 摄像头属于视频类设备。在目前的Linux核心中,视频部分的标准是Video for Linux(简称V4L)。这个标准其实定义了一套接口,内核、驱动、应用程序以这个接口为标准进行交流。目前的V4L涵盖了视、音频流捕捉及处理等内容,USB摄像头也属于它支持的范畴。 本系统所采用的嵌入式Linux操作系统如果需要使用USB摄像头则必须在内核配置时添加Video4Linux驱动和对USB摄像头驱动模块的支持。本系统的设计与实现采用静态加载以上驱动。首先进入Linux源代码所在的目录,在终端输入make menuconfig命令,在基于Ncurses内核配置图形界面进行内核选项的配置。选中多媒体设备选项“Multimedia device->”,进入多媒体设备配置界面,选中“Video For Linux”,加载Video4Linux模块,就可以使内核实现对Video4Linux驱动的支持,为视频采集设备提供编程接口。在内核配置主界面,选中USB支持选项“USB support―>”,选中“USB Multimedia device”选项下的“USB OV511 Camera support”,使内核中加入OV511接口芯片的USB数字摄像头的驱动支持。OV511 USB 摄像头驱动配置界面如图1所示。 图1 OV511 USB 摄像头驱动配置界面 1.2 开启帧缓冲设备 帧缓冲(Frame Buffer,FB)是Linux为显示设备提供的一个接口,是把显存抽象后的一种设备,它允许上层应用程序在图形模式下直接对显示缓冲区进行读写操作。由于FB设备驱动为受限驱动,因此必须进行设备开启。本系统开发环境采用发行版Linux操作系统Ubuntu10.10,Ubuntu下启用FB设备的一般步骤如下所示: 安装v86d和hwinfo两个包查看显卡是否支持,并设置本机支持模式。 修改启动文件/etc/default/grub,如图2所示。 图2 修改启动文件图 修改modules文件/etc/initramfs-tools/modules,如图3所示。 图3 修改modules文件 更新以上两个文件并重启系统,即可查看到FB设备,具体如图4所示。 图4 查看FB设备系统软件设计 本系统软件由摄像头驱动模块、图像采集模块、网络传输模块和网络服务器模块组成[4]。摄像头驱动模块使得摄像头为应用程序编写提供系统编程接口。功能主要包括摄像头设备信息的获取与设置、设备的打开和关闭、信号通道选择、窗口初始化等。图像采集模块的作用是使用编程接口获取摄像头采集来的图像信息并进行暂时存储。服务器通过网络传输模块与远程监控PC机端进行信息交流。 2.1 V4L图像信息采集流程 V4L图像信息采集流程分为如下几步: (1)打开摄像头设备 int vd->fd = open(“/dev/video0”,O_RDWR); (2)读video_capability 中的信息,成功后可读取vd->capability各分量ioctl(vd->fd,VIDIOCGCAP,&(vd->capability)); (3)读video_picture中的信息,成功后可读取图像的属性ioctl(vd->fd,VIDIOCGPICT,&(vd->picture)); (4)初始化channel int i; for(i = 0; i capability.channels; i++){ vd->channel[i].channel = i;第二篇:嵌入式远程视频采集系统的设计与实现(基于S3C2410)
第三篇:基于ARM的视频采集系统的设计与实现
第四篇:嵌入式系统语音采集与播放程序设计
第五篇:基于A8的嵌入式Linux远程视频监控系统的设计与实现