抽象的设备管理框架

最近在弄一个公司的设备管理框架,发现可以把设备抽象出来,对其他可能的设备也可能用这一套框架。出于保密原则,删除了公司业务相关的信息,就列出来如下。

DevTool模块

1 程序描述

DevManager简称DM,ViewManager简称VM。程序启动后,DevManager内注册对Controller的事件处理回调eventCallbackForDM,以便Dev事件到来时回调;ViewManager内注册对Controller的事件处理回调eventCallbackForVM,以便UI事件到来时回调。

eventCallbackForDM内调用dispatchRequestFromCfg解析是否有匹配的事件对应的需求需要处理,如果有而且需要界面,则调用getDataFromDMtoVMForView从DevManager中获取对应界面需要的相应数据,并调用ViewManager的回调requestCallback处理对应的UI请求,最终弹出UI。UI处理完之后,调用eventCallbackForVM,通知Controller对应UI的完成事件,并将UI的返回数据保存在Controller内,然后Controller内调用getDataFromVMtoDMForDev组织数据,调用DevManager的requestCallback请求,最终调用DevApi更新Dev内数据。如果需要提示操作结果,还需要经历一次DM-Controller->VM->Controller的操作。

上述描述是针对Dev事件处理的,也有来源于用户操作的处理。如果是类似修改名称的操作,处理顺序为VM->Controller->DM->Controller->VM-> Controller。

1) VM先启动主页面,响应用户按钮请求,修改名称是在VM内弹框;

2) 填完Dev名称,合法验证通过后,Controller获取数据形成Dev的Request;

3) DM内调用封装好的DevApi实现修改名称,成功之后,返回给Controller;

4) Controller发送UI的Request,说明修改名称成功;

5) VM弹出修改成功提示,用户点击成功;

6) VM通知Controller确认成功。

在5)用户点击成功之前,如果此时用户断开Dev,而且用户需求中要求断开Dev之后关闭相关的对话框,将从DM->Controller->VM完成一次关闭提示框的操作。

在DM和VM之间加一层Controller的好处是所有需要配置定制的部分全部在此部分完成,其他实现可以以库的形式提供。

抽象一层Controller,还有一个好处,是不用在VM内缓存任何数据。比如想实现一个下拉框选择Dev,仅仅有连接/断开事件时传Dev指针到VM内是不够的,需要VM自己维护已有的Dev列表。

UML静态图如下:

2 功能

DevManager、ViewManager 分别实现设备管理、视图管理。主程序内实现控制器的功能,连接各个模块,实现消息的传递、客户定制需求的处理。

2.1 设备管理

连接Dev则新建Dev对象存入devMap,所有针对Dev的数据操作都由DevManager进行。除了与Dev通信,还要负责回复Controller的请求数据、调用Controller的回调,通知Controller事件来了。

2.2 视图管理

响应Conroller的请求弹出UI,当UI操作结束时,调用Controller的回调返回UI操作的结果。

2.3 控制器

Conroller提供回调函数给DevManager、ViewManager,以响应事件,并实现对配置的解析,针对当时的事件,生成相应的请求,提交给DevManager和ViewManager。

2.4 性能

2.5 输入项

2.6 输出项

无。

2.7 算法

无。

2.8 流程逻辑

无。

2.9 接口

数据传输统一采用XML格式,如果某些元素是二进制流数据,且不是无符号整型,也先转成十六进制字符串,然后再传输。

2.9.1 ViewType定义格式

支持的视图类型:View、ListView、TabView、ImageView、Button、ComboBox、TextView、TableView、TrayView、BubbleView、AnimateView。

支持的视图内容布局类型:contentLayout(left/right/center/top/down) marginWidth/marginHeight

支持的布局类型:linearLayout(vertical/horizontal)

支持的宽高类型:height/width(30%/30)  %方式定义与父窗口的相对位置,纯数字定义与MFC的rc文件中定义单位相同

例如定义一个竖型的管理工具mainView

<?xml version="1.0" encoding="utf-8"?>
<view>
	<viewType>mainView</viewType>
	<width>500</width>
	<height>400</height>
	<IsCenterToDeskTop>true<isCenterToDeskTop>
	<linearLayout orientation = "vertical">
		<linearName>outline</linearName>
		<marginWidth>2%</marginWidth>
		<width>96%</width>
		<height>96%</height>

		<!--headline-->
		<linearLayout orientation = "horizontal">
			<linearName>headline</linearName>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>5%</height>
			<backgroundColor>#0001</backgroundColor>
			<imageView>
				<imageName>logoIco</imageName>
				<imageUrl>$(res)/logoIco.png</imageUrl>
				<contentLayout>center</contentLayout>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
			</imageView>
			<textView>
				<marginWidth>2%</marginWidth>
				<width>70%</width>
				<height>96%</height>
				<textValue>$(CustomerName)$(DevName)$(ToolName)</textValue>
			</textView>
			<button>
				<id>btn_min</id>
				<action>onMin</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_min.png</imageUrl>
			</button>
			<button>
				<id>btn_max</id>
				<action>onMax</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_max.png</imageUrl>
				<isEnable>false</isEnable>
			</button>
			<button>
				<id>btn_close</id>
				<action>onClose</action>
				<marginWidth>2%</marginWidth>
				<width>5%</width>
				<height>96%</height>
				<imageUrl>$(res)/btn_close.png</imageUrl>
			</button>
		</linearLayout>

		<!--logo long-->
		<imageView>
			<imageName>logoLong</imageName>
			<imageUrl>$(res)/logoLong.png</imageUrl>
			<contentLayout>center</contentLayout>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>30%</height>
		</imageView>
		<textView>
			<marginWidth>2%</marginWidth>
			<width>70%</width>
			<height>50%</height>
			<textValue>$(CustomerName)$(DevName)$(ToolName)</textValue>
		</textView>
		<linearLayout orientation = "horizontal">
			<linearName>headline</linearName>
			<marginWidth>2%</marginWidth>
			<width>96%</width>
			<height>56%</height>

			<!--logo-->
			<listView>
				<id>listView_mainView</id>
			</listView>

			<!--btnlist-->
			<linearLayout orientation = "vertical">
				<linearName>btnList</linearName>
				<marginWidth>2%</marginWidth>
				<width>36%</width>
				<height>56%</height>
				<button>
					<id>btn_change_name</id>
					<action>onChangeName</action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
				<button>
					<id>btn_view_devinfo</id>
					<action>onView devinfo </action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
				<button>
					<id>btn_init</id>
					<action>onInit</action>
					<marginWidth>2%</marginWidth>
					<width>96%</width>
					<height>10%</height>
					<isEnable>false</isEnable>
				</button>
			</linearLayout>
		</linearLayout>
	</linearLayout>
</view>

2.9.2 DM->Controller交互事件数据格式

<?xml version='1.0' encoding='utf-8'?>
<event>
	<eventType>connect</eventType>
	<devIndex>3</devIndex>
</event>

eventType可选择connect/disconnect/format/datachange

在Controller的eventCallbackForDM中调用。

然后Controller调用getDatatFromDMtoVMForView,组织下一小节中描述的Controller->VM交互请求数据。

mapToUIId标签实现从数据到UI填充的映射。

2.9.3 Controller->VM交互请求数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>createUI</requestType>
	<view>
		<viewType>mainView</viewType>
		<viewId>view_1</viewId>
		<viewParentId>desktop</viewParentId>
		<devList>
			<!—此处的id与viewType定义中的控件对应的id相同,表示填充到对应的id里-->
			<id>devList</id>
			<mapToUIId>listView_mainView</mapToUIId>
			<selectedId>dev_1</selectedId>
			<dev>
				<id>dev_1</id>
				<name>DevStd</name>
				<sn>DS20150415</sn>
				<imageUrl>$(res)/dev.png</imageUrl>
				<otherParamList>
				<param1>
				  <id>param_1</id>
				  <imageUrl>$(res)/param1.png</imageUrl>
				  </param1>
				<param2>
				  <id>param_2</id>
				  <imageUrl>$(res)/param2.png</imageUrl>
				  </param2>
				</otherParamList >
			</dev>
		</devList>
		<button>
			<id>btn_change_name</id>
			<isEnable>true</isEnable>
		</button>
		<button>
			<id>btn_view_devinfo</id>
			<isEnable>true</isEnable>
		</button>
		<button>
			<id>btn_init</id>
			<isEnable>true</isEnable>
		</button>
	</view>
</request>

requestType可以是一些已在概要设计里归纳需要实现的需求,比如createUI、closeUI、showUI、hideUI、updateUI。updateUI中对应的是viewId。当且仅当是createUI需要viewType、viewParent、devId。createUI的返回参数有一个是viewId。

该数据格式在VM的requestCallback中调用。

2.9.4 VM->Controller交互事件数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateUI</requestType>
	<view>
		<viewType>mainView</viewType>
		<viewIndex>view_1</viewIndex >
		<event>click</event >
		<listView>
			<id>listView_mainView</id>
			<selectedId>param_2</selectedId>
		</listView>
	</view>
</request>

用户点击了listView的证书节点。

该数据格式在DM的eventCallbackForVM中调用。

用户选择了证书,则提交请求使能证书操作相关按钮。Controller->VM的请求在VM的requestCallback中调用,格式如下:

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateUI</requestType>
	<view>
		<viewId>1</viewId>
		<viewType>mainView</viewType>
		<button>
			<id>btn_view_param2</id>
			<isEnable>true</isEnable>
		</button>
	</view>
</request>

用户点击了修改名称按钮。则调用一次VM->Controller的交互事件,声明按钮动作,Controller再提交一次到VM的交互请求:

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>createUI</requestType>
	<view>
		<viewType>changeLabelView</viewType>
		<viewId>view_2</viewId>
		<devList>
			<dev>
				<name>dev1</name>
				<id>dev1_devStd</id>
				<value>devStd</value>
				<mapToUIId>oldName</mapToUIId>
				</label>
				<sn>
				<id>DS20150415<id>
				<mapToUIId>sn</mapToUIId>
				</sn>
			</dev>
		</devList>
	</view>
</request>

用户点击了changeNameView的OK之后,调用一次VM->Controller的交互事件,正式调用修改名称操作。

2.9.5 Controller->DM的交互请求数据格式

<?xml version='1.0' encoding='utf-8'?>
<request>
	<requestType>updateDev</requestType>
	<dev>
		<id>dev1_devStd</id>
	</dev>
	<action>changeName</action>
	<paramList>
		<oldName>devStd</oldName>
		<newName>devStdNew</newName>
	</paramList>
</request>

该消息在DM的requestCallback中调用。

requestCallback处理完之后,如果执行成功,Controller再发一次到VM的更新消息,改变UI显示的Name,并创建一个提示框,提示成功。

3 补充说明:

1、同步异步调用的实现区别:

同步:调用者会等待回调结束之后做下一步操作。

异步:调用者请求之后,马上返回。如果有更新的结果,则以事件方式通知Controller。完全不需要在调用者和被调用者创建新的线程来检测。这样做的要求是要在同一进程里。

如果非得是不同进程,可以考虑实现一种RPC远程过程回调。但是目前来看,从之前讨论过的安全性问题来看,应该尽量做到同一进程,然后UI以库形式调用。

2、UI中定义的按钮响应函数处理方法:

所有的按钮功能在Controller中定义,比如修改名称,按照字符串匹配查找相应的函数指针,并填充相应的参数列表。可以统一所有的参数均为字符串。

3、UI中的隐藏:通过Width或者Height更新为0%即可。

至此,可以统一所有的UI请求,不论是不是管理工具发出的,或者即使是安装包的UI,都可以按照这一套来做,完全解耦。全部用XML定义。

时间: 2024-10-22 13:28:11

抽象的设备管理框架的相关文章

Linux 设备和模块的分类

概念:在Linux系统中,所有设备都被映射成 [设备文件] 来处理,设备文件,应用程序可以像操作普通文件一样对硬件设备进行操作. 一.设备类型 整理自:(相当不错,建议有时间看下原文) <第一章 设备驱动简介 1.3.节 设备和模块的分类> <Linux设备驱动之字符设备驱动> 一般情况下,以 Linux 的设备可区分为 3 种基本设备类型:字符设备.块设备,  网络设备 一个字符设备或块设备都在/dev目录下对应一个设备文件. linux用户程序通过设备文件(或称设备节点)来使用

Linux设备驱动模型--分离分层思想

一.设备驱动的分层思想:以platform设备驱动.input设备驱动为例看看他们在分层思想上的体现 [1]在核心层:一类设备总线通用的功能特性,如果某一设备支持的总线比较特别可以不使用这些功能特性,在自己的设备总线结构体中 进行重载. 例(1)platform核心层:定义在drivers/base/platform.c文件 Linux内核对设备总线先进行了一次全局的抽象,即概括了所有设备驱动总线具有的功能特性: struct bus_type { //具备总线名.总线属性.总线上设备属性.总线

Linux 设备模型基本概念

1.设备模型引入 Linux 2.6内核最初为了应付电源管理的需要,提出了一个设备模型来管理所有的设备.在物理上,外设之间是有一种层次关系的,比如把一个U盘插到笔记本上,实际上这个U盘是接在一个USB Hub上,USB Hub又是接在USB 2.0 Host Controller (EHCI)上,最终EHCI又是一个挂在PCI Bus上的设备.这里的一个层次关系是:PCI->EHCI->USB Hub->USB Disk.如果操作系统要进入休眠状态,首先要逐层通知所有的外设进入休眠模式,

系统移植的四大步骤

最近在学习系统移植的相关知识,在学习和调试过程中,发现了很多问题,也解决了很多问题,但总是对于我们的开发结果有一种莫名其妙的感觉,纠其原因,主要对于我们的开发环境没有一个深刻的认识,有时候几个简单的命令就可以完成非常复杂的功能,可是我们有没有想过,为什么会有这样的效果?如果没有去追问,只是机械地完成,并且看到实验效果,这样做其实并没有真正的掌握系统移植的本质. 在做每一个步骤的时候,首先问问自己,为什么要这样做,然后再问问自己正在做什么?搞明白这几个问题,我觉得就差不多了,以后不管更换什么平台,

深入解析物联网操作系统(架构/功能/实例分析)

?? 1.       物联网的主要特点 i.             连接 所谓连接,指的是各种各样的终端设备,都能够通过某种网络技术,连接到一个统一的网络上.任何终端之间都可以相互访问.下一代的基础通信网络,包括未来的5G,通信网络架构重构等,为物联网提供泛连接网络是核心目标.目前也已经有很多厂商推出解决方案,比如Google的thread/wave,华为的Hi-Link,以及NB-IoT等. 传统的物联网连接,都是指物联网终端设备与物联网云平台之间的连接,如下图: 在这种模式下,物联网设备

嵌入式: 根文件系统

看完1, 知道根文件系统的结构和作用. 看完2, 知道kernel挂载根文件系统的实际过程. 1. 详解制作根文件系统  http://fangjian0518.blog.163.com/blog/static/5591965620112171420757/ 什么是根文件系统?Linux引导启动时,默认使用的文件系统是根文件系统. 存放文件系统的设备就是文件系统设备.比如,对于一般使用的windows 2000操作系统,硬盘C盘就是文件系统设备,而硬盘上按一定规则存放的文件就组成文件系统,win

HelloXV1.77网络功能简介

HelloXV1.77的网络功能做了较大程度的加强,移植了业界广泛使用的lwIP协议栈,并做了很多优化工作,修正了其中的一些bug.同时,实现了一个network字符界面应用程序,可以对网络功能进行调试.同时实现了一个抽象的以太网管理框架(Ethernet Framework),实现了一套标准的网络驱动程序接口,屏蔽了不同网络驱动程序之间的差异.这样,不同的硬件,其驱动代码是不同的,但是只要遵循这一套标准的接口规范,就可以无缝挂接到HelloX内核中. 下面简要介绍V1.77版的网络调试程序ne

cat /proc/devices 和ls /dev

对于新手来讲,linux的框架实在是太庞大,况且很多知识点需自己做才能理解 设备 文件 ,设备编号  #ll  -a /dev  在每一行都可以看到设备文件.设备编号(主.次) 对于每种硬件设备,系统内核有相应的设备驱动程序负责对它的处理.而在Unix 中,使用设备文件的方式来表示硬件设备,每种设备驱动程序都被抽象 为设备文件的形式,这样就给应用程序一个一致的文件界面,方便应用程序和操作系统之间的通信. 习惯上,所有的设备文件 都放置在/dev 目录下. /proc/devices/中的设备是通

Android HAL模块实现(转)

Android的HAL(Hardware Abstract Layer硬件抽象层)是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚.思路是把控制硬件的动作都放到了Android HAL中,而linux driver仅仅完成一些简单的数据交互作用,甚至把硬件寄存器空间直接映射到user space.而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android只是一个开放的平台,并不是 一个开源的平台. 总结下来,Androi