1. QNX Momentics 开发环境搭建与首个 Neutrino 程序
任务目标
在QNX Neutrino实时操作系统上,从零创建一个C语言进程:编写源码、使用qcc编译、部署到目标机并运行,观察进程从创建到退出的完整生命周期。
环境准备
- QNX SDP(Software Development Platform)7.0或7.1,安装在宿主机(Windows/Linux)
- QNX目标机(或QNX虚拟机),与宿主机网络互通
- 宿主机与目标机已配置好
qconn连接,或可通过SSH/FTP传输文件
完整实现
创建文件first_process.c,代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/procfs.h>
#include <process.h>
int main(int argc, char *argv[]) {
pid_t pid = getpid();
pid_t ppid = getppid();
printf("进程启动: PID=%d, 父进程PPID=%d\n", pid, ppid);
printf("命令行参数: argc=%d\n", argc);
for (int i = 0; i < argc; i++) {
printf(" argv[%d] = %s\n", i, argv[i]);
}
// 获取进程名称(来自 /proc/self 的进程信息)
char name[64] = {0};
procfs_processinfo_t info;
DIR *dir = opendir("/proc/self");
if (dir) {
// 简化方式:直接读取进程名
FILE *f = fopen("/proc/self/name", "r");
if (f) {
fgets(name, sizeof(name), f);
fclose(f);
}
closedir(dir);
}
printf("进程名称: %s", name[0] ? name : "(读取失败)\n");
printf("进程进入运行状态,休眠2秒模拟工作...\n");
sleep(2);
printf("进程准备退出,返回码=0\n");
return 0;
}
编译与部署
在宿主机QNX SDP的Bash环境中执行以下命令:
# 编译(生成x86_64目标文件)
qcc -Vgcc_ntox86_64 -o first_process first_process.c
# 查看生成的文件类型
file first_process
# 传输到目标机(假设目标机IP为192.168.1.100)
scp first_process qnxuser@192.168.1.100:/tmp/
若目标机为ARM架构(如i.MX8),将gcc_ntox86_64替换为对应的gcc_ntoarmv7le或gcc_ntoaarch64le。
运行与验证
在目标机终端执行:
# 添加执行权限并运行
chmod +x /tmp/first_process
/tmp/first_process arg1 arg2
预期输出(与代码逻辑严格对应):
进程启动: PID=4105, 父进程PPID=1
命令行参数: argc=3
argv[0] = /tmp/first_process
argv[1] = arg1
argv[2] = arg2
进程名称: first_process
进程进入运行状态,休眠2秒模拟工作...
进程准备退出,返回码=0
验证通过条件:
- 程序输出完整的生命周期信息:启动(含PID/PPID)→ 参数解析 → 运行中 → 退出
- 在程序休眠的2秒内,在目标机另开终端执行
pidin | grep first_process,能看到该进程处于RUN状态 - 程序退出后再次执行
pidin | grep first_process,无输出,证明进程已终止 - 执行
echo $?显示返回码为0
进程生命周期说明
QNX进程生命周期包含四个阶段:创建(由fork/exec或spawn触发)、就绪/运行(调度器分配CPU)、阻塞/等待(如sleep)、退出(调用exit或return)。本案例通过getpid()获取内核分配的PID,通过sleep()制造阻塞状态,通过return 0触发正常退出,完整覆盖了进程从生到死的路径。
若需观察进程退出时的状态码,可在目标机执行waitpid工具或使用tracelogger跟踪系统调用,但本案例通过$?已能确认退出码。