一天精通无人机第 23 讲 中级篇系列:创建并运行多进程程序

file

一、基于Linux的进程创建

我们已经在上一节中学习了进程的运行原理,在本节中我们来一起来学习如何在实际编程中创建一个可运行的进程。首先我们来编写一个普通的程序,打开一个文本编译器并在其中输入如下内容:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }
    return 0;
}

之后将其保存为main.c并使用gcc进行编译:

gcc -o main -std=gnu11 main.c

这样就在当前目录下生成了一个叫做main的可执行程序。注意此时的程序还只是一个普通的可执行文件,在操作系统没有执行它之前,它只做为一个普通的文件存放在了计算机的外部存储器上(硬盘),当我们执行了./main之后,操作系统会将main文件的内容载入内存,并为其分配PCB和任务ID号,并为其分配相关数据段内存和代码段内存,最后操作系统使处理器开始执行此程序的代码段程序,于是此可执行文件就成为了一个正在运行的进程。

file

我们再通过一个简单的操作来测试一下操作系统对可执行程序并行执行过程,我们可以打开两个可执行的终端窗口,并先后执行两次./main可执行文件:

file

我们可以清楚的看到,同一个可执行文件main被执行了两次,操作系统为其创建了两个进程,它们的运行过程在操作系统的调度下, 它们在并行的执行程序内容,它们的ID号分为27278和27336:

lidq     27278  0 11:34 pts/0    00:00:00 ./main
lidq     27336  0 11:34 pts/1    00:00:00 ./main

二、飞控程序创建进程

接下来我们来编写一个PX4飞控程序的进程,我们首先要在PX4架构中创建一个模块,创建模块的过程与创建驱动程序的过程一致。在这里我们在modules中创建一个更通用的模块:

  1. 在cmake/configs/nuttx_px4fmu-v3_default.cmake中加添一个测试模块process_test:

file

  1. 在src/modules中创建一个process_test文件夹,并在其中创建一个CMakeList.txt文件,其内容如下:
px4_add_module(
    MODULE modules__process_test
    MAIN process_test
    COMPILE_FLAGS
    STACK_MAIN 1200
    SRCS
        process_test.c
    DEPENDS
)
  1. 在src/modules/process_test中创建一个process_test.c文件,并在其中加入以下内容:
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }
    return 0;
}

之后编译并运行飞控程序,在nsh shell / console 调试串口中即可进入nsh命令窗口,输入process_test即可查看到程序的运行结果。

file

三、后台运行进程

此程序在运行时即占用nsh shell(本身也是一个进程)的输入输出,所以在process_test运行过程中nsh>界面中不能再输入任何内容的命令,所以我们需要使程序在后台运行在运行过程中不影响nsh shell的正常运行,所以我们需要在process_test_main()函数中加入px4的进程创建函数:

/** Starts a task and performs any specific accounting, scheduler setup, etc. */
px4_task_t px4_task_spawn_cmd(const char *name,
                       int scheduler,   
                       int priority,
                       int stack_size,
                       px4_main_t entry,
                       char *const argv[]);

我们再来重新修改一下程序:

#include <unistd.h>
#include <px4_config.h>
#include <px4_defines.h>
#include <px4_tasks.h>

int process_test_main(int argc, int *argv[]);
int process_test_task(int argc, int *argv[]);

int process_test_task(int argc, int *argv[])
{
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }
    return 0;
}

int process_test_main(int argc, int *argv[])
{
    px4_task_spawn_cmd("process_test", SCHED_DEFAULT, 100, 2048,
            (px4_main_t) process_test_task, (char * const *) argv);

    return 0;
}

file

重新编译程序并运行process_test程序在运行过程中即可做为一个单独进程运行在nsh的后台中,事实上PX4的所有进程都是以这种方式运行的,飞控启动时所运行的进程都定义在ROMFS/px4fmu_common/init.d/rcS中。

下期预告:《中级篇:创建并运行多线程》

file