PX4源码开发人员文档(四)——创建后台程序(应用)

xiaoxiao2021-02-28  98

origin: http://blog.csdn.net/lkk05/article/details/48659059

Unix和其他多任务计算机操作系统中,后台程序是指,作为后台进程运行的计算机,而不是由交互用户直接控制。

后台程序概念的主要好处是,后台程序可以直接启动,而不需要将其发送到精确的用户或者shell的后台(然而,这不适用于Nuttx),其状态可以在运行的时候,通过shell查询。也可以终止。

Step 1: 创建一个小的标准应用

根据 FirstOnboard Application Tutorial (Hello Sky)教程(见PX4源码开发人员文档(二)),这是一个基本程序(简化):

[cpp] view plain copy ..  __EXPORT int px4_daemon_app_main(int argc, char *argv[]);  ..  int px4_daemon_app_main(int argc, char *argv[])  {      while (true) {          warnx("Hello Daemon!\n");          sleep(1);      }      return 0;  }  

这个应用的问题非常明显,如果不使用&启动,将会阻塞shellNuttx,并不如此,并且会出于small footprint和可靠性的原因,支持CTRL-Z / fg / bg)。为了回避这个问题,下面部分将应用转换为一个后台程序。

Step 2: 创建后台进程管理函数

主函数由后台进程管理函数替代,旧的主函数的内容现在位于后台任务/进程中

[cpp] view plain copy #include <systemlib/systemlib.h>     ..  __EXPORT int px4_daemon_app_main(int argc, char *argv[]);  ..  int mavlink_thread_main(int argc, char *argv[]);  ..  int mavlink_thread_main(int argc, char *argv[])  {      while (true) {          warnx("Hello Daemon!\n");          sleep(1);          if (thread_should_exit) break;      }         return 0;  }  ..  int px4_daemon_app_main(int argc, char *argv[])  {      if (argc < 1)          usage("missing command");         if (!strcmp(argv[1], "start")) {             if (thread_running) {              warnx("daemon already running\n");              /* this is not an error */              exit(0);          }             thread_should_exit = false;          daemon_task = task_spawn_cmd("daemon",                           SCHED_RR,                           SCHED_PRIORITY_DEFAULT,                           4096,                           px4_daemon_thread_main,                           (argv) ? (const char **)&argv[2] : (const char **)NULL);          thread_running = true;          exit(0);      }         usage("unrecognized command");      exit(1);  }  

这将会启动一个新的任务,具有4096字节的堆栈,并传递非后台程序的具体指令行选项到后台主函数。典型的调用如下所示:

[plain] view plain copy px4_daemon_app start  

上面的代码没有报告状态,并且没有对多次调用后台进程进行保护。

Step 3: 添加停止/状态指令以及安全保护

具有合适的启动/停止/状态建立和附加安全保护的完整px4_daemon_app代码如下:

[cpp] view plain copy /**  * @file px4_daemon_app.c  * daemon application example for PX4 autopilot  *  * @author Example User <mail@example.com>  */     #include <stdio.h>  #include <stdlib.h>  #include <string.h>  #include <unistd.h>     #include <px4_config.h>  #include <nuttx/sched.h>     #include <systemlib/systemlib.h>  #include <systemlib/err.h>     static bool thread_should_exit = false;     /**< daemon exit flag */  static bool thread_running = false;     /**< daemon status flag */  static int daemon_task;             /**< Handle of daemon task / thread */     /**  * daemon management function.  */  __EXPORT int px4_daemon_app_main(int argc, char *argv[]);     /**  * Mainloop of daemon.  */  int px4_daemon_thread_main(int argc, char *argv[]);     /**  * Print the correct usage.  */  static void usage(const char *reason);     static void  usage(const char *reason)  {      if (reason) {          warnx("%s\n", reason);      }         warnx("usage: daemon {start|stop|status} [-p <additional params>]\n\n");  }     /**  * The daemon app only briefly exists to start  * the background job. The stack size assigned in the  * Makefile does only apply to this management task.  *  * The actual stack size should be set in the call  * to task_create().  */  int px4_daemon_app_main(int argc, char *argv[])  {      if (argc < 2) {          usage("missing command");          return 1;      }         if (!strcmp(argv[1], "start")) {             if (thread_running) {              warnx("daemon already running\n");              /* this is not an error */              return 0;          }             thread_should_exit = false;          daemon_task = px4_task_spawn_cmd("daemon",                           SCHED_DEFAULT,                           SCHED_PRIORITY_DEFAULT,                           2000,                           px4_daemon_thread_main,                           (argv) ? (char *const *)&argv[2] : (char *const *)NULL);          return 0;      }         if (!strcmp(argv[1], "stop")) {          thread_should_exit = true;          return 0;      }         if (!strcmp(argv[1], "status")) {          if (thread_running) {              warnx("\trunning\n");             } else {              warnx("\tnot started\n");          }             return 0;      }         usage("unrecognized command");      return 1;  }     int px4_daemon_thread_main(int argc, char *argv[])  {         warnx("[daemon] starting\n");         thread_running = true;         while (!thread_should_exit) {          warnx("Hello daemon!\n");          sleep(10);      }         warnx("[daemon] exiting.\n");         thread_running = false;         return 0;  }  

代码测试将会产生如下的输出:

[plain] view plain copy nsh> px4_daemon_app start  [daemon] starting  Hello Daemon!  

为了使用这一APP,只需在Firmware/makefiles/config_px4fmu_default.mk中,取消对这一示例部分的注释。

转载请注明原文地址: https://www.6miu.com/read-27749.html

最新回复(0)