一种电能表的业务模型研究
2024-11-25刘晓辉赵广东
摘要:在电能表软件开发中,在开发业务遇到跟其他业务有功能交集时,往往通过调用其他业务提供的函数接口实现,久而久之,业务功能会形成一张网,难于拆解,难于维护,造成新人上手慢、培养时间长、项目开发进度不可控等问题。为了解决上述问题,需要搭建一个业务模型,在业务功能开发时,使各个业务功能模块化。每个模块采用相同的固定式接口模型,彼此之间相互独立,没有函数直调,模块间的信息往来通过系统框架提供的接口实现。通过这种业务模型,成功实现模块间的耦合分离,固定业务开发模式,降低了开发难度。
关键词:业务模型;时序图;消息处理;业务注册
中图分类号:TP311.1文献标识码:A
在电能表软件系统中,业务模块包含通信、测量、控制、事件、上报等内容。项目成员从事开发不同的业务模块,编写出来的代码经常是没有固定套路,走读代码困难,业务模块间耦合严重,增加了代码后期维护难度。为了解决这种状况,研究一种新的业务模型,让业务功能开发出的代码具备低耦合、高效能、易维护,显得尤为重要。
1业务模型原理
该种业务模型采用业务注册、消息驱动的机制,实现业务代码的运行。总体上分5个接口函数,分别是初始化函数、读数据函数、写数据函数、消息处理函数及显示处理函数,如图1所示:
每个不同的业务功能均采用该业务模型,多个业务模块之间都只跟中间层进行交互,避免业务模块相互间的耦合调用。业务模型采用C++语言实现,利用其封装继承特性,实现业务模型的固定化开发套路,大大提高软件开发效率,易用易维护。
2业务模型的设计
2.1对象注册
在业务对象定义时,利用业务模块的构造函数完成业务模块自身注册,系统将获取该注册业务对象,为后期的数据管理及消息触发提供支持。其数据结构如图2所示:
CModule类为业务基类,其提供业务模块的5个接口函数,这5个接口函数用于中间层系统调用。
DATA_REG为业务数据结构体,其中包含数据名、数据大小、记录型数据深度、数据类型、eeprom地址等。
CServiceModule为业务类,负责5个接口和数据的具体实现。
2.2业务初始化
OnInitData函数负责业务模块eeprom数据或flash数据的上电或掉电读取工作,用来还原ram变量中的值。例如电表中正向有功电能,反向有功电能这些值在电表掉电后上电都是要从eeprom中恢复的,这个工作就在该函数内实现。
2.3业务读数据
OnReadData函数负责本模块定义的数据对外的读出操作,将ram、eeprom或flash中的数据拷贝到外部缓冲区,供其他业务模块访问本模块数据时使用,这种使用方式是间接性通过框架进行读取,不是直接的函数调用。
2.4业务写数据
OnWriteData函数负责本模块定义的数据的写入操作,其他业务模块通过中间层系统提供的写接口函数间接回调该函数,将ram、eeprom或flash中的数据进行更新替换,访问方式跟读数据类似。
2.5业务消息处理
OnTriggerForApp函数负责本模块响应消息的处理,消息包含定时消息(毫秒消息、秒消息、分钟消息等)、硬件驱动触发消息及模块间协作消息等,如图3所示:
(1)COtherModule为另外一个业务模块类名,跟CServeModule类似。
(2)DispatchMessage为中间层系统提供的消息派送处理接口函数,负责将消息传递到其他业务模块的消息处理函数内。
2.6显示
OnShow函数负责本模块显示功能处理。在该函数内可以出现显示相关操作,如调用底层显示接口完成对应显示功能。
3业务模型实现
3.1业务注册
在业务模块构造函数内,调用系统框架提供的注册函数RegistModule,将业务模块对象指针this及数据信息传给系统框架,为系统框架后期的业务模块调度使用。系统提供的注册函数RegistModule定义如下:u8RegistModule(CMODULE*pObj,u8nAppID),其中pObj为业务模块对象指针,nAppID为业务模块id,用于区分各个业务模块。具体流程如图4所示:
3.2初始化
业务模块注册完毕后,系统运行时会调用业务模块注册的初始化函数,完成业务模块的初始化动作,具体实现流程如图5所示:
3.3读数据
业务模块相互之间通常需要获取数据,如通信业务模块在收到主站发送的抄读数据业务帧时,需要到其他业务模块将其数据抄读回来,由协议层组织成帧报文返还给主站。框架提供ReadAppData接口实现该功能,协议路由层调用该接口,该接口内部通过业务模块对象指针访问该业务模块的OnReadData函数,从而实现了数据的访问。实现流程如图6所示:
3.4写数据
写数据的实现跟读数据很相似,用途是供其他业务模块设置本模块数据时调用。当其他业务模块需要设置非本模块数据时,调用系统提供的WriteAppData接口函数,该接口函数内通过业务模块指针调用其OnWriteData回调函数。具体流程如图7所示:
3.5消息处理
业务模块业务功能的执行靠消息驱动,系统提供DispatchMessage接口函数负责消息的触发。当一个业务模块需要另外一个业务模块帮助完成一个动作时,可以定义个消息id,通过DispatchMessage接口函数将消息传递到对应的业务模块消息处理函数OnTriggerForApp内,函数OnTriggerForApp负责响应该消息,并执行对应的代码。实现流程如图8所示:
3.6显示
每个业务模块可能都有显示的需求,那么显示相关的实现代码就在OnShow函数内实现。依照业务模块在系统内注册的顺序,系统在主循环中每秒调用每个业务模块显示处理函数OnShow一次,保持正常刷新。实现流程如图9所示:
结语
对于功能越来越复杂的电能表,业务功能的独立性显得越来越重要,固定式的业务模型开发模式大大地降低了新员工入门门槛,提高了代码的可维护性。经过在电能表中的验证,该业务模型真正地实现了业务模块的独立,业务模块间业务往来依靠消息驱动,不再直接调用其他业务模块的函数接口,避免了业务蜘蛛网的形成。人员之间的影响大大降低,各自在各自的业务模块内实现业务功能,模块业务接口完全一致,适合集中培训,代码维护更容易。
参考文献:
[1]李无言.一步步写嵌入式操作系统:ARM编程的方法与实践[M].北京:电子工业出版社,2011.
[2]彭为,黄科,雷道仲.单片机典型系统设计实例精讲[M].北京:电子工业出版社,2006.
[3]徐爱钧.单片机高级语言C51应用程序设计[M].北京:电子工业出版社,2001.
[4]RobertL.Kruse,AlexanderJ.Ryba.C++数据结构与程序设计[M].钱丽萍,译.北京:清华大学出版社,2004.
[5]LubomirF.Bic,AlanC.Shaw.操作系统原理[M].梁洪亮,译.北京:清华大学出版社,2005.
作者简介:刘晓辉(1980—),男,汉族,河南许昌人,本科,中级工程师,主要研究方向:电能表软件设计;赵广东(1985—),男,汉族,河南禹州人,本科,中级经济师,研究方向:项目管理费用管理。