2. 开发环境搭建:QNX SDP安装、QNX Momentics IDE配置、目标板与模拟器准备

好,咱们正式开始动手了。这一章我带你把开发环境搭起来。说实话,很多初学者觉得环境搭建就是「下一步、下一步」的事,但QNX这套东西跟Linux、Windows不太一样,坑不少。我当年第一次装SDP的时候,就因为少装了一个依赖,折腾了大半天。咱们今天一步到位,把这事捋清楚。

2.1 QNX SDP 安装:别小看这一步

QNX Software Development Platform(SDP)是整个开发的基础。它包含了编译器、链接器、调试器、头文件、库文件,还有最重要的——BSP(板级支持包)。

版本选择:我个人习惯用QNX SDP 7.0或7.1。7.0比较稳定,7.1对ARMv8的支持更好。如果你做车规级项目,建议用7.0,生态更成熟。

安装步骤

  1. 从BlackBerry官网或QNX客户门户下载SDP安装包(大约2-3GB)。
  2. 在Linux主机上执行安装脚本:
chmod +x qnx-sdp-7.0.0-xxxxxxxxx-linux64.run
sudo ./qnx-sdp-7.0.0-xxxxxxxxx-linux64.run

注意,这里要用sudo。我遇到过有人用普通用户装,结果后面编译时权限报错,折腾半天才发现是安装目录权限不对。

  1. 安装路径建议选/opt/qnx700,别用带空格的路径,否则后面Momentics IDE会报一些莫名其妙的错。
  2. 安装完成后,设置环境变量:
export QNX_HOST=/opt/qnx700/host/linux/x86_64
export QNX_TARGET=/opt/qnx700/target/qnx7
export PATH=$QNX_HOST/usr/bin:$PATH

最好把这几个变量写到~/.bashrc里,省得每次开终端都要重新设。

注意:QNX SDP不支持Windows原生安装。你必须在Linux或macOS上装。如果你只有Windows,那就装个虚拟机,跑Ubuntu 18.04或20.04。我试过Ubuntu 22.04,也能用,但有些老版本的BSP可能不兼容。

2.2 QNX Momentics IDE 配置:你的主战场

Momentics IDE是基于Eclipse的。说白了,它就是QNX版的「VS Code」。但别被它Eclipse的外表骗了,它集成了QNX特有的调试器、系统分析器、性能剖析工具,这些是普通Eclipse没有的。

安装IDE

SDP安装包里其实已经包含了IDE。你到/opt/qnx700/ide目录下,运行qde启动脚本就行:

/opt/qnx700/ide/qde

第一次启动会问你工作空间(workspace)路径。我建议单独建一个目录,比如~/qnx_workspace,别跟其他项目混在一起。

配置交叉编译器

IDE启动后,需要告诉它你的工具链在哪。操作路径:

  • Window → Preferences → QNX → QNX Toolchain
  • 点击「Add」,选择你的SDP安装路径(比如/opt/qnx700
  • IDE会自动识别出可用的架构(x86_64、ARM、AArch64等)

嗯,这里有个坑。如果你同时装了多个版本的SDP,IDE可能会搞混。我建议一次只配一个版本,用哪个配哪个。

创建第一个QNX项目

配好之后,咱们建个测试项目试试手:

  1. File → New → QNX Project → QNX C/C++ Project
  2. 项目类型选「QNX Executable」
  3. Target Architecture选你的目标板架构(比如ARMv7或AArch64)
  4. Finish

IDE会自动生成一个Hello World模板。你直接编译,如果没报错,说明环境搭好了。

小技巧:Momentics IDE的调试视图非常强大。你可以同时看CPU寄存器、内存、堆栈、线程状态。我调试多核虚拟化的时候,经常同时开4个调试实例,每个核一个,同步观察。这个功能普通GDB做不到。

2.3 目标板与模拟器准备:两手都要硬

做嵌入式开发,你总得有个跑代码的地方。要么是真机(目标板),要么是模拟器。我建议你两个都准备,因为各有各的用处。

2.3.1 目标板准备

QNX支持的板子很多,常见的有:

板卡型号 架构 适用场景
Raspberry Pi 3/4 ARMv8-A 入门学习、原型验证
TI AM572x ARM Cortex-A15 工业控制、多核实验
NXP i.MX8 ARM Cortex-A53/A72 车载、高端嵌入式
Intel x86_64 PC x86_64 开发调试、性能测试

我个人最推荐Raspberry Pi 4。便宜、好买、社区支持好。你花300块买个Pi 4,再配个TF卡,就能跑QNX了。

烧录BSP到目标板

以RPi4为例,步骤是这样的:

  1. 从QNX官网下载RPi4的BSP包(通常是一个.img文件)
  2. dd命令烧录到TF卡:
sudo dd if=qnx-rpi4-7.0.0.img of=/dev/sdX bs=4M status=progress
sync

注意/dev/sdX是你的TF卡设备名,千万别写错了。我有个同事曾经把/dev/sda(系统盘)当成TF卡给写了,结果...嗯,你们懂的。

  1. 插卡、上电、接串口线(或用HDMI接显示器)
  2. 启动后你会看到QNX的Shell提示符,说明BSP跑起来了

2.3.2 QNX模拟器(QEMU)

不是每个人都有目标板。而且说实话,开发阶段用模拟器效率更高——编译完直接跑,不用烧卡、不用插线。

QNX官方提供了基于QEMU的模拟器镜像。你可以在SDP安装目录下找到:

/opt/qnx700/target/qnx7/x86_64/usr/bin/qemu-system-x86_64

启动模拟器的命令:

qemu-system-x86_64 -m 2048 -smp 4 \
  -kernel /opt/qnx700/target/qnx7/x86_64/boot/sys/biosboot \
  -initrd /opt/qnx700/target/qnx7/x86_64/boot/sys/initrd \
  -append "root=/dev/ram0 console=ttyS0" \
  -serial stdio

这个命令启动了一个4核、2GB内存的虚拟QNX系统。你可以把它当成一台x86_64的目标机来用。

重点:模拟器和真机在行为上基本一致,但有两个区别要注意:
1. 模拟器的时钟精度不如真机,做实时性测试时要以真机为准。
2. 模拟器不支持某些硬件特性(比如硬件虚拟化扩展),做虚拟化开发时,最终还是要上真机验证。

2.4 验证环境:跑个Hello World试试

环境搭好了,咱们验证一下。写个简单的多线程程序,既能测试编译器,又能测试运行时环境:

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

void *thread_func(void *arg) {
    int id = *(int *)arg;
    printf("Thread %d: Hello from QNX!\n", id);
    return NULL;
}

int main() {
    pthread_t threads[4];
    int ids[4] = {0, 1, 2, 3};

    for (int i = 0; i < 4; i++) {
        pthread_create(&threads[i], NULL, thread_func, &ids[i]);
    }

    for (int i = 0; i < 4; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("All threads completed.\n");
    return 0;
}

在Momentics IDE里编译,然后通过IDE的「Run As → QNX Application」部署到模拟器或目标板上。如果看到4个线程都打印了消息,恭喜你,环境搭建成功!

避坑指南:我曾经在IDE里编译通过,但部署到目标板时报libc.so.7找不到。原因是目标板上的QNX版本和SDP版本不一致。解决办法:确保目标板的BSP版本和SDP版本匹配。比如SDP 7.0就配BSP 7.0,别混用。

好了,环境搭建就到这里。下一章咱们开始真正进入虚拟化技术,我会带你写第一个虚拟机监视器(VMM)程序。到时候你会看到,QNX的虚拟化跟Linux的KVM完全是两码事。