基于Java的高速公路收费管理系统的设计与实现(精选8篇)
【摘 要】本文阐述了基于Struts2+Spring+Hibernate开源框架实现高速公路收费管理子系统的开发流程。本文首先对Struts2、Hibernate、Spring等框架进行论述,其次描述了系统的需求分析与总体架构设计,包括系统的功能需求、性能需求、功能结构设计和体系结构设计等;然后详细介绍了系统的各个模块的具体实现,主要模块有登陆模块、数据录入模块、维护模块等;最后,对系统进行的测试并对项目的主要工作和存在的不足做了论述。
【关键词】Struts2;Spring;Hibernate
0 引言
基于B/S结构的Web程序的开发,有非常大的灵活性,允许用户远程访问系统资源的同时能对数据平台和管理访问权限进行有效的保护。B/S结构软件的所有的客户端只是浏览器,也只需要管理服务器,更为快捷、方便、高效。与C/S体系结构相比,B/S体系结构不仅具有C/S体系结构的全部优点,而且具有客户端零维护、可扩展性好、安全性好、资源重用性好等新的优点。系统需求分析
计算机收费系统式收费站的主要组成部分[3]。每个收费站由网络服务器、管理计算机构成的上端管理系统和若干个车道控制计算机构成 的车道控制系统组成局域网。高速公路计算机收费系统的目标是:按照每辆车的车型和实际行驶里程收费;提高收费的工作效率,尽量降低由于收费过程引起的交通延误,提高高速公路的通行能力;实现高速公路的现代化营运管理为智能运输系统的实现留有一定的接口。基于系统的以上目标,收费系统应该具有以下功能:
1)实行计算机管理,尽量减少人为干预,保证车型判别的正确性。
2)系统能自动检查设备运行状态,能准确并及时地给出故障信息和故障排除信息。
3)系统应该是全天候、实时的,如收费车道应该在任何时间有车辆通过时能正常使用。
4)具有一定的报警功能,如遇抢劫时的远程报警,与车辆冲关或进出口收费员判刑不一致时报警。
根据以上对系统需求的描述和功能的分析,对于收费管理系统,它主要处理的数据是收费数据,主要包括 4个模块:数据登录模块,录入模块,维护模块。技术平台
2.1 MVC模式和Struts框架
MVC某种语言所特有的设计思想,而是所有面向对象程序设计语言都应该遵守的规范[4]。MVC思想将应用分为三个基本部分:模型、视图、控制器。这三个部分将以最少的耦合协同工作,从而提高应用的可扩展性及可维护性。
Struts2是Struts的下一代产品,是一个优雅的,可扩展的Java EE Web框架[5]。它是Struts和WebWork的技术基础上进行合并的全新的Struts2框架。但是,Struts2没有继承Struts1的血统,而是继承WebWork的血统。Struts框架作为MVC模式的典型实现,对Model、View和Controller都提供了对应的实现组件。
2.2 Spring框架
Spring框架是一个分层架构,由7个模块组成,各个模块之间是相互的。Spring其他模块构建在核心容器之上,其中,核心容器定义了创建、配置和管理bean的方式。系统实现
在系统需求分析和设计的基础上,在系统的开发过程中,将SSH架构应用到实际的项目开发中,并且利用第三方报表开发软件开发报表部分,极大地简化了系统的开发,提高了效率。在整个系统的实现过程中,本文主要实现了收费管理系统模块。
3.1 数据登录模块
用户登录模块的设计中完全实现了MVC模式,实现了视图与数据处理的分离。登录页面、修改密码页面以及登录成功页面构成视图层;用户登录及修改密码的请求应答控制由控制器实现;具体的用户信息合法性由Struts2提供的客户端输入校验完成,保证输入信息的合法性。图1是用户登录的简要图。
3.2 录入模块
数据录入模块主要就是报表文件的开发,设计报表文件,首先要打开设计器,连接到数据源,然后开始进行报表文件的设计。本模块中报表文件,仅用于数据录入,因此可以创建的报表应该选择填报或参数表单。然后在快逸报表中的表格中填写选项,设置选项的属性要根据需求来设置,包括设置数据的格式,编辑的风格、是否可写,能否为空等。
3.3 维护模块
该模块主要是负责维护人员名单的相关信息。由于本系统是内部人员使用的系统,用户较少,不需要通过注册来添加人员,而是通过该模块来添加删除人员或者修改其权限。
主要涉及到的信息包括:站号、用户ID、用户名、用户密码、班次编号、录入权限、监视权限、统计权限、检索权限、稽查权限、维护权限、票据管理权限、卡管理权限等,如表1所示。其中各种管理权限来自于用户信息中purview字段,每个比特位代表一种权限。结论
系统采用SSH(Struts2+Spring+Hibernate)轻量级框架,完成了高速公路收费管理系统的开发,对三个框架的使用和集成有了深刻的认识。本文详细介绍了三个框架的背景、相关技术以及内部实现原理,包括MVC的开发模式、ORM技术以及IOC和AOP,这些对于系统的开发有非常重要的帮助。项目基于MVC的思想进行开发,Struts2框架负责了表示层和控制层;采用Hibernate框架以面向对象的方式来访问数据库,极大地简化了数据库操作;Spring框架将业务层又细分为业务逻辑层和数据持久层,使得接口和实现进一步的分离,使开发者从繁杂的事务管理中解脱出来,而专注于业务逻辑的处理。
【参考文献】
交通的发展是国家国民经济发展的基础, 近几年来随着我国经济的不断发展, 道路交通设施有了很大的变化。然而在交通主骨架迅猛发展的同时, 高速公路的管理难度也逐年增加, 带来的问题也越来越严重。原因多在于道路公司多是重视建设而忽略管理。所以出现了虽然基础设施建设增多, 但却因忽视管理带来了不可预计的经济损失, 也就影响了社会效益。随着科技的进步, 越来越多的智能化管理系统进入了人们的工作生活。但大部分的管理系统设备满足不了现在工作的需求, 因为冗杂的系统功能给人们的工作带来诸多的不便, 而且大部分的现有的系统是由高速公路联网收费系统, 高速公路监控系统, 高速联网收费数据查询分析平台三部分组成, 设备老化单一。在数据量越来越庞大的情况下, 不仅仅增加了人们的工作负担, 而且人工稽查也出现了越来越多的失误, 因而影响到道路交通部门的经济情况。
组织研发高速公路运营管理系统以实现打击偷逃行费、实现收费还贷, 提高高速公路收费稽核管理水平是现阶段迫切需要的。
2 系统功能分析
系统实现结构图如图1所示。
2.1 联网收费管理模块
联网收费系统利用半自动和ETC两种收费方式, 外联IC卡作为通行卡或者是现金支付等支付手段。电子不停车收费系统 (ETC) 利用挡风玻璃上的电子标签和收费通行卡通过与微波技术与ETC车道的装置交换数据, 收费系统根据收到的数据完成交易扣费, 实现不停车收费。
2.2 收费稽查管理模块
费稽查管理模块通过手工稽查或者系统自动稽查方式一方面通过调用监控日志、收费记录信息、行车记录以及业务员的操作信息对收费进行稽查, 通过分析模型, 自动完成数据分析, 并生成数据记录。对一定次数以上违规的车辆进行费用追回以及拉黑处理, 对于违规操作的业务员进行扣分以及记录;另一方面通过监控以及手机呼叫功能对路况进行稽查, 对异常路段 (维修, 交通事故等路段) 进行标记上传并将出现路况的路段中的车辆进行手机业务短信通知。
2.3 违规处理模块
违规处理模块主要功能是处理员工在工作中所犯的错误导致违反了公司的规章制度的方式的记录。传统的手工记录模式使得记录人的工作量不断加大。当加入该子系统后, 记录人的工作设备更新为现代化的计算机, 仅仅需要从数据库中调出员工的基本信息就可以进行记录, 备份后将新的数据插入到数据库的数据表中, 在进行绩效考核的时候, 通过查询数据库中的数据可以直观地了解每位员工的详细工作状况。很显然, 这无疑减轻了相关员工的工作压力, 提高了工作的效率。
2.4 业务人员信息管理模块
该模块员工可以更改、查询以及删除基本信息, 例如部门、现任职务、邮箱、电话和家庭住址等。当然, 对于隐私信息, 只能由员工本人通过自己拥有的权限进行以上操作。公司正常地运营, 离不开管理层的有效管理, 所以各级领导不仅可以依据人员类别、组织机构代码查询公司岗位、各组织之间的联系, 还可以查询每个员工的基本信息了解基层员工的工作能力与工作状况, 方便做出相应的决策。
2.5 报表模块
报表系统在现代企业中发挥着越来越重要的作用, 在这套系统中我们使用了现在流行的交互式报表。该子模块提供了完整的业务建模功能, 实现了报表业务的统一部署和管理。交互式报表不同于传统的报表系统, 传统报表是以一种相对静态的数据表现形式, 而交互式报表是一种可以动态化的进行业务分析的报表解决方案, 可以用到数据可视化、向下钻取、贯穿钻取、数据过滤、数据排序等功能, 易于操作学习, 提供了非常友好的用户界面, 更能适应商业智能的需求。
3 系统设计与实现
B/S开发模式B/S开发模式是在WEB兴起后的一种新型网络结构模式, 客户端最主要的应用软件就是WEB浏览器的三层结构模式。利用这种构架可以大大简化客户端电脑的载荷, 减轻系统维护与升级的成本, 较少工作量, 降低用户的使用成本, 同时提高产品的使用效率。
ASP.NET是一种由多种相关语言进行具体开发的一套开发框架, 它可以由C#、VB.NET多门语言进行开发, 在ASP.NET中有很完整的框架类库。ASP.NET不但可以大幅度执行效率而且在对代码的控制上也处理的很好, 并且支持Web Controls功能和多种语言, 为系统的安全性、易管理性和扩展性提供了很好的技术支撑。
j Query是一个非常优秀的Java Script库, 产生于Prototype之后, j Query扩大了Java Script的功能, 其凭借简洁的语法和跨平台的兼容性, 很大程度上简化了Java Script开发人员遍历HTML文档, 操作DOM, 处理事件, 执行动画和开发Ajax的操作。Java Script程序员的设计程序和编写程序的的方式也因其独特的代码特点而改变。
4 结语
该系统的设计开发, 在很大程度上提高了公司人员对稽查以及收费业务工作的工作质量, 提高了工作效率, 使得相关工作的管理达到了现代化的管理需求。通过本系统能对公司的整个工作工作过程进行全面的管理, 包括对人员工作的基础数据的控制, 对稽核数据的分析, 系统的用户管理以及系统的配置管理等管理方便了对数据的管理和操作, 增加了减轻工作人员的负担, 加快了高速公路系统进入现代化的进程。
参考文献
[1]邓芳, 毕忠东, 刘启明.ASP.NET网站设计实例教程.清华出版社, 2015.
[2]黄兴荣.基于B/S架构模式的三层结构设计与实现[J].电脑知识与技术, 2015, (32) :52-53.
[3]邓芳, 毕忠东, 刘启明.ASP.NET网站设计实例教程.清华出版社, 2015
[4]胡海斌, 冉利龙.JQuery Tooltipster在网站开发中的应用[J].电脑编程技巧与维护, 2015, (12) .
【摘 要】本文阐述了在Java平台上,利用AWT组件以及JDBC-ODBC桥连接数据库,讲述了一个简单的商品销售管理系统的设计与实现过程。Java提供了许多组件,相比较C/C++的设计语言,Java更适合与用户的交互设计,其语言更加简练,提供的组件也更加易于理解与运用。【关键词】Java;awt;JDBC-ODBC;商品销售管理 一、技术支持1、java.awt包Java平台提供了AWT组件,它是Java提供的用来建立和设置Java的图形用户界面的基本工具,为图形用户界面提供用户接口,通过这个接口可以继承多种方法,使应用程序更好地与用户进行交流。2、JDBC-ODBC桥JDBC-ODBC桥是一个JDBC驱动程序,通过将JDBC操作转换为ODBC操作来实现JDBC操作,桥为所有对ODBC可用的数据库实现JDBC。实现的包为sun.jdbc.odbc,包含一个用于ODBC的本地库。使用JDBC-ODBC桥,用通过ODBC子协议,用URL打开JDBC连接和Class.forName显示加载方式进行加载桥驱动程序类,加载时ODBC驱动程序创建实例,同时在JDBC驱动程序管理器进行注册。二、系统需求商品由生产厂家提供,并由企业的库存管理人员进行入库记录。有用户提交订单请求时,企业的销售管理人员对订单进行审核,与库存人员沟通,库存人员对库存审核,出库记录,然后销售人员将商品售给客户。所有人员均由主管理员来负责管理。根据上述功能需求,我们将系统的角色划分为5类:普通用户:查看个人信息,下订单,退订,查看订单;主管理员:增、删、改、查各类别用户;商品管理员:增、删、改、查商品信息;销售管理员:审核订单,查看订单,生成报表;厂商管理员:增、删、改、查厂商信息;库存管理员:商品入库、出库。三、系统设计1、数据库设计系统涉及用户信息、商品信息、库存信息、厂商信息与订单信息,可以建立5个表:用户表(User)、商品表(Goods)、订单表(MyOrder)、厂商表(Factory)、库存表(Save)。以用户表为例,用户表内的字段及其属性见表1:2、模块设计商品销售系统的用户角色可分为两类:管理员与用户。不同的管理员授予不同的任务,将功能划分为模块,管理员的功能模块如图1。四、系统实现1、建立ACCESS数据源通过JDBC-ODBC桥,可用读取Access数据库。在计算机的ODBC数据源中,通过添加Access Database创建数据源*.mdb,并添加数据库名。由此,在访问数据库时可直接调用数据库的名字来连接数据库。连接数据库的关键代码如下:String JDriver = "sun.jdbc.odbc.JdbcOdbcDriver"; //声明JDBCString conURL="jdbc:odbc:Sale"; //定义JDBC的URL对象驱动程序对象Class.forName(JDriver); //加载JDBC-ODBC桥驱动程序Connection con=DriverManager.getConnection(conURL);//连接数据库URLStatement s=con.createStatement( );//建立Statement类对象2、系统主要类(1)Model包封装表虽然已经在数据库中建立了表,但要想方便地对表中数据进行读取等操作,需要建立Model表存放对应的类,即用户类、商品类、订单类、厂商类、库存类。(2)DAO包数据库操作类将数据库操作与表结构分开,有利于代码的重用性,使分层清晰,代码模块化。在Dao包中的类,专门用于对数据库的增、删、改、查操作,对于数据库连接、数据源加载等相同的语句,应单独成类,其他函数通过调用来完成这一过程,如此一来可以提高代码的重用率。以添加商品的操作为例,关键代码是executeUpdate(sql),sql为插入商品语句,该函数可用于执行插入商品操作。(3)View包界面显示类商品销售管理系统有多个用户和多个任务,就需要绘制不同的界面。采用awt组件进行布局,用java.util包引入日期与列表参数。针对不同的用户,通过建立登录界面、商品管理界面、库存管理界面、用户管理界面、订单管理界面以及厂商管理界面,客户下单与个人信息界面。以用户操作为例,界面绘制结果如下:参考文献:[1] 陶维成.基于UML的企业销售管理系统设计[J].廊坊师范学院学报(自然科学版).2012(12):67-69[2] 戴敏龙.基于ERP的销售管理系统研究[J].价值工程,2012(22):187-189.[3] 黄勇,赵伟.基于ERP的销售管理系统的开发与实施[J].河北农业大学学报,2008(6):187-189.[4] 王敏,张俊,赵坤灿.基于MFC的高校人事档案管理信息系统的设计与实现[J].昆明冶金高等专科学校学报,2009(3):31-36.
【摘 要】近年来,我国高速公路通车里程和汽车数量的日益增多,如何提高出入口车辆的通行效率和收费管理工作是面临的主要问题之一。本文介绍一种采用图像处理技术和通信技术的高速公路收费系统,以实现无人值守电子不停车收费,可有效提高通行效率和收费系统自动化程度及智能性。本文还给出了车辆图像信息的采集、处理方法以及实现不停车收费的软硬件设计方案。
【关键词】嵌入式;收费系统;自动识别
0 引言
目前,我国高速公路收费大多处于纯人工收费状态,需要大量人力,工作效率低下,运营成本较高;交费时需要停车,在交通高峰时期,收费站成为高速公路的“瓶颈”;近来,部分省市实施的高速公路区域联网收费在全国得到了公认,采用人工半自动收费和电子不停车收费(ETC)等,但存在“倒卡”和“换卡”等现象,给国家造成不小的损失。
针对我国高速公路收费的现状,本文提出了基于嵌入式技术和图像识别技术进行车辆识别的收费系统,自行采集动态视频和静态图像自动判别车型,识别车牌号码,并记录相关信息;自动判别并匹配车型与车牌号码,计算通行费,以实现无人值守和集中管理。系统设计和硬件选型
系统有控制部分和图像信息采集及处理两个部分组成,框图如图1所示。
图1 系统结构框图
1.1 控制部分
系统采用S3C2410型ARM9芯片,扩展相应的外围电路,完成对图像信号采集控制、信息显示、通信接口等工作。一个控制板可控制多个车道的图像采集和信息传输工作,各车道的DSP不参与采集过程,只用于图像处理,减轻了其工作压力,具有很高的实时性。
车辆进入入口处缓行车道时,由传感器感知到有车辆通过,ARM9主控板发出控制信号,三个位置的CCD传感器分别拍摄,采集车辆三视图像,用以确定车辆车型和车牌号码。传统的DSP与PC机采用PCI卡接口一对一进行数据交换,成本较高,在ARM9上运行linux操作系统后支持以太网协议,设计光口和电口电路,可直接组网与PC机相连,将车辆信息上传至服务器数据库,并送LED显示屏显示;ARM9控制板与各DSP处理器采用RS485协议进行通信。
图2 主控系统硬件结构图
出口处图像采集过程同上,采集后的信息,经ARM9上传至PC机后,在服务器数据库中检索并匹配,计算出相应的里程,并根据车型计算出通行费用,并送LED显示屏显示,付费可采用IC卡预交等方式。
为防止夜间车辆大灯对图像采集的干扰,需设置可供车辆图像采集缓行通道。硬件框图如图2所示。
1.2 图像采集部分
电荷藕合器件图像传感器CCD(Charge Coupled Device),它能把光线转变成电荷,通过模数转换器芯片转换成数字信号,在ARM9控制信号的作用下将一帧数据传输给DSP。
1.3 图像处理部分
图像识别芯片采用TI公司生产的TMS320C6201型DSP,该部分负责接收CCD采集的图像信息;由三位平面图像计算出车体的长宽高;进行车牌定位,并识别出车牌号码;在ARM命令CCD传感器拍摄图像后,再由ARM发出DSP读命令,然后通过RS485总线将车辆信息传送至主控部分。软件设计
系统软件设计主要包括主控程序设计与图像识别算法的实现。主控部分设计主要是嵌入式操作系统的移植与应用程序的编写;如何选择高效可靠的图像识别技术是系统可靠工作的关键,本系统采用纹理法进行车牌图像提取,利用改进的Sobel边缘检测算法提取号码特征信息,使用gabor变换的方法进行号码分类识别的方法读取出号码信息。
2.1 主控部分软件设计
2.1.1 操作系统
本文选用linux嵌入式操作系统,实现以太网驱动和对各应用任务的调度。移植工作需完成对TCP/IP协议栈的修改和以太网接口驱动程序的编写,以满足系统的要求。通过网络驱动程序,向系统注册检测到的网络设备和传送车辆信息数据。
2.1.2 应用程序模块
应用程序采用模块化结构,使用C语言编写。包括初始化模块、通信模块、人机界面模块。
(1)初始化模块:在开机或复位后初始化,包括I/O端口、寄存器、LCD参数、通信参数、实时时钟、EEPROM数据等的初始化。
(2)人机界面模块:LED屏实时显示经过车辆信息,可由键盘操作,显示历史车辆信息。
(3)通信模块:通信模块包括采用RS485协议与DSP的通信数据;采用以太网与PC进行信息交换。
2.2 图像识别方法
2.2.1 车型识别
车型识别主要根据焦距和投影图像大小的比例关系。使用颜色分割法分割出车辆三视图,根据与焦距之间的比例关系计算出车辆实际的长宽高,作为通行费计算的一个依据。
D=np/M(1)
式中:n为像素数;p为像素间距;M为倍率;D为车辆实际尺寸。
2.2.2 车牌识别
要进行车牌的提取和识别,必须了解车牌与背景或车体的区别特征。我国通行的车牌大体有四类:蓝底白字、黄底黑字、黑底白字和白底黑字或红字。在环境等因素影响下,从颜色特征提取变得比较困难。可从下面两个角度进行特征识别:(1)一般车牌格式为:省份?英文字符?5个英文字符或阿拉伯数字,而且数字和英文字符笔画上连通;(2)车牌牌底和号码颜色特征区别明显,边缘突出。及时准确的获取车牌信息是收费系统中的一个重要的部分,识别过程:图像信息预处理→车牌定位→倾斜校正→二值化→字符分割→字符识别。
本系统设计时将车牌识别过程:
1.字符切分:车牌定位完成图像预处理、车牌搜索和倾斜校正;
2.车牌字符切分与识别:车牌二值化,字符分割,字符特征提取和字符识别。结论
本文设计的基于嵌入式技术的高速公路收费系统,相对于现有的收费模式,实现了无人电子不停车收费模式,采用嵌入式和以太网技术,大大降低了成本;采用高速的DSP芯片,选择合理高效的软件识别算法,提高了实时性、准确性和成功率。该系统的研制可满足我国高速公路发展的要求,具有较高的兼容性。
【参考文献】
中央广播电视大学计算机与科学技术专业
毕
业
论
文
学生姓名:黄志刚
学 号:14360012501
专 业:计算机与科学技术
班 级:
指导教师:李慧
2016年04月
目录
目录
I V VII VIII 1 1 1 2 2 2 3 3 3 4 5 6 6 7 摘要
前言
文献综述
第1章 绪论
第1节 第2节 背景
研究的目的与意义
第2章 设计简介及设计方案
第1节 第2节 第3节 设计原则 运行架构 设计方案
第3章 相关技术介绍
第1节 第2节 第3节 MVC简介
Spring 的起源和背景 Hibernate 概述
第4章 需求分析
第1节 第2节 注册博友 普通用户
I 9 10 10 11 11 12 12 14 15 15 15 15 17 18 20 第5章 系统架构设计
第1节 第2节 系统架构说明: Hibernate层
5.2.1 设计持久化对象(PO)5.2.2 实现DAO 层 5.2.3 DAO组件的定义 5.2.4 实现DAO组件 5.2.5 部署DAO 层
第3节 第4节 实现Service 层 MVC 层实现
5.4.1 1.Model 部分 5.4.2 View 部分
5.4.3 3.Controller部分 5.4.4 采用Ajax加深用户体验
设计结果及对设计结果的分析
全文总结
致谢21
目录
目录
I V VII 摘要
前言
II
VIII 1 1 1 2 2 2 3 3 3 4 5 6 6 7 9 9 10 10 11 11 12 文献综述
第1章 绪论
第1节 第2节 背景
研究的目的与意义
第2章 设计简介及设计方案
第1节 第2节 第3节 设计原则 运行架构 设计方案
第3章 相关技术介绍
第1节 第2节 第3节 MVC简介
Spring 的起源和背景 Hibernate 概述
第4章 需求分析
第1节 第2节 注册博友 普通用户
第5章 系统架构设计
第1节 第2节 系统架构说明: Hibernate层
5.2.1 设计持久化对象(PO)5.2.2 实现DAO 层 5.2.3 DAO组件的定义 5.2.4 实现DAO组件
III 14 15 15 15 15 17 18 20 5.2.5 部署DAO 层
第3节 第4节 实现Service 层 MVC 层实现
5.4.1 1.Model 部分 5.4.2 View 部分
5.4.3 3.Controller部分 5.4.4 采用Ajax加深用户体验
设计结果及对设计结果的分析
全文总结
致谢21
IV
摘要
越来越多的网络用户希望能够在网络平台上更多地展现自己的个性,更方便地与他人互动交流,拥有一个自己独立的空间,随着Web2.0时代的到来,一个新的概念出现了——博客。
首先介绍了博客网站设计的意义和背景,主流博客网站的主要功能。重点介绍了基于J2EE架构的博客网站设计方案,实现的主要功能。
其次,重点讲述了博客网站的业务逻辑层和持久层的设计与开发过程中所涉及的技术及开源框架。系统如何以Spring 框架为核心,向下整合Hibernate进行持久层访问,向上整合Struts 按清晰的MVC 模式控制,怎样划分应用的层次。简述了页面的请求的分发及流程。
最后对BLOG网站开发中所碰到的一些问题,并针对这些问题提出一些解决方案,最后对系统性能作出一些简要评估,阐述了一些个人想法。
关键词: 博客,J2EE, Spring,Struts,Hibernate
Abstract More and more network users hope to unfold there characteristics in the network platform and interact with people more conveniently.From the begining of Web 2.0, a new concept of blog emerged.Firstly, we introduce the meaning and background of designing of blog site, and then introduce the main function of the blog site briefly.We also introduce the designing scheme of blog site which is based on the architecture of J2EE.The main function carried out in our blog project is presented.Secondly, we introduce the designing of logic and permanent layer of the blog site.The technic and structure refered in the process of developing are presented.We also depict how to be around with frame of Spring, how to work with Hibernate to visit permanent layer below, how to work with Struts to control the clear MVC model up and how to divide layers of application.We also give the brief introduce of distribution and flow of pages’request.Finally, we discuss some problems about the blog realization and show schemes of solving problems.Brief evaluation on the performance of system is given.We give a comment on problems occurring in our work.V
Keywords: blog, J2EE, Spring, Struts, Hibernate
VI
前言
本文介绍了基于轻量级J2EE开发博客网站。同时利用Spring、Struts、Hibernate、Ajax等框架整合开发。本文主要分为七章。
第一章主要介绍了进行博客网站的背景及意义。第二章对博客网站设计方案做了简要介绍。第三章介绍了博客网站的需求分析。
第四章详细介绍了系统的架构设计,并详细讲述了通过Spring 框架,向下整合Hibernate 进行持久层访问,利用DAO模式隔离业务逻辑层与具体持久层,向上整合Struts按清晰的MVC模式构建系统。
第五章简单讲述了系统设计时遇到的问题及解决方案,另外对系统的性能作了一个简要的评论及设计结果和设计结果分析。
第六章对全文所使用的方法、结果以及目的和意义做了全面的总结,展望java技术在Web上的一些应用。
本文的完成得到了戴祖旭博士的帮助和指导,在此向他表示衷心的感谢。
VII
文献综述
Hibernate相关文献介绍
文献错误!未找到引用源。围绕着ORM,讲述了对象映射配置,对象关系映射、集合映射、对象的操作和查询。及详细如何利用Hibernate 构建DAO层,怎样根据PO的关系。面向对象操作数据库,怎么配置数据库映射文件。Java基础文献概述
文献错误!未找到引用源。讲述了java基础知识,如控制流程、初始化和清理、接口和内部类等。并讲述如何利用对象提供服务,并通过接口隐藏具体实现。J2EE相关文献概述
文献错误!未找到引用源。论述了在J2EE平台中在各层经常遇到的问题,该文献详细讲解如何解决J2EE平台所遇到的问题。
文献错误!未找到引用源。将述了如何构建轻量级的J2EE企业应用程序,并讲解MVC在Web中应用,怎么将请求控制并转发,Struts标签。
文献错误!未找到引用源。详细讲述了Spring 的控制反转、AOP编程思想。及其怎么利用Spring整合Hibernate,利用Spring提供IOC容器管理DAO组件,利用事务管理SessionFactory。
文献错误!未找到引用源。以8 个小型J2EE项目讲述怎么利用Struts、Hibernate、Spring等框架构建J2EE Web应用。并且也详细讲述各个框架的在项目中应用。文献错误!未找到引用源。这本书是有3个具有15以上的开发经验的企业java架构师或首席架构师所著。本书讲述了J2EE的3层所涉及的核心模式。通过通用模式可以更快构建稳定的J2EE应用。
文献错误!未找到引用源。这本书详细讲述了架构设计的方法。架构设计应该包括那些方面。
怎么应用架构模式。Ajax技术文献概述
文献错误!未找到引用源。讲述了JavaScript、CSS、DOM、XML的在Ajax上一些应用。如何利用这四个技术实现html片段的替换。并结合一些实例讲述如何利用Ajax 实现友好用户体验。Eclipse文献概述
文献错误!未找到引用源。讲述了如何利用Eclipse开发java应用程序。该文献主要讲如何构建java开发环境,如何安装Eclipse插件。并利用Eclipse自动生成一些代码。Jsp文献概述
文献错误!未找到引用源。围绕着实例讲述Jsp的各种技术。比如Servlet,JavaBean 在Jsp中的应用。本文中的图片播放器和音频播放器是基于这书上实例改进的。
VIII
第1章 绪论
第1节 背景
商业网站设计的主要目的一般是通过网站的推广,实现更多网络用户的关注,从而吸引更多的企业用户投入更多的宣传经费到网站上。
长期的战略目标,商业网站不仅是公共产品信息和服务的推广,它还是将买家与卖家、厂商和合作伙伴紧密结合的平台,借助这些商业网站可以消除企业与客户之间时间与空间带来的障碍。
Blog博客网站致力于为广大博客提供优质博客页面服务的商业网站。每个博客都希望借助自己的博客页面宣传自己,而博客数量越多,网站的点击率越高就越能够吸引广大的企业客户选择该商业网站作为媒介,将自己的产品展现给客户。可以说,对这些博客网站而言:为博客提供良好的服务就意味着为网站带来更多的商业客户。因此,在具体设计实现该博客网站时,主要考虑了主流博客网站的几个主要功能。
1.博客的注册、登录验证功能
2.网络用户通过关键字搜索博文功能 3.最热门博客页面推荐浏览
4.文章详细内容及相关评论显示 5.博客页面访问量统计
6.博客个人文章管理维护功能
7.博客个人文章分类管理维护功能 8.博客个人友情链接维护功能
9.博客个人基本信息管理维护功能 10.博客图片上传及个人相册管理
11.网络用户写留言,博主查看留言。第2节 研究的目的与意义
Blog记载了日常发生的事情和自己的兴趣爱好,把自己的思想和知识和他人分享、交流,同时又通过“六度空间”结识了更多志趣相投的朋友;而越来越多专业知识的 Blog 的出现,让我们看到了 Blog 更多所蕴涵的巨大的信息价值:不同的 Blog 选择不同的内容,收集和整理成为很多人关注的专业 Blog ——目前越来越多的人获取信息的来源是一些固定的 Blog。随着博客人数的增加,Blog 作为一种新的生活方式、新的工作方式、新的学习方式已经被越来越多的人所接受,并且在改变传统的网络和社会结构:网络信息不再是虚假不可验证的,交流和沟通更有明确的选择和方向性,单一的思想和群体的智慧结合变的更加有效,个人出版变成人人都可以实现的梦想—— Blog 正在影响和改变着我们的生活。
第2章 设计简介及设计方案
在整个blog进行开发之前,要确定出整个项目的整体架构,包括系统的选型、运行环境的确定及系统结构设计。下面对这进行详细介绍。第1节 设计原则
在进行软件系统开发的最初环节,一般都需要进行系统的选型,即根据系统功能的实际需求,选择合适的开发工具及软件架构。
blog对系统的可靠性、稳定性有比较高的要求。本系统设计时,比较主流的B/S设计有基于JSP、ASP、PHP、CGI及J2EE等模式。相比较而言PHP的功能相对简单,不适合做大程序;而CGI效率相对较低,所以也不考虑。由于J2EE的开源的框架中提供了MVC模式实现框架Struts、对象关系模型中的Hibernate 的框架及拥有事务管理和依赖注入的Spring。利用现存框架可以更快开发系统。所以选择Java技术作为blog 的开发工具。第2节 运行架构
为了增加系统的吞吐量,提高并发处理客户请求数量,系统采用了IBM服务器作为主机。在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL错误!未找到引用源。
该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下:
1.服务器端操作系统:独立于操作系统的跨平台系统,客户端MicroSoft Windows 2000及以上;
2.数据库:MySQL 5.0.27版本; 3.Web服务器:Tomcat 5.5及以上版本,配合MVC设计模式及 Hibernate开发架构; 4.客户端运行环境:能运行IE 5以上或Netscape 5以上浏览器的操作系统,配合
使用Ajax技术;
5.客户端运行工具:目前的系统采用浏览器作为客户端,为了支持Ajax开发框架,应该选择使用IE 5以上版本浏览器。
本网站以NT为Web平台,JSP+Ajax+Servlet+JavaBean+Hibernate为网站实现技术,建立基于MySQL数据库系统的核心动态网页,实现博客网站前台及博客个人维护管理等功能模块。第3节 设计方案
为了在更短的时间内实现博客网站,我们采用J2EE架构。集成开发环境我采用对于插件即插即用的Eclipse,JSP运行环境我们采用Tomcat应用服务器,数据库管理系统我们采用的是MYSQL,博客网站主要实现注册用户可以在 服务器上开辟自己的空间,也可以发布消息,上传文件,回复消息,从服务器发送客户端的数据应用XML来封装.本系统采用的是经典的J2EE三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。并利用Spring、Hibernate、Spring等轻量级框架实现三层结构的设计。即采用的是贫血模式,业务逻辑对象正面封装了全部的业务逻辑方法,Web 层仅与业务逻辑组件交互即可,无须访问底层的DAO 对象。Spring 的声明式事务管理将负责业务逻辑对象方法的事务性。在贫血模式下,其分层非常清晰。Domain Object 并不具备领域对象的业务逻辑功能,仅仅是ORM 框架持久化所需的POJO,仅是数据载体。贫血模型容易理解,开发便捷,但严重背离了面向对象的设计思想,所有的Domain Object 并不是完整的Java 对象。
第3章 相关技术介绍
第1节 MVC简介
MVC 是Model、View、Controller 三个词的缩写,三个词分别代表应用的三个组成部分:模型、视图与控制器。三个部分以最少的稿合,协同工作,从而提高应用的可扩展性及可维护性。起初,MVC 模式是针对相同的数据需要不同显示的应用而设计的,其整体的效果如图1 所示:
图1 MVC结构
在经典的MVC 模式中,事件由控制器处理,控制器根据事件的类型改变模型或视图,反之亦然。具体地说,模型维护一个视图列表,这些视图为获得模型变化通知,通常采用观察者模式登记给模型。当模型发生改变时,模型向所有登记过的视图发送通知:接下来,视图从对应的模型中获得信息,然后更新自己。概括起来,MVC 有如下特点。.多个视图可以对应一个模型。按MVC 设计模式,一个模型对应多个视图,可以减少代码的复制及代码的维护量,一旦模型发生改变,也易于维护。
1.模型返回的数据与显示逻辑分离。模型数据可以应用任何的显示技术,例如使用JSP 页面、Velocity 模板或者直接产生Excel 文档等。
2.应用被分隔为三层,降低了各层之间的稿合,提供了应用的可扩展性。
3.控制层的概念也很有效,由于它把不同的模型和不同的视图组合在一起,完成不同的请求。因此,控制层可以说是包含了用户请求权限的概念。
4.MVC 更符合软件工程化管理的精神。不同的层各司其职,每一层的组件具有相同的特征,有利于通过工程化和工具化产生管理程序代码。第2节 Spring 的起源和背景
2002 年wrox 出版了《Expert one on one J2EE design and development》 一书。该书的作者是Rod Johnson。在书中,Johnson 对传统的J2EE 架构提出深层次的思考和质疑。并提出J2EE 的实用主义思想。2003 年,J2EE 领域出现一个新的框架: Spring,该框架同样出自Johnson 之手。事实上,Spring 框架是«Expert one on one J2EE design and development» 一书中思想的全面体现和完善,Spring 对实用主义J2EE 思想进一步改造和扩充,使其发展成更开放、清晰、全面及高效的开发框架。一经推出,就得到众多开发者的拥戴。传统J2EE 应用的开发效率低,应用服务器厂商对各种技术的支持并没有真正统一,导致J2EE 的应用并没有真正实现Write Once 及Run Anywhere 的承诺。Spring 作为开源的中间件,独立于各种应用服务器,甚至无须应用服务器的支持,也能提供应用服务器的功能,如声明式事务等。Spring 致力于J2EE 应用的各层的解决方案,而不是仅仅专注于某一层的方案。可以说Spring 是企业应用开发的“一站式”选择,并贯穿表现层、业务层及持久层。然而,Spring 并不想取代那些已有的框架,而与它们无缝地整合。总结起来,Spring 有如下优点: 1.低侵入式设计,代码污染极低。
2.独立于各种应用服务器,可以真正实现Write Once, Run Anywhere 的承诺。3.Spring 的DI 机制降低了业务对象替换的复杂性。
4.Spring 并不完全依赖于Spring,开发者可自由选用Spring 框架的部分或全部。
第3节 Hibernate 概述
Hibernate 是目前最流行的ORM 框架,其采用非常优雅的方式将SQL 操作完全包装成对象化的操作。其作者Gavin King 在持久层设计上极富经验,采用非常少的代码实现了整个框架,同时完全开放源代码,即使偶尔遇到无法理解的情况,也可以参照源代码来理解其在持久层上灵巧而智能的设计。目前Hibernate 在国内的开发人员相当多,Hibernate 的文档也非常丰富,这些都为学习Hiberante 铺平了道路,因而Hibernate 的学习相对简单一些。下面通过对比来了解Hibernate 和传统JDBC 操作数据库持久层之间的差异。
第4章 需求分析
Blog网站主要是实现注册用户登录、管理相关信息、博文及相关评论、查看留言、友情链接、及图片的上传和图像的播放而为上网用户提供按博文主题搜索,查看注册用户的博文及提出相关评论,并为注册用户写留言,游览注册用户的相册、注册等功能的系统。下面就以两种不同的用户来分析博客网站的需求。第1节 注册博友
首先必须在博客首页中登录填写用户名和密码,这样才能执行一些相关操作,不然就是普通用户只能查看一些信息,而不能发表博文。可以在管理页面上添加博文的分类,可以上传图片和游览自己的相册,在上传过程中可以将一张图片定义为自己的签名,在个人管理页面中注册用户还可以修改自己的个人信息。博文管理,友情链接管理及博文分类管理,用例图2。
图2 博客管理页面的用例图
在博客主界面中发表博文时可以选择博文类型,这样可以更好管理自己的博文。并查看和删除网友对自己的博文的一些评论、查看和删除网友留下的一些留言,提供与其他网友交流的空间。更好交流,在信息时代人们通过个人空间沟通也用来但不能在自己的博客主页面中提交评论和留言。这样在本系统中就可以为博友提供更多的个人色彩。在管理页面中添加和删除友情连接。这样博友可以在自己空间中快速定位自己的关心的网站。这样还可以让网友看到自己的一些信息。友情链接及网页访问量统计显示:在博客的个人页面中还提供了推荐给普通网络用户的相关友情链接,此外,对个人页面的访问量也在随时进行统计,并在个人页面中进行直观的显示。博客主页面的用例图如图3所示:
图3 博客主页面的用例图
第2节 普通用户
在博客注册页面注册成为博客的注册用户,才可以拥有自己独立的空间,进入某一博客页面查看相关文章信息时,可以随时对自己所感兴趣的文章发表评论,同时也可以查看到其他人针对该博文的评论。普通用户在阅读博文时可以在最后留下自己的一些评论。他也可以留下更多的信息。这样他可以写留言。这样他留下的信息就更快地被博友所看到。普通用户进入博友的用例图如图4所示:
图4上网博友在博客主页面的用例图
普通网友可以搜索自己关心的一些数据。并且在搜索结果中提供在结果范围内再次搜索。这样就可以将范围缩小。首页向注册用户提供登陆模块,注册用户在博客网站首页跟上网网友一样可以查看博客和博文推荐。上网网友可以注册成为博客用户,拥有自己独立的空
间。这一模块的用例图如图5所示:
图5 博客首页的用例图
第5章 系统架构设计
本系统采用严格的J2 EE 应用结构,主要有如下几个分层。
1.表现层:由JSP 页面组成。2.MVC 层:使用Struts框架。
3.业务逻辑层:主要由Spring loC 容器管理的业务逻辑组件组成。
4.DAO 层:由7 个DAO 组件组成,实现类必须继承Spring提供的HibernateDaoSupport。
5.Hibernate 持久层:由7 个PO 组成,并在Hibernate Session 管理下,完成数据库访问。
6.数据库服务层:使用MySQL 数据库存储持久化数据。系统的具体分层如图5 所示。
图6 系统结构图
在图6 黑色大方框内的MVC 控制层、Service 层及DAO 组件层的组件,都由Spring IOC 容器负责生成,并管理组件的实例(实例必须是单身模式的,本系统中的bean基本上是单身的)。
第1节 系统架构说明:
本系统不仅严格按MVC 模式设计,还按J2 EE 分层设计,将中间层严格分成业务逻辑层、DAO 层及数据持久层等。MVC 层的控制器绝对禁止持久层访问,甚至不参与业务逻辑的实现。表现层采用传统JSP 技术。
本系统采用的是典型的J2EE 三层结构,分为表现层、中间层(业务逻辑层)和数据服务
层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。Jsp广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。中间层采用的是流行的Spring+Hibernate,为了将控制层与业务逻辑层分离,又细分为以下几种。
Web 层,就是MVC 模式里面的C,负责逻辑层和表现层的交互。调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的MVC采用Struts框架。
Service 层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以DAO 层为基础,通过对DAO 组件的正面模式包装,完成系统所要求的业务逻辑。
DAO 层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。
PO,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,该系统采用Hibernate 作为ORM 框架。Spring 的作用贯穿了整个中间层,将Web 层、Service 层、DAO 层及PO 无缝整合,其数据服务层用来存放数据。
第2节 Hibernate层
通过使用Hibernate 持久层,可以避免使用传统的JDBC 操作数据库,对JDBC近一步包装,从而更好地使用面向对象的方式来操作数据库。保证了整个软件开发过程以面向对象的方式进行,即面向对象分析、设计及编程,透过Hibernte 对PO对象持久化操作,不管插入还是查询都是通过PO。5.2.1 设计持久化对象(PO)面向对象分析,是指根据系统需求提取应用中的对象,将这些对象抽象成类,再抽取出需要持久化保存的类,这些需要持久化保存的类就是持久化对象(PO)。该系统并没有预先设计数据库,而是完全从面向对象分析开始,设计了7 个持久化类。本系统一共设计了如下7 个PO。
1.Blog: 对应博客网友的一些基本信息,必如id、username、password、sex、picturename、name、address、uid、subject。还包括一些集合,博友的博文(Articles)、图片(Pictures)、留言(Messages),这样在系统中我们可以随时通过getXxx()访问博客的一些属性就不用编写sql语句来访问博友的些属性,2.Picture: 对应博友的图片,包含name、blog,filename,这样我们可以将图片 的路径名保存到数据库中,在根据路径名访问博友上传的图片,就不用用到数据库中的Blob类型,将图片数据格式转来转去,不过这样服务器直接存储客户的图片。
3.Messages: 对应网友留下的留言,属性有id、username、Blog、注册用户可以查看别人写的留言,但不能在自己的空间内留言。
4.FeedBack: 对应回复,包括id、article、username、content。他对于一篇博文,是网友阅读博文后对博文的评论。该评论无论是谁都可以看到。
5.Sort: 对应博文分类属性有Id、Blog、name、Articles,注册用户可以在自己的空间定义一些分类,这样可以更好管理自己的博文,一个分类对应一个Blog,一个分类可能有很多分类。
6.Article: 博客系统的核心 对应有 title,Id、blog、content、sort,一个博文属于一种分类,可以有很多回复,7.Links: 对应有情连接,包括id、url、name、blog博友通过添加有情连接可以在自己的空间中提供快速的自己关心的网站。
客观世界中的对象不是孤立存在的,以上7 个PO 也不是孤立存在的,它们之间存在复杂的关联关系。分析关联关系也是面向对象分析的必要步骤,这7 个PO 的关系如下。Blog除了FeedBack外,与另外5个都是1-N的关系,在blog类里对应有个集合。比如messages,是SetArticle 和FeedBack之间存在I-N 的关系,每篇博文可以被很多人评论。Article和sort 之间存在N-1 的关系,即每篇博文只能属于一种分类中,并且只属于一个博友,在Hibernate框架中它提供了以xml文件形式出现的映射文件,完成从PO到数据库表映射后,即完成面向对象的程序设计语言与关系数据库的映射。以面向对象的方式操作关系数据库。5.2.2 实现DAO 层
在Hibernate 持久层之上,可使用DAO 组件再次封装数据库操作。通过DAO 层,可以让业务逻辑层与具体持久层技术分离,一旦需要更换持久层技术时,业务逻辑层组件不需要任何改变。因此,使用DAO 组件,即意味着引入DAO 模式,使每个DAO 组件包含了数据库的访问逻辑:每个DAO 组件可对一个数据库表完成基本的CRUD 等操作。DAO 模式的实现至少需要如下三个部分。1.DAO 工厂类。2.DAO 接口。
3.DAO 接口的实现类。DAO 模式是一种更符合软件工程的开发方式,使用DAO 模式有如下理由。
1)DAO 模式抽象出数据访问方式,业务逻辑组件无须理会底层的数据库 访问,而只专注于业务逻辑的实现。
2)DAO 将数据访问集中在独立的一层,所有的数据访问都由DAO 对象完成,这层独立的DAO 分离了数据访问的实现与其他业务逻辑,使得系统更具可维护性。
3)DAO 还有助于提升系统的可移植性。独立的DAO 层使得系统能在不同的数据库之间轻易切换,底层的数据库实现对于业务逻辑组件是透明的。数据库移植时仅仅影响DAO 层,不同数据库的切换不会影响业务逻辑组件,因此提高了系统的可复用性。
对于不同的持久层技术,Spring 的DAO 提供一个DAO 模板,将通用的操作放在模板里完成,而对于特定的操作,则通过回调接口完成。Spring 为Hibernate 提供的DAO 支持类是: HibernateDaoSupport,5.2.3 DAO组件的定义
DAO 组件提供了各持久化对象的基本的CRUD 操作。而在DAO 接口里则对DAO组件包含的各种CRUD 方法提供了声明,但有一些IDE 工具也可以生成基本的CRUD方法。使用DAO 接口的原因是:避免业务逻辑组件与特定的DAO组件藕合。由于DAO 组件中的方法不是开始
就设计出来的,其中的很多方法可能会随着业务逻辑的需求而增加,但以下几个方法是通用 的。
• get: 根据主键加载持久化实例。
• saveor update: 保存或更新持久化实例。• remove: 删除持久化实例。
上面涉及了7个PO,这样我们必须设计7个对应的PODao 7个Dao必须继承BaseDao 这个BaseDao 有对接口的一些基本的CURD操作。7个Dao 如下。LinksDao,BlogDao、FeedBackDao、ArticleDao、MessageDao、SortDao、PictureDao。这7个Dao 分别封装对自己的持久化对象的一些操作。5.2.4 实现DAO组件
借助于Spring的DAO支持,可以很方便地实现DAO类。Spring 为Hibernate 的整合提供了很好的支持,Spring 的DAO 支持类是:HiberanteDaoSupport,该类只需要传入一个SessionFactory 引用,即可得到一个HibernateTemplate 实例,该实例功能非常强大,数据库的大部分操作也很容易实现。所有的DAO 类都继承HibernateDaoSupport,并实现相应的DAO 接口。而业务逻辑对象则面向接口编程,无须关心DAO 的实现细节。通过这种方式,可以让应用在不同的持久化技术之间切换。LinksDaoHiberante,BlogDaoHiberante、FeedBackDaoHiberante、ArticleDaoHiberante、MessageDaoHiberante、SortDaoHiberante、PictureDaoHiberante分别是LinksDao,BlogDao、FeedBackDao、ArticleDao、MessageDao、SortDao、PictureDao的实现类,并继承HibernateDaoSupport,并通过Spring IoC容器向7个Dao 实现类注入SessionFactroy,在7个Dao 的实现类就可以通过HibernateTemplate对PO持久化操作。并借助于Spring 提供的两个工具类: HibernateDaoSupport和HibernateTemplate,可以很容易地实现DAO 组件。这种简单的实现较之传统的JDBC 持久化访问,简直不可同日而语。比如我现在要得到所有Blog对象我只需一句 return getHibernateTemplate().find(“from Blog”);则返回一个Blog对象的列表。5.2.5 部署DAO 层
HibernateDaoSupport类只需要一个SessionFactory 属性,即可完成数据库访问。SessionFactroy创建Session,而数据库的CRUD操作都是有Session 完成,并将查询结果保存在一级缓存中,每次用户提交一次会话,可能需要Session完成一些数据库的操作而实际的数据库访问由模板类HibernateTemplate完成,该模板类提供了大量便捷的方法,简化了数据库的访问。5.2.5.1 DAO 组件运行的基础
应用的DAO 组件以Hibernate和Spring 为基础,由Spring 容器负责生成并管理DAO组件。Spring 容器负责为DAO 组件注入其运行所需要的基础SessionFactory。Spring 为整合Hibernate 提供了大量工具类,通过LocalSessionFactoryBean 类,可以将Hibernate 的SessionFactory 纳入其IoC 容器内。使用LocalSessionFactoryBean 配置
SessionFactory之前,必须为其提供对应的数据源,配置代码如下:
在将dataSource注入到上面简述的7个Dao中,就可以用HibernateTemplate提供的大量便捷的方法。进一步简化了持久层讨问,其模板的操作大大降低Hibernate 的重复操作;Spring 提供的DAO 支持简化了DAO 开发;SessionFactory 的依赖注入简化了Session 的控制等;这些都极大地提高J2EE应用的开发效率。声明式事务的管理分离了业务逻辑和事务逻辑,将应用从特定的事务逻辑中解料,使应用可以方便地在不同的事务策略之间切换。在所有的ORM 框架中,Sping 对Hibernate 的支持最好。Spring 提供很多IoC 特性的支持,方便地处理大部分典型的Hibernate 整合问题,如SessionFactory 的注入到7个PODao中、HibernateTemplate 的简化操作及DAO 支持等,然后在7个PODao实现类继承HibernateDaoSupport,这样的话,Dao实现类就可以通过HibernateTemplment以面向对象的方式操作数据库。另外,Spring 还提供了统一的异常体系及声明式事务管理等。一旦Hibernate 处于Spring 的管理下,Hibernate 所需要的基础资源,都由Spring 提供注入。Hibernate创建SessionFactory 必需的DataSource,执行持久化必需的Session 及持久层访问必需的事务控制等,这些原本必须通过代码控制的逻辑,都将由Spring 接管:DataSource, SessionFactory, TransactionManager 等,都将作为Spring 容器中的beano 将这些bean 放在配置文件中管理,可以提供很好的解耦。Spring 提供了DAO 支持,可以大大简化DAO 组件的开发。IOC 容器的使用,提供了DAO 组件与业务逻辑组件之间的松糯合。所有的DAO实现Bean 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心DAO 组件的实现。面向接口编程及DAO 模式的使用,提高了系统组件之间的解稿,降低了系统重构的成本。通过Spring 整合Hibernate,使持久层的访问更加容易,使用Spring 管理Hibernate持久层有如下优势。
1.有效的Session管理: Spring提供了有效、简单和安全的Hibernate Session处理。2.IoC 容器提高了DAO 组件与业务逻辑层之间的解糯。3.DAO 模式的使用,降低了系统重构的代价。
4.方便的事务管理: Hibernate 的事务管理处理会限制Hibernate 的表现,而 5.Spring的声明式事务管理力度是方法级。
6.通用的资源管理: Spring 的ApplicationContext 能管理SessionFactory,使得 配置值很容易被管理和修改,无须使用Hibernate 的配置文件。
7.异常包装:Spring 能够包装Hibernate 异常,把它们从checked exception 变为 runtimeException;开发者可选择在恰当的层处理数据中不可恢复的异常,从而避免烦琐的catch/throw 及异常声明。配置DAD 组件所有继承HibernateDaoSupport 的DAO 实现类,必须为其提供SessionFactory 的引用。由于所有DAO 组件都需要注入SessionFactory 引用,因此可以使用bean 继承简化DAO 组件的配置。本应用同样将所有的DAO 组件配置在单独的配置文件中daoContext.xml中例如:由于7个Dao 都必须利用IoC容器注入
SessionFactory。我们先配一个dao模板,然后7个Dao就继承该模板这样就可以简化daoContext.xml文件
parent=“daoTemplate”/> 其余6个PODAO的配置相似。从上面的配置文件可以看出Spring Ioc容器在Tomcat启动时就可以向Dao 注入SessionFactory 第3节 实现Service 层 Service 组件采用正面模式封装多个DAO 组件,DAO 对象与Service 组件之间的关Service 组件需要实现的业务方法主要取决于业务的需要,通常需要在业务组件中包含对应的方法。 业务层组件的实现业务层组件与具体的数据库访问技术分离,使所有的数据库访问依赖于DAO 组件,定义一个FacadeManagerImpl来包装7个Dao这样就可以把逻辑层和Dao分开,达到松散耦合的效果。事务管理将推迟到Service 组件而不是DAO 组件,因为只有对业务逻辑方法添加事务才有实际的意义,对于单个DAO 方法(基本的CRUD 方法)增加事务操作是没有太大实际意义的。关于事务属性的配置,本系统使用Spring 提供的TransactionProxyFactoryBean配置事务代理。这样不必为每个目标对象配置代理bean;避免了目标对象被直接调用。部暑业务层组件单独配置系统的业务逻辑层,可避免因配置文件过大引起配置文件难以阅读。将配置文件按层和模块分开配置,可以提高Spring 配置文件的可读性和可理解性。在applicationContext.xml 配置文件中配置数据源、事务管理器、业务逻辑组件和事务管理器等bean。配置文件如下:
PROPAGATION_REQUIRED
利用SpringFrameWork的TransactionProxyFactoryBean管理业务组件的事务,对应业务的方法名调用不同的事务管理,所以在业务逻辑组件的方法取名时一定要规范化。txProxyTemplate Bean是个业务组件事务管理的一个代理的父Bean,业务组件代理继承txProxyTemplate,并注入对应目标业务组件FacadeManagerImpl的在业务控制器根据请求
调用的是一个业务逻辑事务管理的代理,这个代理把请求分发给目标业务逻辑组件去处理,业务逻辑组件根据请求调用相应得Dao去执行。这样通过FacadeManagerImpl隔离业务逻辑控制器与Dao耦合。业务不需要知道是那个Dao执行的,也不需要Dao的 实现类。我们通过 Spring向FacadeManagerImpl注入7个Dao组件,业务逻辑组件是 面向DAO 接口编程,可让业务逻辑组件从DAO 组件的实现中分离。因此业务逻辑组件只关心业务逻辑的实现,无须关心数据访问逻辑的实现。第4节 MVC 层实现
MVC 架构的核心思想是:将程序分成相对独立,而又能协同工作的三个部分。通过使用MVC 架构,可以降低模块之间的耦合,提高应用的可扩展性。另外,MVC 的每个组件只关心组件内的逻辑,不应与其他组件的逻辑混合。
本文的MVC采用Struts框架。因为Struts 是最健壮,应用最广的MVC 框架。系统使用Struts 框架可以提高系统的可控制性,保证了系统的稳定性及可用性。5.4.1 1.Model 部分
模型独立于数据的显示,博客中所涉及的Model 都是ActionForm和JavaBean组成。模型返回的数据与显示逻辑分离。应用被分隔为三层,降低了各层之间的耦合,提高了应用的可扩展性。其中ActionForm用于封装用户请求参数,所有的用户请求参数由系统自动封装成ActionForm 对象:该对象被ActionServlet转发给Action;然后Action 根据ActionForm里的请求参数处理用户请求。比如本系统中的Registfrom封装了注册用户的所有信息,但页面触发了.do结尾 的 Http请求。这Struts的核心控制器ActionServlet将填充RegistForm 即调用RegistForm的setXxx。然后RegistAction就可以向业务逻辑组件提交添加RegistForm到博客。这样就完成用户的注册。而JavaBean 则封装了底层的业务逻辑,包括数据库访问等。比如本文中FacadeManagerImpl,通过业务外观向表现层封装数据的处理部分,而ActionForm 封装了请求参数以一个值对象(VO)的形似穿透J2EE的各层。
5.4.2 View 部分
Struts 的View 部分采用JSP 实现。整个应用由客户端请求驱动,当客户端请求被ActionServlet 拦截时,ActionServlet根据请求决定是否需要调用Model 处理用户请求,当用户请求处理完成后,其处理结果通过JSP 呈现给用户。通过Jsp将业务逻辑组件返回的值对象格式化,用户和系统通过View交互的。5.4.3 3.Controller部分
Struts 的Controller由系统核心控制器及业务逻辑控制器。
系统核心控制拦截特定形式的请求,再根据请求调用相应得业务逻辑控制器处理请求,在web.xml中如下定义:
com.blog.webapp.util.MyActionServlet
config
/WEB-INF/struts-config.xml
整合Struts 与Spring 只有一个要求,让Struts 将拦截到客户端的请求转发给Spring容器中的bean。也就是说Struts的业务逻辑控制器可以将从核心控制器转发过来的请求教给spring IOC容器管理业务逻辑组件处理。本系统使用DelegatingRequestProcessor 的整合策略,使用DelegatingRequestProcessor的整合策略可避免创建过多的本系统采用DelegatingActionProxy,提前将请求转发到Spring 容器内的bean。为了在应用启动时由Struts 负责创建Spring 容器,应在struts-config.xml 文件中增加如下配置:
className=“org.springframework.web.struts.ContextLoaderPlugIn”>
1.在struts-config且xm1文件中配置对应的Action。
2.在Spring 容器中配置实际的Action,在本文中需要与数据层交流Action必须
继承BaseAction,而BaseAction 具有一个facadeManger的属性,本文的请求不直接处理请求,而是交给业务逻辑组件处理。本文通过向Action注入相应得业务逻辑组件facadeManger,Acton 将请求交给它处理。我们在action-servlet.xml 里配置一个
这样的Bean 然后每个Action将继承actionTemplate,这样Action就可以把请求交给facadeManager 处理。而facadeManager是个业务逻辑事务处理的一个代理。这样通过Spring 将facadeManager注入到业务逻辑控制器中,Action 就可以将请求分发给Spring Ioc容器中目标业务逻辑处理。这样完成Spring 向上整合Struts。5.4.4 采用Ajax加深用户体验
为了加深用户体验,本系统在处理请求时还应用到Ajax 技术。页面提交一个非.do结尾的请求,及触发了一个文档模型(DOM)事件。Ajax处理请求如下: 1.DOM事件处理者收到事件发生的消息进行处理,即在JavaScript定义的一个函数处理。2.处理者开始创建一个XMLHttpRequest对象,并根据触发的事件对XMLHttpRequest 对象设置目标URL、http 方法(GET或POST),在本系统中URL是一个以.do结尾的请求。主要是请求交给业务逻辑组件处理,再注册服务器的回调函数。3.向服务器分派异步的Http请求。
4.异步的Http请求发出后,游览器不必等待服务器的响应,用户还可以与页面交互。5.Struts 的核心控制拦截http请求,根据请求分派Action去处理请求。
6.Action交给业务逻辑组件处理。Action 接受到业务逻辑组件处理后的结果(一般是VO或VO数组),再将返回的结果序列化成XML作为服务器的响应内容。核心控制器再将响应内容返回给游览器。
7.调用XMLHttpRequest注册的回调函数。
8.回调函数解析响应内容XML文档,在这里我们利用DOM将XML换成html格式数据流。利用DOM改变交互页面的html节点。达到用户的需求。
设计结果及对设计结果的分析
本系统是一个小组(3个人)合力设计的。我负责底层即Hibernate Dao层逻辑层,MVC层,PO 和DAO 的设计。故我们采用值对象(VO)作为我们的数据交流载体。我负责VO的处理,而胡爱梅负责数据的显示即利用Jsp格式化从我设计业务逻辑层返回的数据。陈成负责搜索引擎的设计,他主要用到我设计的PO和外观组件(Dao封装体)去查询实体。在设计的过程中沟通是非常重要的。为了更好地向胡爱梅同学提供更好的服务。在设计逻辑组件返回的数据时我利用VO或XML来封装。利用DOM将XML格式转化为html的一格节点或者将VO填充到Jsp的内置对象比如Session。在JavaScript中替换她在Jsp页面定义的Html 节点。她转发的请求参数统一利用ActionForm来封装。而Struts 的核心控制器会帮我们填充。只要Action中将ActionForm换成我在Hibernate层定义的持久化对象PO就行了。再把PO交给facadeManger处理。这样只要胡爱梅同学知道我设计的PO的结构并将PO填充的Session的那个属性,她就可以将PO显示在页面上。而我只要知道她需要完成那些功能,即知道请求格式(请求的URL,ActionForm)和需要返回何种数据就行了。我便可以设计Action应该如何处理业务逻辑,再考虑将数据格式化成何种XML结构。并举例如何解析XML数据,或者将PO(List
)填充到Session的属性告诉她。为了更容易操控数据库,及格式化查询结果。我采用Hibernate 的DAO模式,利用Hibernate 查询的结果本来就是一个对象或对象列表,这就更方便我数据系列化成xml文件了。
本系统基本上可以实现前面需求分析中所要求实现的功能。另外添加了mp3播放和像word软件一样的编辑器。
由于第一次利用Java开发程序,第一次开发web应用程序。第一次利用Spring、Hibernate、Struts、Ajax等技术或框架编写程序,第一次利用MyEclipse 编写java应用程序、第一次利用MySql作为数据库系统。种种第一次,使的我在设计本系统困难重重。下面详细讲述我在开发过程中所遇到的问题和我的解决方案。1.到处出现乱码。为次我必须统一我的编码方式。
我统一采用UTF-8作为我的编码方式。并且在ActionServlet将请求转发的时候先将request的编码统一设为UTF-8,这样还是不能将Actionform 的乱码解决。ActionForm的编码是ISO-8859-1 为此我可以采用String类提供的构造函数解决。比如ActionFom的String属性str,我通过new String(ActionForm.getStr().getByte(“ISO-8859-1”),”UTF-8”)可以将ActionForm转为UTF-8。开始装MySql 时就要设定 数据库建表时表所用到的编码。同样设为UTF-8,开始我有些Form是采用Struts的DynaActionForm,这样可以少写个ActionForm类。但DynaActionForm的编码不确定。最后我只能将DynaActionForm改为ActionForm的类。对于Struts 不能拦截的请求我们统一采用Actionform一样的方式。
利用Validator验证失败能返回到指定的页面上去。
input=“/registadmin.jsp ” validate=“true”>
Struts 失败验证后Struts 不会将请求交给registAction处理直接转到input定义下的/registadmin.jsp页面上。而事实并不能转发,而是转到一个空白页面,由于验证成功可以转发,所以,其他一切都没错,只能是Action 的配置有错。将input=“/registadmin.jsp ” 改为input=“input”,定义input为一个forward 这样可以解决问题。在input属性直接配置他jsp页面是从书上将的。从这可以得出只有实验才体验框架的工作原理。2.图片上传
图片上传需要解决两个问题,1图片以什么形式出现在MySql中?以Blob,还是图片的一个路径名。博主将 图片上传到服务器,将图片的路径名保存到
MySql数据库中。我采用Struts提供的FileForm 作为上传图片ActionForm的文件属性,在Action处理时通过FileForm.getfile()得到该文件2,怎么产生路径名?为了不使图片的名称一样我采用以时间和用户名两个参数随机产生一个字符串作为图片的路径名。激将上传图片统一保存到一个特定的文件夹内。最后在表单中必须有 enctype=“multipart/form-data”这样可以让Jsp知道表单含有大量数据要上传。3.博文字数 多时不能就博文提交。
必须把写博文的表单中method设为post而不是get,因为get只是在提交请求 时带些参数而已。
4.一个对象不能同时在两个Session中,由于我开始没有将查询作为一个事务处理。后来将曾经查询过的对象作一些修改。由于对象的修改是在一个事务管理中。查询和修改不在一个事务管理中,则修改时事务管理重新开启一个Session。将对象保存到数据库中,这时一个对象同时在两个Session中,JDBC是不支持的。要修改对象,以前需要查询操作,由于利用了Spring 的事务管理,这就必须将两次操作放到一个事务中。
5.在blog主页面的所有Jsp页面刷新后的mp3重新播放
由于在mp3播放的页面中是采用在页面中嵌入
由于本系统的jsp容器是Tomcat,系统设计也采用轻量级的Hibernate,而不是EJB所以在群集,负载均衡、安全性、事务、系统管理都不很理想。数据库的连接池也不能很大,因为tomcat 不便管理。在本系统的数据库中只采用了一级缓存Session 没有启动二级缓存SessionFactory,由于大量重复数据的查询,性能可能有所降低。对于页面的分页处理,一般有两种,一种是物理分页,利用Sql语句向数据库查询指定那个页面所需要的数据,对于种方式由于数据库的差异,数据库提供的offset也不同,对于明确数据库的项目来说,物理分页在性能上讲显然比逻辑分页要来的好。第二种是逻辑分页,通过sql语句查询所有数据,再利用for语句读取用户所需要的数据,查询数据全部提交给客户端,还是将当前页面的数据相应客户端,是不好选择,因为如果全部相应,则用户可能只关心一部分,浪费了大量带宽,将当前数据提交给客户端则客户可能还关心其他数据,便再次相应服务器,要求得到其他数据,数据都在服务器的缓存中,加重服务器的压力,我选择的是将数据全部相应客户端。
全文总结
本文从博客网站的所需要实现的功能模块开始分析,决定使用Java开发博客网站。并利用JDK,Tomcat,MyEclipse,MySQL等软件来搭建开发环境,我的主要任务利用Java技术的Spring、Hibernate、Struts等开源框架设计J2EE三层结构的中业务逻辑层和数据服务层,blog网站以Spring 框架为核心,向下整合Hibernate 进行持久层访问;向上整合Struts 按清晰的MVC 模式控制。这样可以更快开发松散耦合的blog 网站。
由于没接触过Java,还有一些软件还没用过,如MyEclipse,因此完成此次毕业并不容易。通过摸索、翻阅并购买了大量相关参考资料,让我java 技术有了一定的了解。比较圆满地完成了本次毕业设计的任务,达到了此次毕业设计的目的和要求。
通过这次毕业设计学会利用java构建Web 网站,在毕业设计中接触过不少开源框架。开源框架的强大让我觉得还有很多技术需要去学习,这也让我明白,要不断地学习新知识才会利于自己各方面的发展。还让我体会到在项目小组里没有比沟通更重要
致谢
在论文结束之际,首先要感谢我的指导老师戴祖旭教授,在我的论文设计以及实现过程中均给了我大量的帮助和指导,他严谨的敬业精神和治学态度给我留下了深刻的印象。从他身上,我学到了许多能使我受益终身的东西,再次对戴老师表示衷心的感谢。
感谢理学院领导以及老师给我们创造的良好的学习环境和诸多帮助。
摘要
本文根据家庭视频采集系统的要求,提出一种基于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
1 试卷分析系统设计的意义
试卷作为考察教学成果的重要手段之一, 如何客观、准确、快速统计考试结果并进行分析, 一直以来是教学工作中的一个难题。通过全员全卷的量化分析, 多个角度分析对提升教学质量, 改进教学方法和手段具有十分重要的意义。
试卷分析通过多种量化指标, 有针对性地指出试卷所存在的问题, 有效地提高教师出卷的质量。将所有的试卷数据输入计算机系统, 可以快速实现试卷分析, 并且得到的分析结果可信度高, 处理过程十分规范, 分析结果误差小, 该系统的实用性非常强, 具有一定的推广和应用价值。
2 目标实现
2.1 开发目标
该系统主要用于教师或者是相关的教育部门对试卷进行分析, 需要录入相关的考试信息和学生成绩, 并且能够对这些信息进行查询、录入、修改等操作, 为了确保系统数据的安全性, 用户在使用之前需要进行注册, 注册之后才能进行登录。分析完成之后, 生成分析报表, 并能够对这些报表进行打印。
2.2 应用目标
通过该系统的应用降低教师的工作量, 通过各项分析结果准确有效地评估学生成绩, 找到教学之中的不足之处进行相应的改进, 提高教学质量。
3 运行环境
服务器端: (1) Tomcat; (2) Windows服务器; (3) My SQL; (4) 技术实现:struts。
客户端:A.火狐浏览器, IE浏览器;B.Windows 7。
4 系统设计
4.1 设计思想
本系统采用传统的MVC开发模式, 即Jsp+Javabean+Servlet, 使用My SQL数据库。其中Jsp实现视图端, Javabean是模型端, Servlet是控制端。Servlet担当主要逻辑控制, 通过接受Jsp传来的用户请求, 调用以及初始化Java Bean, 再通过Jsp传到客户端, 本系统中Sql Bean担当主要的与数据库的连接与通信, Java Bean在本系统中主要担当配合Jsp以及Servlet来完成用户的请求, 而Jsp主要担当接受与响应客户端, 如图1所示。
4.2 管理员端实现过程
对学生、教师、课程信息进行增、删、改、查。对学生的选课信息进行添加、删除等操作
4.3 教师端实现过程
查看个人信息并修改登录密码, 查看学生信息, 其中包括对学生成绩进行查询与修改, 将教师的成绩录入功能与成绩修改功能合并。查看学生的排名情况, 包括学生的课程排名与专业排名。
4.4 学生端实现过程
查看、修改个人信息并修改登录密码。查询自己成绩以及成绩排名情况, 同时拥有通过学号查询其他人成绩的功能。
5 模块设计
根据需求分析的描述可将试卷分析系统划分为以下几个模块。
(1) 用户模块, 该模块主要的功能为:用户登录、用户信息注册、用户信息修改3个子功能。 (2) 试卷分析模块该模块的主要功能有试卷分析的添加、删除、修改、查看4个子功能。 (3) 学生成绩模块该模块的主要功能有学生成绩的添加、删除、修改、查看4个子功能。 (4) 试卷分析报表该模块的主要功能有试卷分析报表的生成等功能。
在试卷分析系统的中, 使用了My SQL数据库。因为My SQL小巧, 功能齐全且查询迅捷, 提高系统查询效率。数据库作为后台数据存储空间, 由7张表组成, 设计遵循数据库设计要求, 力求规范。各表的结构如表1—7所示。
6 系统实现
(1) 系统的登陆界面。当用户要使用本系统时, 为了保证系统的安全性, 则用户需通过登录界面登录到本系统, 才能使用本系统。
本系统的用户模块的用例图如图2所示。
(2) 试卷分析模块实现界面。当用户成功登陆系统后, 就会进入系统的主界面, 在该页面中会自动显示所有的试卷基本信息, 并提供了添加试卷分析, 查看试卷分析, 编辑试卷分析, 删除试卷分析4个功能。
此模块实现的用例图如图3所示。
(3) 学生成绩录入模块。
(4) 成绩模块。
7 结语
试卷分析系统的设计和开发, 取代了传统的手工分析试卷分析的过程。试卷分析软件大大减轻了任课教师的工作强度, 提高了教学水平和工作效率。
参考文献
[1]江志晃, 黄佳莉.刍议高校试卷分析系统的设计与实现[J].赤峰学院学报 (自然科学版) , 2015 (10) :19-21.
【关键词】高速公路;电子不停车收费系统;设计
在高速公路上运用电子不停车收费系统是解决道路拥堵的一种有效方式,很多发达国家都在运用这种手段来提高出行效率。我国的部分高速公路已开始运用电子不停车收费系统,取得了较好的实践效果。但在技术方面还存在一定不足,需要设计人员开展进一步的研究,确保系统能够更加适用于我国的高速公路实际运行情况,发挥最大效用。
1.电子不停车收费系统的概念及组成
1.1电子不停车收费系统的概念
电子不停车收费系统隶属于智能交通系统领域,凭借其快速、高效、智能的运行模式在国际社会得到广泛应用。具体来说电子不停车收费系统就是在车辆识别技术的辅助下实现收费站和车辆之间的数据通信,开展数据交换,利用网络来对收费数据进行处理,在车辆不停的状态下完成高速公路收费的智能系统。
1.2电子不停车收费系统的组成
电子不停车收费系统的组成主要包括四个部分:第一是CPU卡和电子标签,其中CPU卡作为一种全新的IC卡在电子付费方面发挥着重要作用,而电子标签的功用在于储存车辆信息、车主资料及车牌信息等,是电子射频的一种。第二个组成部分是收发器,收发器通过与电子标签间的微波高频通信来阻抗干扰,实现快速通信。第三部分是微处理器,其主要功用是进行通信处理,将OBU和CPU卡收集到的信息传至控制器,获取并处理车辆信息,对OBU和CPU卡中的信息进行修正。第四部分为车道控制器,该控制器需要对OBU和CPU卡中的数据进行分析,对车辆的通行权进行判定,明确OBU和CPU卡是否有效,在判定无效的情况下发出警示,同时还能完成对违章现象的取证工作。
2.建立电子不停车收费系统的意义
在高速公路上建立电子不停车收费系统意义重大。首先,这是对科学发展观的有力践行,由于近年来车辆数量持续性增长,给高速路的正常通行带来了很大压力,高速公路拥堵成为备受关注的社会问题。建立不停车收费系统能够使司机在不停车的状态下完成交费,交费消耗的时间几乎可以忽略,使高速路收费站的容量得以扩展,工作效率得以提升。其次,不停车收费系统的运用是科技兴交的重要体现方式之一。车辆不必在通行中频繁刹车、起步,使车辆磨损得到有效控制,节省油耗,同时减少对大气环境的污染,实现节能环保。第三,此类智能系统的投用能够解决人工收费的诸多弊病,如票款丢失、效率低下等,使高速公路保持顺畅,真正实现高速通行。通过为人们提供安全快速的交通环境,使交通行业的全新形象完美地展现出来。
3.高速公路电子不停车收费系统的设计
3.1系统架构设计
C/S架构是一种较为通用的系统架构,其组成部分包括收费站、分中心和省中心。这三个部分共同构成一个局域网,具体的工作方式为:高速公路车道作为信息采集前端,为收费站获取车辆信息,将信息传送到收费站的数据库服务器上,再由收费站将处理后的数据传送到分中心和省中心。系统硬件结构是系统架构设计的重点,而硬件结构的主要部分就是ETC车道。ETC车道包括的硬件设备较多,如车道工控机、判别线圈、触发线圈、抓拍摄像机、报警器、数据叠加器等等。设备之间是相互连接的,车道计算机起着主要的控制作用,而整体系统的运行则是由ETC车道软件来控制的。
3.2系统功能模块划分
电子不停车收费系统的组成模块包括:车道前端、车道监视、数据通信以及ETC管理四个部分。其中车道前端的主要任务是处理车道交易、检测外部设备并对设备进行有效控制以及拍下图像进行保存;车道监视的功用在于查看车辆、设备的变化情况,并对收费过程进行监督;数据通信需要将车道前端收集到的数据下载下来,并将收费数据上传到中心;而ETC管理的主要工作就是完成相关数据的统计与核查,需要处理的内容包括参数的更新、交通流量的统计、突发情况的统计、收费金额的审查等等。四个模块缺一不可,只有四者协调工作才能确保电子不停车收费系统的正常运行。
3.3系统模块设计
系统模块设计是系统设计当中的重要环节,需要处理好以下几个方面的设计工作:第一是入口OBU处理,首先要对OBU的有效性进行判断,确定其能够正常运行的情况下再对OPU卡的有效性进行判定,用OPU卡来对车道号、收费站编号等进行记录,进而写入入口信息,形成入口过车明细。第二是出口OBU处理,同样需要对OBU的有效性进行判断,确定有效后读出CPU卡中的基本信息,进行费率计算,从车辆持有人的电子钱包当中扣除费用,回写出口信息,最终形成出口收费明细。第三是对车道异常进行处理,比如无电子标签的车辆处理流程为车辆进入→无电子标签报警→引导车辆走MTC车道→处理下一车辆。无效电子标签、无CPU卡、入口信息无效等车道异常情况的处理流程都与之相同,只是声光报警系统显示的报警内容存在差别。第四是ETC管理,ETC管理需要做的工作是进行数据浏览、查询、统计等,具体流程可以表示为管理开始→选择功能项→设置查询条件→生成SQL语句→显示查询结果→进行结果打印。
3.4数据库设计
数据库设计包括概念设计和库表设计两个部分。在数据库的概念设计当中涉及的内容包括:OBU(即电子标签)、IC卡、车辆实体、员工实体、班次及机构实体等等。以OBU为例,其包括的实体属性包括车型、编号、车牌号、车牌颜色、启用及失效时间、OBU状态等等。高速公路的员工实体属性包括操作员的姓名、工号、密码、所属路段及收费站等。数据库的库表设计较为复杂,需要用到的库表种类繁多,如OBU字典表、机构编码表、车辆信息表、IC卡字典表、收费标准字典表等等,不一而足。每种库表都有各自的功效,如OBU字典表是用来保存车辆的属性,以车辆信息为依据来进行车型识别。通过数据库的库表设计能够对高速公路路段的各项信息进行有效记录,使不停车收费系统更加完善。
3.5界面设计
建立清晰的电子不停车收费系统界面能够减少信息检索实践,提高工作效率。在ETC车道入口的界面中,需要包含交易信息区、车道运行信息区、外部设备状态显示区及摄像显示区等等。监视界面的设计需要包含的内容有车道外部设备的运行情况、车辆交易实况、摄像机图像等。收费站的ETC管理系统界面需要展示系统登录、数据及报表管理、提供退出等部分。除了上述几个环节的界面设计外,通行费统计、车流量统计、黑名单查询等系统组成部分的界面都需要有一个完美的设计。要求各区域的划分要十分明确,结构安排也要尽量合理,力求在一个界面上展示足够多的信息。
4.结束语
电子不停车收费系统在提升高速公路通行效率、实现节能环保、展现交通形象等方面起着积极作用,道路交通部门应该积极将这种智能化的系统引入到高速收费工作当中。系统设计者则需不断完善设计工作,使系统能够顺畅高效地运行,助益于高速公路事业的发展。
【参考文献】
[1]李佩清.高速公路收费站收费内业资料管理的几点思考[J].中小企业管理与科技(下旬刊),2012(12).
[2]廉飞宇,范伊红,张元.ETC电子不停车收费的技术研究[J].计算机工程与应用,2010(05).
[3]张爱春.高速公路电子不停车收费系统(ETC)及其应用[J].科技信息,2011(20).
【基于Java的高速公路收费管理系统的设计与实现】推荐阅读:
基于基础地理信息数据库的制图设计与实现11-11
浅谈基于.NET的高校教材管理系统的分析与设计论文09-23
浅谈高速公路收费站管理创新06-25
基于hadoop分析实现05-25