体化模块程序设计样例V.ppt

上传人:牧羊曲112 文档编号:5226462 上传时间:2023-06-15 格式:PPT 页数:32 大小:640.50KB
返回 下载 相关 举报
体化模块程序设计样例V.ppt_第1页
第1页 / 共32页
体化模块程序设计样例V.ppt_第2页
第2页 / 共32页
体化模块程序设计样例V.ppt_第3页
第3页 / 共32页
体化模块程序设计样例V.ppt_第4页
第4页 / 共32页
体化模块程序设计样例V.ppt_第5页
第5页 / 共32页
点击查看更多>>
资源描述

《体化模块程序设计样例V.ppt》由会员分享,可在线阅读,更多相关《体化模块程序设计样例V.ppt(32页珍藏版)》请在三一办公上搜索。

1、一体化模块程序设计样例(V1.00),Page 2,工程创建,一体化程序代码主要包括两个部分,一个是用户程序代码,这部分代码在完成后可编译成m0烧入模块程序中,并且状态机的应用主要在这里;另一部分是模拟器代码,这部分代码作用是可以在windows平台下对用户程序代码进行调试并且提供一个简单友好的人机界面。以下是工程的创建步骤:1、运行VC6.0 2、新建工程,在Workspaces中选择Blank Workspace项,输入工程名称后,点击确定,Page 3,3、新建工程,在Project中选择MFC AppWizard(dll),并且选择Add to current workspace,点击

2、确定。此后可一直选择默认选项,直至工程建立完毕。以后用户程序的所有代码都会放在这个工程里进行调试,当然为了配合模拟器的使用,工程里还带有部分模拟器的代码段。,Page 4,4、新建工程,在Project中选择MFC AppWizard(exe),并且选择Add to current workspace,点击确定。该工程将来会作为模拟器来使用,我们这里选择比较简单的对话框工程,如果对VC比较熟悉的,可以选择其他的工程类型来作为模拟器的平台,Page 5,模拟器和用户代码之间的通信,用户代码是运行在嵌入式系统下的,为了让这些代码可以在windows下进行调试,我们可以把代码封装在动态链接库中,并在

3、模拟器中进行加载。同时创建一个线程,在线程开启后可通过statewizard提供的一些API函数完成模拟器和用户代码之间的通信。基本流程如图所示:,Page 6,样例,该样例的功能是实现模块开机后自动搜网的功能1、状态分析 下面我们先对模块的各个状态进行一个简要分析。开发板在按下复位键后,模块开始上电运行。模块此时的状态从下电状态切换到上电状态,同样的道理,关机的过程的状态切换则为上电状态到下电状态。除此之外,模块不会再有第三种状态存在。也许有人会说模块也有可能上电失败阿,没错,上电失败确实是第三种状态,不过,我们做的是用户程序,对于用户程序来说开始只有STOP和START,上电失败后用户程序

4、仍然是处于STOP。因此,我们可以设定,模块的初始状态由两种,这两种状态可互相进行切换。,Page 7,根据我们的最初目的,在模块开始后,需要其执行一段搜网的操作,也就是说模块不会立即进入IDLE状态。我们可定义搜网过程的状态为REGISTER。此时的模块状态关系可如图所示:进入IDLE状态后,模块的搜网算是结束,这个程序中我们只实现开机搜网的这一功能,至于后续由于键盘操作或是其他操作造成的一些状态。我们统统把其划分为IDLE范围内。在REGISTER中,我们需要执行多个AT命令已达到搜网的目的,也就是说我们可以根据这些AT命令来对REGISTER进行细分。以下是我们设定的搜网步骤:,Page

5、 8,把上面几幅图整合起来,就是模块搜网时的所有状态,Page 9,2、事件分析 从STOP状态切换到START状态,是由于收到了一个POWER_UP的事件;同样从START切换到STOP是由事件POWER_DOWN导致。在REGISTER中,我们一般是通过AT命令来进行判断下一步该做什么操作的,因此对外来说,状态间的切换是受到事件AT_CNF引起,至于切换到哪一个状态则要根据AT命令的回应内容进行判断,我们这里简单定义AT命令回应正常时为AT_CNF_OK,不正常时为AT_CNF_ERROR。列举的事件列表如下:EVENT_POWER_UPEVENT_POWER_DOWNEVENT_AT_C

6、NFEVENT_AT_CNF_OKEVENT_AT_CNF_ERROR,Page 10,3、编码刚才我们已经把模块开机搜网的状态分析完毕,接下来我们所要做的就是在代码中实现这些状态切换。在statewizard开发包(以下简称state)中,我们可以通过简单的一些菜单操作,即可方便的实现这些代码。State的安装步骤可参考UML StateWizard,这里不做详述。另外,在两个工程中都需要加入state提供的一个链接库,可以在vc中进行加载,链接库文件可在state的样例中找到。,Page 11,3.1 文件类型设计首先,需要更改state设定的插入的文件类型(默认是.cpp文件,我们用的是

7、.c文件)。在state工具栏中点击settings图标,弹出对话框,如下图进行设置。,Page 12,3.2 应用添加安装好state后,在workspace边框中会有statetree的页面选项,选择它。在页面框中我们可以看到之前我们创建的两个子项目的状态树,目前里面只有项目名称及挂在其下的几个初时文件名。,Page 13,选择app application(s),右键菜单中选择New Application。弹出如下对话框,在Application Name中输入名称后点击确定。Entry Function是指程序进入这个状态的入口函数,即进入该状态后第一个执行的函数就是它;同样道理,E

8、xit Function是程序退出该状态时执行的最后一个函数。我们可以利用这两个函数作一些变量初始化和内存释放的操作。在有些情况下我们可以不需要这些入口和出口函数,可以把前面的勾选去掉即可。,Page 14,应用创建后,可以看到APP工程里已经添加了两个名为POWERUPDOWN.c和POWERUPDOWN.h的文件。这里对里面的代码做一个简要解释,详细说明可在UML StateWizard中找到。,Page 15,FILE:POWERUPDOWN.c,Page 16,列举了在POWERUPDOWN状态中的事件函数列表SME_BEGIN_STATE_DEF(POWERUPDOWN,POWERU

9、PDOWN)/*SME_STATE_DEF(POWERUPDOWN,POWERUPDOWN)*/SME_STATE_ENTRY_FUNC(POWERUPDOWNEntry)SME_STATE_EXIT_FUNC(POWERUPDOWNExit)/*SME_STATE_DEF*/SME_END_STATE_DEF列举该应用下的状态之间的关系SME_BEGIN_STATE_TREE_DEF(POWERUPDOWN)/*SME_STATE_TREE_DEF(POWERUPDOWN)*/SME_STATE(POWERUPDOWN,POWERUPDOWN,SME_INVALID_STATE,-1)/*S

10、ME_STATE_TREE_DEF*/SME_END_STATE_TREE_DEF,Page 17,对该应用的一个宏定义,其定义了一个SME_APP_T的结构。这个应用的状态树的名称即为POWERUPDOWN_STATE_TREE。SME_APPLICATION_DEF(POWERUPDOWN,POWERUPDOWN)函数实体int POWERUPDOWNEntry(struct SME_APP_T*pApp,struct SME_EVENT_T*pEvent)return 0;int POWERUPDOWNExit(struct SME_APP_T*pApp,struct SME_EVENT

11、_T*pEvent)return 0;FILE:POWERUPDOWN.h里面是对一些状态的声明及函数声明,这里略过。,Page 18,3.3 状态添加状态树的添加和应用添加类似,选中POWERUPDOWN应用,右键选择NEW state。在对话框中写入各个状态的名称。,Page 19,下图为所有状态添加完毕后的状态树,Page 20,3.4 事件添加和状态添加一样,通过右键菜单,我们可以在各个状态中添加其需要处理的事件。第一次添加事件时,state会提示你需要创建一个事件列表,还记得之前的事件分析吗?根据对话框的提示,我们创建好的文件中把所有事件进行枚举。,Page 21,FILE:even

12、tid.henum/*SME_EVENT_ID_LIST_DECLARE*/EVENT_POWER_UP=0,EVENT_POWER_DOWN,EVENT_AT_CNF,EVENT_AT_CNF_OK,EVENT_AT_CNF_ERROR/*SME_EVENT_ID_LIST_DECLARE*/;事件列表创建完毕后,我们就可以正常进行事件添加了。选中一个状态项,右键菜单选择Add Event Handle弹出对话框。,Page 22,Event ID:事件ID值Transit to选项:指在发生该事件后需要切换到哪个一个状态。Internal Transition选项:指事件为内部事件,事件发

13、生后状态不进行改变。Action:事件发生后执行的函数,可省去。按照之前的事件分析,我们把所有事件添加入程序中,由于事件EVENT_AT_CNF_OK和EVENT_AT_CNF_ERROR需要现解析EVENT_AT_CNF所传过来的参数进行解析,因此这两个事件处理需要在后续的代码添加中进行实现,在此先不进行描述。,Page 23,模拟器的实现,模拟器部分的代码是纯windows的代码,其主要的内容是向用户程序发送一些模拟事件及处理用户程序发过来的一些事件处理。1、创建一个线程类一个线程对应一个用户程序中的应用,这里我们的用户程序只有一个应用,因此只需要创建一个工作线程即可。包含头文件#incl

14、ude“srvAgent.h”定义一个线程上下文 SME_THREAD_CONTEXT_T g_PowerUpDownThreadContext,Page 24,在虚函数中加入如下代码HWND hWnd=AfxGetMainWnd()-m_hWnd;/*设置上下文id,可和当前的线程id进行匹配,也可以自己设定任意值*/g_PowerUpDownThreadContext.nAppThreadID=GetCurrentThreadId();/*根据不同的宏定义,加载不同的用户程序做成的链接库*/#ifdef _DEBUG#ifdef _UNICODEAgtStartAppThread(hWnd

15、,_T(App_UD.dll),AppMain,#endif,Page 25,2、增加初始化时打开线程的代码定义全局变量 HANDLE g_hPowerUpDownThread=NULL;/*保存线程句柄*/在OnInitDialog()中打开线程CWinThread*pAppThreadObj=AfxBeginThread(RUNTIME_CLASS(PowerUpDown);g_hAppThread=(HANDLE)pAppThreadObj;3、增加一些事件触发按键这里为了简单起见,只通过一些button控件来实现事件触发,Page 26,用户程序中完成一些state的api调用,通过调

16、用state的API函数,以及注册state的相关回调函数,可以最终实现和模拟器的数据交互。由于这部分代码是用于模拟器调试部分,为了方便后续的编译问题,我们让其单独生成一组文件(main.c/main.h)。主要函数有:AppMain()。此为链接库的入口函数,主要进行一些状态机的初始化操作以及回调函数设置。如果需要定义一些回调函数的话,也可以在把回调函数写在这个文件中。设置回调的API函数可以参考文档State Machine Engine API。,Page 27,事件处理,先前有些状态中的事件需要先进行分析后才能决定下一步的走向,因此我们在这些事件处理函数中要加入一些分析代码。下面以状态

17、qTSIM中的EVENT_AT_CNF为例:在我们向模块发送AT%TSIM查询命令后,会得到当前sim卡的状态,如果返回的值为1则表示sim已激活,我们可以进行下一步AT命令执行;如果返回的值为0,则表示当前sim未激活,此时状态直接跳转至IDLE状态。我们在事件函数中加入如下代码:SME_EVENT_ID_T nEventId;SME_EVENT_T*pInteralEvent;if(*(char*)pEvent-Data.Ptr.pData+6)=1)/*%TSIM 1*/nEventId=EVENT_AT_CNF_OK;,Page 28,else/*%TSIM 0*/nEventId=E

18、VENT_AT_CNF_ERROR;/*发送事件进行不同的状态触发*/pInteralEvent=SmeCreateIntEvent(nEventId,0,0,NULL,pApp);SmePostEvent(pInteralEvent);同样我们在其他的一些事件函数中也可加入类似代码。,Page 29,调试代码,到目前为止,一个简单的模拟器+用户程序代码已经初具雏形了,可以用VC的debug模式进行简单的模拟调试了,为了能够进一步获得程序的调试信息,我们可以在代码中加入一些调试函数,这样在模拟器这边可以获得更多程序运行信息了。具体的调试信息添加可以参考样例程序,本文就不进行详细描述了。,Page 30,模块一体化接口函数嵌入,程序写到这,我想大家应该已经清楚了整个状态机的运行机制,即只要向状态机发送相应的事件就行。根据模块提供的一些接口函数,我们可以定义不同的事件,以此达到状态切换的目的。函数文件为user.c/user.h,Page 31,编译,用户程序用到了一些state提供的链接库,而我们编译的时候需要这些库的源文件,因此别忘了把这些文件也复制到相关目录下。主要文件有sme.c、sme.h、sme_debug.h,谢谢!,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号