DtvFrame设计思路.doc_第1页
DtvFrame设计思路.doc_第2页
DtvFrame设计思路.doc_第3页
DtvFrame设计思路.doc_第4页
DtvFrame设计思路.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DTV应用程序设计思路一 系统架构DTV应用程序采取三层模型,以此来提高软件的可移植性和扩展性。图下图所示:1. 基础支撑类库层:封装不同功能的基础类库,将应用程序的功能模块以及基础框架开发与具体的平台(硬件平台和操作系统)隔离开来。初步包含多线程相关类,例如线程、信号量、互斥锁、事件等;网络通信类,例如TCP/UDP等网络SOCKET封装;日志调试输出以及文件操作;数据结构类,例如队列、堆栈、MAP等;其它与操作系统或驱动相关的封装类。2. 应用框架层:提供应用框架、消息管理、模块管理、数据管理以及GUI相关等功能,完成应用程序的基础框架,实现不同模块间的消息传递和模块加载、协调运行。同时提供应用模块开发的必要接口。3. 功能模块层:根据应用框架提供的接口开发的各种具体功能模块,以及移植和封装的第三方中间件等。二 设计思路应用程序的运转是由消息机制驱动的,而且所有消息都要经过图形系统的消息循环。消息分为系统消息和用户自定义消息。系统消息是由应用框架定义好的具有固有特征的消息,例如启动、初始化、退出、各种按键操作、各种内部事件(SI、CA)等。用户自定义消息是由各个应用模块自行定义并处理的消息。消息的执行分为同步消息和异步消息。所有模块必须将其完成的功能绑定到具体的消息上,包括加载、初始化等过程,并明确对消息的处理是否具有排他性,以适应多个模块绑定到相同消息的情况。应用模块分为静态模块和动态模块。静态模块表示在应用程序发布时编译到应用程序中的各个模块;动态模块指在应用程序运行过程中允许从独立编译好的二进制文件中加载的功能模块。应用框架与各模块之间都可以通过指定的接口直接访问全局或共享的数据及属性参数。也可以定义模块独立的数据,仅方便模块内部访问。三 应用程序Demo介绍基于以上的架构和思路,构建了一个最小的应用程序Demo。组成包括:1 基础类库源自Apple发布的一个开源类库,包括线程管理,数据结构,网络,和文本解析工具。这些类的封装简化了较高层次的代码;借助这些类还分离了专用于不同平台的代码。下面是对库中各个类的简短描述: OS类。这些类在时间,条件变量,互斥锁,和线程方面提供了专用于不同平台的代码抽象。这些类包括OS,OSCond,OSMutex,OSThread,和OSFileSource。 数据结构类。包括OSQueue,OSHashTable,OSHeap,和OSRef。 套接口类(Sockets)。这些类为TCP和UDP网络通讯方面提供了专用于不同平台的代码抽象。通常情况下,套接口类是异步的(或者说是非阻塞的),可以发送事件给Task对象。这些类有:EventContext,Socket,UDPSocket,UDPDemuxer,UDPSocketPool,TCPSocket,和TCPListenerSocket。 解析工具。这些类负责解析和格式化文本。包括StringParser,StringFormatter,StrPtrLen,和StringTranslator。 Task(任务):Task(任务)对象就是执行这种通讯的一般性的机制。每一个Task对象都有两个主要的方法:即Signal和Run。调用Signal方法来把一个事件发送给Task对象,而Run方法则用来为Task对象指定处理事件的时机。每个Task对象的目标都是用小的非阻塞的时间片来实现具体的功能。2. 消息结构定义struct APPMsgUINT32 uiMsgID;/消息的ID值UINT32 uiParam1;/参数1UINT32 uiParam2;/参数2UINT32 uiParam3;/参数3;消息的不同ID值代表不同的消息,一个消息最多允许带三个参数,也可以不带任何参数。参数的具体含义需与消息ID对应起来,例如uiMsgID表示为一个遥控器或面板按键消息,则参数uiParam1是按键的值。消息ID定义:enum /system msg define/ Globe Msg DTV_MSG_Invalid= 0, DTV_MSG_Register= 1, DTV_MSG_Initialize= 2, DTV_MSG_Shutdown= 3, DTV_MSG_Restart= 4, DTV_MSG_ErrorLog= 5, DTV_MSG_RereadPrefs= 6, DTV_MSG_StateChange= 7,/ Module Msg DTV_MSG_LoadModule= 8, DTV_MSG_SleepModule= 9, DTV_MSG_WakeupModule= 10, DTV_MSG_UnloadModule= 11, DTV_MSG_ShowWindow= 12, DTV_MSG_HideWindow= 13,DTV_MSG_UpdateWindow= 14,/ Event Msg DTV_MSG_Keyvent= 15, DTV_MSG_CAEvent= 16, DTV_MSG_SIEvent= 17, DTV_MSG_SystemNum, /user msg base define DTV_MSG_ID_UserDefine= 512 ;typedef UInt32 DTV_MSG_ID;Register注册消息模块在处理Register消息时,向应用框架报告自己支持的其它消息。应用程序在启动的时候,会发送一次Register消息给各个模块。Register消息总是应用程序执行的第一个消息。如果模块的Register消息执行不成功,则不会被装载。Initialize初始化消息所有模块处理Register消息之后,应用框架接着向各个模块发送Initialize消息,如果这些模块注册了该消息的话。模块通过Initialize消息来初始化全局的和私有的数据结构。应用框架会向每个模块的Initialize消息传入一些对象参数,这些对象可以用于获取应用框架的全局属性,预置信息,以及文本错误信息。 3. 字典对象字典是一种把键值对实现为对象数据的数据存储类。应用框架对象中有一个预置信息字典。应用框架内部有一个模块列表,列表中的每一个模块都有一个字典,用于存放自己的预置信息。字典对象为模块和应用框架之间的数据交换提供了一种途径。每个字典对象是由一些属性组成的,这些属性用于存储数据。每个属性都有一个名称,一个属性ID,一个数据类型,以及一个读写属性值的权限。字典对象的数据结构:struct DictValueElement / This stores all necessary information for each attribute value. DictValueElement() : fAllocatedLen(0), fNumAttributes(0), fAllocatedInternally(false), fIsDynamicDictionary(false) / Does not delete! You Must call DeleteAttributeData for that DictValueElement() StrPtrLen fAttributeData; / The data UInt32 fAllocatedLen; / How much space do we have allocated? UInt32 fNumAttributes; / If this is an iterated attribute, how many? Bool16 fAllocatedInternally; /Should we delete this memory? Bool16 fIsDynamicDictionary; /is this a dictionary object?;字典对象的属性的数据结构:struct AttrInfo / This is all the relevant information for each dictionary / attribute. char fAttrNameDTV_MAX_ATTRIBUTE_NAME_SIZE + 1; DTV_AttrFunctionPtr fFuncPtr; DTV_AttrDataType fAttrDataType; DTV_AttrPermission fAttrPermission;有两种属性类型: 静态属性。静态属性可用于一个对象类型的所有实例。模块只能在Register消息中将静态属性添加到对象中。所有应用框架内置的属性都是静态属性。 实例属性。实例属性添加到相应的对象类型的特定实例中。模块可以使用在任何时候将实例属性添加到相应的对象中,也可以删除已经添加到对象中的实例属性。向对象类型或者对象实例中添加一个或者多个属性,是模块存储专用或私有数据最有效的方法。添加静态属性的效率要比添加实例属性高。模块通过存储在字典对象中的属性来和应用框架交换信息,因此会经常读取属性的值。有三个接口函数可以用于获取属性值: DTV_GetValue,将属性值拷贝到由模块提供的缓冲区中。这个函数可以用来获取任何属性的值,但是其效率不如DTV_GetValuePtr函数。 DTV_GetValueAsString,将属性值作为一个字符串拷贝到由模块提供的缓冲区中。这个函数可以用来获取任何属性的值,是效率最低的获取属性值的方法。 DTV_GetValuePtr,返回一个指向应用框架内部的属性值拷贝的指针。这是获取抢占访问安全的属性的最有效方法。这个函数也可以用于获取非抢占访问安全的属性,但是需要首先将对象锁定,在DTV_GetValuePtr函数调用之后则需要解锁。在获取一个非抢占访问安全的属性时,调用DTV_GetValue函数可能比首先锁定对象,然后调用DTV_GetValuePtr函数,最后解锁对象的效率要高。有两个接口函数可用于设定属性的值: DTV_SetValue:将模块提供的值拷贝到属性缓冲区中。 DTV_SetValuePtr,设置一个指向应用框架内部的属性值拷贝的指针。4. 模块完成不同功能的软件单元可以构成一个独立的应用模块。模块可以创建线程,使用互斥锁,并且可以完全自由地使用任何操作系统工具。模块应该遵循下面的规则: 尽可能快地执行任务,并将控制权返回给应用框架。 在执行I/O的时候,尽可能避免使用同步I/O。一个模块的I/O操作被阻塞,可能会影响其它模块的运行。 有显示窗口的模块须处理好排他性和容他性。每个DTV模块必须实现两个函数接口: 一个Main函数,应用框架在启动的时候将调用这个函数,来模块所在的DTV stub库进行初始化。 一个Dispatch(分发)函数,应用框架为了某种特定的目的调用模块时,需要使用这个函数。Main函数:每个DTV模块必须提供一个主函数。应用框架在启动的时候会调用这个主例程,并使用这个例程来初始化DTV stub库,以便在之后调用该模块。对于编译到应用框架里面的模块,其主函数的地址必须传递到应用框架的模块初始化函数中。主函数的函数体必须按照如下方式书写:DTV_Error MyModule_Main(void* inPrivateArgs) return _stublibrary_main(inPrivateArgs, MyModuleDispatch);这里,MyModuleDispatch是模块分发函数的名称。对于二进制提供的模块,主函数必须命名为MyModule_Main,其中MyModule是包含模块的文件名称。Dispatch函数:每个DTV模块都必须提供一个分发函数。应用框架为了某种特定的目的需要某个模块时,需要调用该模块的分发函数,并在调用时将任务的消息及相应的参数块传递给该函数。分发函数必须具有下面所示的原型:DTV_Error MyModuleDispatch(DTV_MSG_ID inMsg, UINT32 uiParam1, UINT32 uiParam2, UINT32 uiParam3);其中MyModuleDispatch是分发函数的名称,由模块的主函数来指定;inMsg是消息的ID,只有注册了该消息的模块才会被调用;uiParam1,u

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论