构建基于Linux的嵌入式应用的一点想法
一. 尽可能少的修改Linux系统的代码。
比较理想的情况是,只修改一行代码。
例如,在 /etc/rc.local脚本的最后,增加一行代码,那就是“/path/to/my_app/start.sh”。通过这一行代码就进入了我们的应用的世界。
这样的修改就很干净,而且这样的修改也很稳定,以后也基本不需要再有什么变化。
二. 不要直接启动我们的应用程序
注意,前一节启动的start.sh还不是我们的应用程序。他相当于用于发射火箭的发射架。start.sh中,可能会做很多准备工作,例如,驱动模块的加载,文件系统的mount,硬件是否就绪的检测,相关文件夹的创建,时间的同步,当前工作目录的设置等等。这些只是在应用启动时执行一次的工作,放在start.sh中做,是比较方便的。如果放在应用程序中做,不仅实现起来麻烦,维护起来也不方便(稍有变动,就得修改编译应用程序的代码)。
三. start.sh的最后一行干什么
start.sh在前面做了各种准备工作。这些都做完了,还要干什么呢?当然是拉起我们的应用程序。但是,如果想让系统的可靠性好一点的话,这里还是不要直接拉起最终的应用程序。而是拉起一个守护程序,例如,Daemon.exe。
Daemon.exe的实现逻辑要超级简单。简单到什么程度呢?简单到几乎不可能有任何bug。只有这样简单的代码,才经得起积年累月的运行而不崩溃。
那么Daemon.exe的任务究竟是什么呢?启动时,从配置文件中读取一个程序列表。将列表中的程序一个个拉起来。然后进入一个循环,监视列表中的程序有没有退出的。一旦遇到退出的程序,就再将他拉起来。
四. 应用程序的实现
上一节中,由Daemon.exe拉起来的程序列表中的程序,才是我们真正的应用程序。他可能由一个或多个可执行程序构成。这些程序的设计要注意什么呢?
1. 尽可能提供一些命令行选项
例如,-m 5 -d 等。这样,允许我们不用修改代码就能改变系统特性。UNIX中的很多实用程序,基本都支持命令行选项。说到这里,再提一点。如果不是写临时性的非正式程序,最好不要直接使用argv[1]、argv[2]等来获得控制程序的命令行参数。因为这样做,用户就得按照顺序输入各个参数,这就会带来记忆的麻烦。另外,如果程序所需的参数个数发生了变化,可能会造成参数的输入顺序也得跟着变。
2. 通过配置文件提供丰富的特性控制
这样做,主要是提供给用户更大的灵活性。凡是容易有变化的地方,都做成配置项,放到配置文件中。程序根据配置文件的内容,决定应该如何表现。这样能更好的适应用户的需求。
也符合UNIX程序设计的哲学,程序提供的是机制,策略的事交给用户。
3. 核心程序要具有在运行时重新加载配置的能力
程序在启动时,通过配置文件读取了用户的配置,并且跑起来了。如果后面用户改变了配置,怎么办呢?有人可能想,把程序关掉,重新启动一下。对不起,有些高要求的场合是不允许这么搞地。例如,有些核心的程序,通过管道或socket为其他进程提供服务。核心程序挂了,会给使用他的服务的诸多进程造成很大麻烦。所以,核心程序不能挂。当然,使用核心程序的服务的程序可以挂。再例如,有些场合可能需要提供7*24小时不间断的服务。这个不间断,可能是几秒钟都不行哦。因此,核心程序在运行时能够重新加载配置,还是很重要的。