BREW平台主要技术的分析与总结

摘要:2003年,美国高通公司在中国推出了BREW平台,在中国获得了快速的发展和应用。时间虽然不短,但是由于高通公司的种种约束以及BREW平台本身的诸多限制,使得许多开发人员对在BREW平台下进行开发不得要领。本文深入分析了BREW平台的主要技术以及实现机制,包括模块加载机制、事件处理机制、接口机制和回调机制,以期对BREW平台有深入透彻的理解,并对BREW的主要技术进行了总结。

关键词:BREW;模块加载;事件处理;接口;回调机制

中图分类号:TP311

1         引言

如今,手机已不仅是语音通信的工具,而且逐步成为数据业务开发与应用的平台,随着科学技术的不断更新和发展,如今手机已不仅仅是满足打电话的功能,而是更多地成为人们在工作、学习和生活中的助手。在这种情况下CDMA手机产生了一种新的应用平台,也就是由美国高通公司研发出的BREW平台[1]

BREW 是Binary Runtime Environment for Wireless(无线二进制运行环境)的缩写,是美国高通(QUALCOMM)公司为无线数据应用程序开发和执行提供的通用接口平台。它为制造商和开发人员提供了一套应用程序接口(API),可以随时对运行环境进行扩展,提供应用程序需要的各种附加性能模块[2]

BREW 包含两个系统,一个是在运营商的发布系统,也就是平时用mobile shop 访问的系统;另一个是在手机端的BREW 运行环境系统。不同的厂商对手机所配备的操作系统一般都是独立开发的(智能手机除外),之间可能是千差万别,然而它们都共同需要运行BREW程序,这就需要依赖一个的中间层存在,这个中间层对BREW 程序提供调用的接口,而把程序的调用事实上转化为对操作系统的系统调用或对底层硬件的直接访问,由于这个中间层基本上是一个调用的中转关系,因此它本身的体积是很小的,并在BREW 运行期间一直驻留内存为BREW 程序提供服务,这也就是为什么即使操作系统在BREW 运行期间不占用内存,应用程序也无法完全的使用内存。

2         BREW平台主要技术

2.1     模块加载机制

在BREW中,Module是基本的执行单位,一个Module可以包含一个或多个Applet,或者多个Extension Class[3]。下面具体分析BREW是如何动态加载模块的。

1)        Module的信息

原则上来说,每个Module都需要有标识自身的MIF文件。

2)        枚举Module信息

这一步是在BREW环境初始化的时候进行的,由于通常在开机时就初始化BREW环境,所以枚举Module信息在开机时就进行。对于BREW通过检索各个MIF文件来获得各个Module的必要信息,比如ClassID等。ClassID是一个4字节的无符号整数,作为Module的唯一标识。

3)        Module加载

Module的加载是在运行时才进行的,即执行该Module的时候。Module的加载是通过调用函数AEEMod_Load()实现的,而AEEMod_Load()实际是调用AEEStaticMod_New(),该函数的部分代码如下:

int AEEStaticMod_New(int16 nSize, IShell *pIShell, void *ph, IModule **ppMod,

PFNMODCREATEINST pfnMC,PFNFREEMODDATA pfnMF)

{

AEEMod *pMe = NULL;

VTBL(IModule) *modFuncs;

... ...

// 初始化函数指针

modFuncs->AddRef         = AEEMod_AddRef;

modFuncs->Release        = AEEMod_Release;

modFuncs->CreateInstance = AEEMod_CreateInstance;

modFuncs->FreeResources  = AEEMod_FreeResources;

// 初始化虚函数列表

INIT_VTBL(pMe, IModule, *modFuncs);

... ...

return SUCCESS;

}

在该代码片段中AEEStaticMod_New()向BREW运行系统注册了四个函数,其中就有一个AEEMod_CreateInstance()函数,这样在每次BREW系统加载Module时都会去调用该函数,所有函数的源头调用点,就在这里[4]

4)        Module 创建

这是通过AEEMod_CreateInstance()函数来创建的。该函数的实现如下:

static int AEEMod_CreateInstance(IModule *pIModule,IShell *pIShell,AEECLASSID ClassID,void **ppObj)

{

AEEMod    *pme = (AEEMod *)pIModule;

int        nErr = EFAILED;

if (pme->pfnModCrInst) {

nErr = pme->pfnModCrInst(ClassID, pIShell, pIModule, ppObj);

#if !defined(AEE_STATIC)

} else {

nErr = AEEClsCreateInstance(ClassID, pIShell, pIModule, ppObj);

#endif

}

return nErr;

}

而通过分析AEEMod_CreateInstance()的代码,我们又可以发现Module指定了通过调用通用函数AEEClsCreateInstance()来创建Module包含的每个Applet。

5)        Applet创建

AEEClsCreateInstance()通过AEEApplet_New()来最终创建Applet,AEEApplet_New()无非是具体分配Applet内存,初始化Applet的回调函数列表,并实例化Applet_HandleEvent(),然后返回IApplet指针,供运行时使用。

6)        程序运行

通常就是在Applet_HandleEvent()中进行各种事件处理。处理前一般将传入的IApplet指针先转换为AEEApplet或者用户自身的结构,以便可以访问其中的数据成员。

通过对模块加载流程的跟踪分析,给出模块加载的主要过程如下:

首先BREW允许系统调用AEEMod_Load ()函数,该函数不做任何事情将任务完全委托给函数AEEStaticMod_New()进行处理; AEEStaticMod_New()函数会加载一个Module,并注册必要的函数,其中就注册了函数AEEMod_CreateInstance();AEEMod_CreateInstance()函数创建模块实例并调用函数AEEClsCreateInstance();这个函数的功能就是依据ClassID 来创建该Module中所含有的所有Applet。当该模块要退出时,BREW会调用在AEEStaticMod_New()注册的函数AEEMod_FreeResources()释放资源。

2.2     消息处理机制

BREW应用程序的模型是基于一个事件驱动的协作式多任务模型[5]。事件处理机制的核心问题是程序应该只处理需要的事件,对于不需要处理的事件,需要返回给系统处理。应用在加载之后可以通过HandleEvent()函数接收所有输入的事件,然后会通过返回TRUE或FALSE指示是否处理事件。AEE层存在一个全局的事件队列,所有的事件都存储在该队列中,如果队列中的事件在分发后处理完毕或者无人处理,该事件将被从事件队列中删除。

BREW环境要求及时地处理事件。简而言之,如果应用执行处理事件HandleEvent()调用后没能在合适的时间返回,AEE可能就会关闭应用以保护设备响应其他请求。有些操作,例如,从网络套接字中读取数据,也许耗时过长,无法一次调用事件处理期就可以完成。这时就需要采用回调机制,以便在操作完成之后通知该应用。

BREW 中的消息处理函数都是Boolean返回类型的,这是为了实现事件处理的层次机制,当该层上的消息处理函数没有处理该事件时,应该返回FALSE,以便上层对该事件感兴趣的消息处理函数来处理。如果处理了,应该返回TRUE,说明该事件已被处理,无需其他层再处理。

当BREW 运行后,首先捕捉到各种事件,并将事件分发至BREW 环境中,BREW 环境再通过消息发送模块具体分发消息至目的地。接着在两种不同的情况下将走不同的流程。

如果当前没有活动对话框,则紧接着IAPPLET_Handleevent被BREW 自动调用来处理事件,从而实现了允许用户程序捕捉到事件并处理的机制。在用户的程序在处理消息过程中,用户程序可以将事件继续下发。

如果当前有活动对话框,则紧接着这个对话框的事件被BREW 自动调用,从而使得事件被对话最先截获,而对话框之后的处理是检查这个对话框包含的控件中哪个处于激活状态,并将事件下发给它的消息处理函数来处理,同时根据其返回值来判断其是否已经处理了该事件,当其返回FALSE 后,对话将该事件继续转发至其他对话框注册的消息处理函数,如果该消息处理函数仍然返回FALSE,BREW 继续将该事件转发至其他消息处理函数。这种机制使得以对话框方式来创建应用时,各种事件被自动的处理,从而简化了代码量.

除了IAPPLET具有HandleEvent外,所有继承IControl的接口也具有事件处理函数,允许处理事件。

例如:

Static Boolean IAPPLET_HandleEvent(AEEApplet * pMe, AEEEvent e, uint16 wp, uint16 dw)

{

case EVT_APP_START:               //模块启动时

case EVT_APP_STOP:                       //模块停止时

case EVT_KEY:                                  //响应按键事件

case EVT_COMMAND:               //响应控件事件

IMENU_HandleEvent();                      //控件事件处理函数

ITEXTCTL_HandleEvent();

case EVT_DIALOG_INIT:                  //响应对话框初始化事件

}

2.3     接口机制

BREW中所提供的服务实际上是一些小的二进制可执行程序形成的组件,它们可以给应用程序、操作系统以及其他组件提供服务[6]。开发自定义的BREW组件(如BREW 扩展类)类似于开发动态的、面向对象的API。多个BREW对象可以连接起来形成应用程序或组件系统。并且,组件可以在运行时刻,在不被重新链接或编译应用程序的情况下被卸下或替换掉。

BREW可以在运行时刻同其他组件连接起来构成某个应用程序,可以动态地加载或卸载应用,是动态链接的。BREW组件隐藏(封装)其内部实现细节,基于BREW的应用以二进制的形式发布,可以在不妨碍已有用户的情况下升级BREW应用或者BREW组件(如扩展类)。BREW的自定义扩展类按照一种标准的方式来宣布它们的存在。

BREW组件之间通过接口进行交互。接口是包含了一组函数的数据结构,通过这组数据结构,代码可以调用组件对象的功能。接口定义了一组成员函数,这组成员函数是组件对象暴露给客户的所有可用信息,客户可以利用这些信息取得组件提供的服务。

BREW提供了一组固定的接口,即使以后实现的方式出现了变化,只要应用程序和组件程序之间的接口不变,就不需要任何改变。BREW使用基于接口对象的引用计数来控制接口的生存期,并且为多个程序之间共享统一接口对象提供了有效的控制手段。BREW接口的引用计数使用方式是针对每个接口类或者应用程序采用引用计数[1]。

应用程序用一个指向接口数据结构的指针来调用接口成员函数,如图2.2所示。

图1 BREW应用程序的接口指针示意

BREW平台支持C和C++开发语言,但是一般的BREW应用程序都是用C写的,而对于C++的使用,BREW平台则需要做更多的事情,比如定义符重载等。而C语言是不支持面向对象的,只有C++支持面向对象的程序设计,因此BREW中必须使用C语言模拟实现C++语言面向对象机制。而面向对象技术中的关键技术多态是基于以上的内存模型和函数指针实现的,一般来说,如果使用类C语言描述多态,它相当于增加了一个间接层,在这个间接层拦截对于方法的调用,然后根据具体的指针指向实际对象调用相应的方法实现[1]。

下面结合具体的代码,对BREW接口和多态机制进行解释。

C结构体中内存对象的布局是采用按照定义顺序排列的,如果结构体定义如下:

struct A

{

int a;

int b;

int b;

};

在内存中的各个变量的布局为:

int a;

int b;

int c;

而如果结构体的定义如下:

struct B

{

int a;

int b;

int c;

int d;

};

在内存中的布局为:

int a;

int b;

int c;

int d;

这样可以看出完全是按照定义的顺序布局的,而如果采用如下的方式定义结构体C:

struct C

{

struct A a;

int d;

};

其在内存中的布局则为:

struct a;

int d;

这样把结构体成员a全部展开,就与结构体B的内存布局相同,存取结构体C中的a的成员a,虽然采用C.a.a才可以,但是内存中的布局与直接访问A.a效果是相同的,只不过增加了一个编译中间层,因此,在BREW中可以依照此技术实现继承机制。而把父结构体当作子结构体的第一个成员变量时,可以在运行时通过使用父结构的成员访问方式直接访问实际子结构体的成员变量,并且可以使用类型转换,转换为实际的子结构体,这样的技术正好是面向对象程序设计中继承和多态技术的基础。

BREW接口中定义了大量的函数指针,并且BREW规定所有BREW的模块必须实现IBase接口,而IBase接口的实质为如下的定义:

struct IBase

{

uint32  (*AddRef) (iname*);

uint32  (*Release) (iname*);

};

为了能够顺利从IBase接口派生特别定义了宏INHERIT_IBase,它就是如上的接口定义,而且BREW的定义模型,为了防止在接口之间转换造成混乱,只支持单根继承,也就是说用户每次只能够从一个接口派生,并不能同时派生多个接口,派生时使用如下的方式:

struct IInherit

{

INHERIT_IBase(IInherit);

void (*func1)();

void (*func2)();

};

这样根据前面介绍的内存模型,可以使用IBase接口来访问他的成员,而实际上访问的是IInherit接口的成员。

以上是继承的实现,相应的多态机制也就可以实现了。派生接口可以添加自己的成员变量和成员函数,不同的派生接口因而有了不同的特性,从而实现了接口的多态机制。

2.4     回调机制

回调机制是BREW平台中最关键的机制之一,很多接口类都是通过回调机制呈现在开发人员的面前[7]。相关操作函数为Callback_init()、Ishell_resume()和Callback_cancel().

BREW平台的回调机制,通常是异步的,举例来说,在网络通信的时候,如果是发送数据,普通的方式是发送一快数据,判断是否发送成功,如果发送不成功,则空闲一段时间,在调用发送数据的函数,如此往复,但是如果在BREW平台上,调用发送函数发送数据,如果发送成功,函数会返回发送成功的字节数,如果返回的是-2,表示当前发送不成功,接下来,需要注册一个回调函数,BREW会根据网络状况调用你注册的回调函数,继续发送需要发送的数据,直到所有数据发送成功。同样的道理,在接收数据的时候,如果数据量比较大,不是一次能够接收完,需要注册接收回调函数,当有数据到的时候就会调用你注册的回调函数接收数据,直到所有数据接收成功。

BREW平台回调机制的实现有几个关键的部分下面一一介绍。

Callback机制中的核心数据结构[8]

typedef struct _AEECallback AEECallback;

struct _AEECallback

{

AEECallback *pNext;

void        *pmc;

PFNCBCANCEL  pfnCancel;

void        *pCancelData;

PFNNOTIFY    pfnNotify;

void        *pNotifyData;

void        *pReserved;

};

该结构体,前两个参数pNext和pmc都是不可修改的,是系统维护其值;pfnCancel和pCancelData是在取消回调时使用的;pfnNotify和pNotifyData是在回调时使用的;最后一个pReserved是保留参数,可以存储任何数据。

CALLBACK_Init和CALLBACK_Cancel是两个关键函数。CALLBACK_Init负责对AEECallback结构体进行初始化,该函数的参数列表第二个参数是PFNNOTIFY类型,就是需要回调的函数的函数指针类型,第三个参数是传递给该回调函数的参数指针,类型是void型指针。CALLBACK_Cancel函数是取消回调函数,也就是调用AEECallback结构体中的pfnCancel指针指向的函数来取消回调。ISHELL_Resume()函数允许向 AEE 外壳注册回调。 它可以向 AEE 外壳的待处理操作列表中添加回调。 AEE 外壳将在下一次调用事件循环时调用此回调函数,以使应用程序或对象协同处理多任务。如果已注册回调,则会先将其注销,然后再重新注册。

如果要使用BREW平台的回调机制,则只要初始化适当的AEECallback结构体,再在需要回调的时候调用ISHELL_Resume来启动回调函数 。回调函数是由系统调用用户的函数,由系统回调的函数,而非用户自行调用,这样用户就可以根据需要动态改变系统的功能,但是要求用户设计的函数必须遵循系统的函数声明。而从技术上讲,回调函数就是函数指针,可以达到运行时动态调用函数的作用[9]

BREW中的回调函数除了使用在事件处理之外,定时器、复杂的数据加密算法和网络数据发送与接收等都使用回调函数技术,回调函数在基于事件处理的系统中还可以避免使用轮询技术导致应用程序陷入长时间的循环等待中。当把需要等待的事件或者是处理的任务作为回调函数注册到系统中,这样当系统接受到指定的消息或者是当系统处理完当前的任务,将会调用已经注册的回调函数。

在BREW程序设计中,特别需要避免的是长时间的单一函数或者方法执行,或者是使用如下的技术:

  while(1)

  {

   DoSomeThing();

  }

这种技术在游戏设计中是经常采用的,一旦进入游戏,将进入用户自己的循环,只从系统得到需要的数据。但是在BREW中,一旦陷入这种无限循环而无法及时响应系统消息,将会导致手持设备的强制性重新启动。因此在BREW中需要进行的周期性工作,一般是使用定时器来执行的,在设置定时器的时候,一般会同时初始化一个回调函数,这样在定时器结束后会调用这一个回调函数。

回调函数在BREW中的另外一个作用就是对于复杂任务的分解执行,对于十分复杂的任务或者功能,可能执行时间较长,由于这将导致设备的重新启动,因此必须修改算法,把复杂算法分步执行,没有执行完的程序也需要立刻返回,并且把没有完成的工作注册为回调函数,等下次执行调用。因此BREW的协作式多任务由此可以产生,由于把复杂任务进行了分解,导致每次只执行一部分,并且各个任务都可以得到执行的机会,因此可以产生模拟的多任务效果。但是这里的多任务是协作的,需要由用户在程序设计中进行保证,必须及时出让占用的系统资源,这个是协作式与抢先式多任务的明显区别,虽然这样增加了用户进行程序设计的难度,但是却最大限度的节约了系统资源,最大限度地增加了系统的执行和运行效率。因此在嵌入式程序设计以及BREW中被广泛采用。

3         总结

本文主要分析了BREW平台的主要技术,包括模块加载机制、事件处理机制、接口机制和回调机制,并结合具体的代码进行了深入的阐述。这四个机制并不是独立的,而是有机组成为BREW的技术核心,其中模块加载时会运用到事件处理机制和接口机制,事件处理过程同样也会运用到回调机制。对这四个机制进行深入的分析和了解,能更好更全面地理解BREW平台以及基于BREW平台的应用。

参考文献

 

[1]      陈秀寓. 基于BREW平台的多态机制实现. 软件工程师. 2010. (104).

[2]      薛飞. 深入研究BREW事件处理机制. 中国科技论文在线. 2009.

[3]      dota_1234. BREW的动态模块加载机制. CSDN博客. 2008-09-22.

[4]      yanzhong.lee. BREW加载机制. 163博客. 2007.

[5]      卜佳俊、张海翔、陈天洲. 深入BREW手机游戏开发. 第一版. 北京:清华大学出版社.  2004. 57-61.

[6]      曹洪伟. BREW进阶与精通——3G移动增值业务与运营、定制与开发. 第一版. 北京:电子工业出版社. 2009.

[7]      忆龙2009. BREW平台Callback(回调)机制的最终分析. CSDN博客. 2010-01-17.

[8]      BREWAPIReference. 参考文档. QUALCOMM Incorporated. 2005.

[9]      zhangjianwsuaf. 关于BREW中回调函数的一些讲解. CSDN博客. 2009-11-23.

Analysis and Summary of the main technology for the BREW Platform

Abstract

In 2003, the QUALCOMM launched BREW platform in China, it won the fast development and application in China. Not short, but due to various constraints, and Qualcomm BREW platform itself many restrictions, so many developers on the BREW platform for development to no avail. This paper in-depth analysis of the BREW platform and the achievement of the main technical mechanisms, including the module loading mechanism, the event handling mechanism, interface mechanism and the callback mechanism, looking on the in-depth and thorough understanding of BREW platform, also summarize the main technology for the BREW Platform.

Keywords: BREW; module loading; event handling; interface; callback mechanism.

BREW平台主要技术的分析与总结相关推荐

  1. JVET H.266编码技术amp;JEM编码平台关键技术整理分析

    也是很久没有写博客了,也不能说因为时间太忙,可能就是有些顾不太过来更新,同时自己项目和学习的进展也比较有限吧. 这篇博客是上一周,给导师做的<JVET H.266编码技术调研>.其实基本没 ...

  2. 兼顾稳定和性能,58大数据平台的技术演进与实践

    http://www.infoq.com/cn/articles/58-big-data-platform-technology 主要内容分为三方面:58大数据平台目前的整体架构是怎么样的:最近一年半 ...

  3. 【问链财经-区块链基础知识系列】 第二十二课 贸易金融区块链平台的技术机理与现实意义

    简介:贸易金融区块链平台的技术机理.模式.优势与现实意义都有哪些?对湾区贸易金融区块链平台的未来建设有何展望?本文将进行详述. 小微企业贡献了我国60%以上的GDP.50%以上的税收以及80%的城镇就 ...

  4. 稳定和性能如何兼顾?58大数据平台的技术演进与实践

    作者|赵健博 编辑|尚剑 本文将为你分享58大数据平台在最近一年半内技术演进的过程,包括:58大数据平台目前的整体架构是怎么样的:最近一年半的时间内我们面临的问题.挑战以及技术演进过程:以及未来的规划 ...

  5. 嵌入式仿真平台SkyEye的覆盖率分析

    随着嵌入式系统也越来越复杂,功能迭代越来越多,代码中就可能就会存在部分无用代码,或者在执行过程中无法测试覆盖的分支,这可能就会给软件带来很大的漏洞,严重降低软件的可靠性.因此,需要一个能够动态分析代码 ...

  6. android平台应用技术特点,Android平台应用安全关键技术研究

    摘要: 最近几年来,随着智能手机的普及和移动互联网技术的发展,手机成了人们日常生活中不可缺少的一部分.在众多的智能手机操作系统里面,Android系统以其开源,自由,免费等特点占有着很大的市场占有率. ...

  7. [2016][34]基于大数据的牛顿(Knewton)平台自适应学习机制分析

    自适应学习平台的关键技术与典型案例 1. 概述 2. Knewton平台 2.1 基础架构 2.1.1 数据收集与处理组件 2.1.2 推理与评估组件 2.1.3 个性化服务组件 2.2 数据模型 2 ...

  8. 分布式定时任务调度平台Elastic-Job技术详解

    在我们的项目当中,使用定时任务是避免不了的,我们在部署定时任务时,通常只部署一台机器.部署多台机器时,同一个任务会执行多次.比如给用户发送邮件定时任务,每天定时的给用户下发邮件.如果部署了多台,同一个 ...

  9. PaaS 平台学习(开源力量OSF)构建千万级大规模、高可靠PaaS平台的技术挑战 学习笔记

    感谢许志强老师的辛苦付出.2015年1月13日 参加云通讯PaaS平台学习,特作此记录. 大纲: 选择Paas平台的考量(我的企业是否适合选PaaS平台,我应该选怎么样的PaaS平台) 基于PaaS平 ...

最新文章

  1. Locality Sensitive Hashing(局部敏感哈希)
  2. 一次解析系统_消防稳压泵的流量、压力、选型以及配套气压罐的重难点解析
  3. 粒子网格算法 pm_使粒子网格与Blynk一起使用的2种最佳方法
  4. python 示例_带有示例的Python列表copy()方法
  5. redhat7.3安装yum源 基于外网的http服务
  6. 介绍计算机的英文文章,计算机方面的英语资料,介绍一些计算机的英语短文,有兴趣的可以看...
  7. 如何检测圣诞树? [关闭]
  8. OnePill本地保存用户的结构
  9. Atitit 运维之道 1.1.devops算是最低门槛了。什么运维平台,搞来搞去也就那些东西。无外乎cmdb、部署、监控之类的,再加点各种小平台自动化需求。 CMDB --Configurati
  10. 软件设计师考试大纲(2004版)
  11. idea+java+selenium自动化测试环境搭建
  12. Paypal支付跳转失败的原因及解决办法
  13. Flink Table和SQL中Table和DataStream的相互转换(fromDataStream、toChangelogStream、attachAsDataStream)
  14. Swift 在UILabel前面或者后面插入图标
  15. 【Flocking算法】海王的鱼塘是怎样炼成的
  16. nodejs前端+后端
  17. html parser java库_Java解析HTML之HTMLParser使用与详解
  18. 计算机教学学期小结,学年第一学期信息技术教学工作总结
  19. Linux中$home和波浪号~
  20. 微信Mac 3.0.0内测版上线!终于可以用电脑刷朋友圈了!!

热门文章

  1. 大数据平台-元数据管理系统解析
  2. js当前时间+1操作
  3. 2015湖南省赛 CSU 1783 :聊天止于呵呵(模拟)
  4. tsm linux文件备份命令,tsm 命令行参考
  5. Vue脚手架安装及项目搭建(mac版)
  6. 网关型水利遥测终端机TY910智慧灌溉的得力助手
  7. Real-time noise-aware tone mapping阅读笔记
  8. EPON与APON的区别 10G EPON如何与1G EPON兼容?
  9. ubuntu 挂载局域网网盘目录
  10. matlab怎样改文件名,使用matlab快速修改文件名