物联网操作系统HelloX应用编程指南

  HelloX应用开发概述

  可以通过三种方式,在HelloX操作系统基础上开发应用:

  1. 以内部命令方式实现应用,直接编译链接到HelloX的内核shell中。这时候应用代码的执行上下文,是shell线程的上下文。应用程序代码不会单独成为一个独立的线程;

  2. 以外部命令方式实现应用。直接编译链接到HelloX的内核中,通过shell来启动应用。这时候的应用,内核会创建一个独立的线程来承载;

  3. 以外部应用方式实现应用。应用代码单独编译链接,完成后存放在安装了HelloX操作系统的计算机存储设备中。在shell下,使用loadapp命令,加载可执行的应用模块。这种方式下,应用代码也是在一个独立的线程中执行的。需要注意的是,在这种方式下,应用代码只能调用HelloX SDK提供的API接口函数和C库函数。

  本文主要对第一种和第二种实现方式进行说明。

  以内部命令方式实现应用

  内部命令采用映射表的方式,使系统功能的添加和删除变得比较容易。比如要添加一个功能,只需要写一个处理函数,然后在HelloX的内部命令射表内添加一个项目即可。下面我们通过一个示例来说明如何往系统中添加新的功能。

  第一步:假设新增的功能命令为mycommand,首先编写一个功能函数,可以直接在SHELL.CPP文件中添加,也可以通过另外的模块实现,然后在SHELL.CPP中,包含实现的命令函数的头文件。假设mycommand命令的实现函数如下。

  VOID mycommand(LPSTR)

  {

  ChangeLine();

  PrintLine("Hello,World!");

  ChangeLine();

  }

  该函数的功能十分简单,打印出“Hello,World!”字符串,这也是大多数编程语音的一个入门示例。

  第二步:把该命令字符串和命令函数添加到内部命令列表中,并更改CMD_OBJ_NUM宏为原来的值加一,因为新增加了一个内部命令。代码如下(黑体部分是修改内容):

  //#define CMD_OBJ_NUM 21

  #defineCMD_OBJ_NUM 22

  __CMD_OBJ CmdObj[CMD_OBJ_NUM] = {

  {"version" , VerHandler},

  {"memory" , MemHandler},

  {"sysinfo" , SysInfoHandler},

  {"sysname" , SysNameHandler},

  {"help" , HlpHandler},

  {"cpuinfo" , CpuHandler},

  {"support" , SptHandler},

  {"runtime" , RunTimeHandler},

  {"test" , TestHandler},

  {"untest" , UnTestHandler},

  {"memview" , MemViewHandler},

  {"ktview" , KtViewHandler},

  {"ioctrl" , IoCtrlApp},

  {"sysdiag" , SysDiagApp},

  {"loadapp" , LoadappHandler},

  {"gui" , GUIHandler},

  {"reboot" , Reboot},

  {"poff" , Poweroff},

  {"cls" , ClsHandler},

  {“mycommand”, mycommand}

  };

  第三步:重新编译连接(rebuild)整个操作系统核心,并重新制作引导盘引导系统。成功启动后,在命令行提示符下,输入mycommand并回车,就可以看到mycommand的输出了。

  需要注意的是,内部命令是直接在shell线程上下文中被调用的,没有自己独立的执行环境。因此只适合于实现较为简单的功能。

  以外部命令方式实现应用

  外部命令则会有独立的执行上下文,被内核以独立线程方式加载运行。因此,外部命令的功能非常强大,可以进一步以子命令的方式,实现更进一步的功能。比如,HelloX的网络诊断功能,就是以外部命令方式实现的。用户在shell界面下,输入network后回车,即可进入network诊断命令。这时候系统提示符会改变。在network命令下,输入help命令,可以看到该命令模式下所有可用的子命令,如下图:

  其中iflist,ping等就是network应用下的子命令。在执行子命令的时候,用户可以指定参数,HelloX会以一种统一的方式,把用户指定的参数,传递给命令处理函数。

  下面以network诊断外部命令的实现为例,说明外部命令的实现方式。

  第一步:编写外部命令的入口处理函数。

  以network命令为例,要编写类似下列形式的处理函数:

  DWORD networkEntry(LPVOID p)

  {

  return Shell_Msg_Loop(NETWORK_PROMPT_STR,CommandParser,QueryCmdName);

  }

  具体的处理函数的实现,就是开发者大显神通的地方。比如要实现子命令,则需要定义一些子命令映射列表等信息。在上面的实现中,是一个消息处理循环,根据用户的输入,来调用特定的子命令。