主页(http://www.pttcn.net):嵌入式DVR软件中用结构化语言实现面向对象的设计思想 嵌入式DVR是一种高度集成、复杂的嵌入式设备,其软件需要保证良好的可靠性、复用性、扩展性及高效性。 传统的结构化设计方法,在其软件设计中就有些“力不从心”,因为结构化的软件要求软件设计一开始就假定软件需求是很明确的,系统处理数据的模式和方法也是明确的。然而DVR的用户是面向不同领域的,而每个客户的要求都有所不同,如有的客户可能需要用RS485总线来控制温度采集器,有的则可能需要来控制云台,这在结构化设计方面就需要用不同的数据结构和方法来描述。因此,每当针对不同客户就需要专门定制不同的软件版本,这无疑增加了软件的维护和测试成本,这是DVR生产厂商所不愿意看到的。并且,面向对象的设计思想需要采用面向对象的设计语言,无疑是对嵌入式设备一个巨大的考验。当然,现在不少嵌入式开发工具,已经支持C++、JAVA等面向对象的设计语言。但是这些面向对象的语言需要很大的C++设计库,这会增加DVR对存储设备容量的要求。而且面向对象的设计语言在执行的时候会添加一些额外的代码,如“析构”、“构造”函数,会导致执行效率比结构化的设计语言要低。因此一些编译器对面向对象的设计语言的支持远没有对结构化的设计语言高。如LINUX下的GCC编译器附带的调试工具,在调试C++程序中有时就无法打印堆栈和函数的调用关系。 新型软件设计方法 这种设计方法的实质是:用面向对象的设计思想去分析嵌入式DVR的需求;用面向对象的设计模式去设计DVR软件构架;用结构化的语言去实现DVR系统功能。这样一来,就可以发挥面向对象设计思想在需求分析和建模方面的方便快捷直观的优点,同时又能保证嵌入式软件在执行效率和存储方面的要求。 当然,我们必须摒弃一些面向对象设计思想中需要依赖面向对象设计语言的一些特性,如运行中的多态,类型识别等。这些行为也能够在结构化语言中实现,只是有些特性对系统设计来说就有点无关轻重了。如果把所有面向对象的特性都拿来用,这就会导致设计走向另一个极端:在嵌入式开发上使用面向对象的语言来设计系统。特别值得指出的是,面向对象语言中的内存分配,如果在嵌入式软件上设计使用,会导致频繁的动态分配不定大小的内存,会引起系统堆栈破碎的风险。 面向对象软件 设计人员采用比较实用快捷面向对象的MVC结构,即模型-视图-控制器结构,把整个系统分成三个部分:一部分是底层的软件部分,我们在DVR软件称为“微内核”;一部分是人机交互部分,即界面部分;另一部分则是两者之间的接口,我们称之为适配器。在软件架构上也分为三个大的部分(或者说三个软件包):界面、“微内核”、界面和“微内核”之间的接口。 这三个部分在迭代中最先完成的是“微内核”部分。而“微内核”设计中最关键的就是录像部分,这需要考虑到各种不同的录像种类和各种录像条件,而做好录像部分的用例分析就可以设计出微内核的基本架构,也就是整个软件的“灵魂”。 完成第一次迭代设计后,DVR软件的其它需求的开发就是一个“添枝加叶”的过程。根据面向对象设计“高内聚、低耦合”的思想原则,每次迭代的过程我们都采用模块化的设计,。在添加每一个模块时,统一各个模块的接口,采用“模块名_domsg”做为对外接口。这样一来,就能很好地屏蔽掉各个模块的内部处理机制,减少软件开发的耦合程度。如“微内核”中的录像部分可能需要读出硬盘模块提供的分配目录信息。,就可以通过“hdisk_domsg”来获取。 各个模块开发 struct Module_Obj 在模块开发中,也可以采用面向对象的设计模式。设计人员在采用软件设计的过程就采用了很多“四人帮”(即“GOF”,四个国外开发者,提出面向对象软件开发中的常用设计模式)的设计模式。如在系统启动后就采用创建式的单例模式分配系统内存,保证系统各个模块在系统中唯一。又如报警模块中采用了observer(观察者)模式,其它模块如果要获取报警信息,可先向该模块注册需要的报警信息,当该报警模块发现有改变报警端子有报警的时候,就会把报警信息逐个通知各个已经注册的模块。这些模式的采用能够很好地提高代码的健壮性。 界面 |