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