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,生态更成熟。
安装步骤:
- 从BlackBerry官网或QNX客户门户下载SDP安装包(大约2-3GB)。
- 在Linux主机上执行安装脚本:
chmod +x qnx-sdp-7.0.0-xxxxxxxxx-linux64.run
sudo ./qnx-sdp-7.0.0-xxxxxxxxx-linux64.run
注意,这里要用sudo。我遇到过有人用普通用户装,结果后面编译时权限报错,折腾半天才发现是安装目录权限不对。
- 安装路径建议选
/opt/qnx700,别用带空格的路径,否则后面Momentics IDE会报一些莫名其妙的错。 - 安装完成后,设置环境变量:
export QNX_HOST=/opt/qnx700/host/linux/x86_64
export QNX_TARGET=/opt/qnx700/target/qnx7
export PATH=$QNX_HOST/usr/bin:$PATH
最好把这几个变量写到~/.bashrc里,省得每次开终端都要重新设。
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项目:
配好之后,咱们建个测试项目试试手:
- File → New → QNX Project → QNX C/C++ Project
- 项目类型选「QNX Executable」
- Target Architecture选你的目标板架构(比如ARMv7或AArch64)
- Finish
IDE会自动生成一个Hello World模板。你直接编译,如果没报错,说明环境搭好了。
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为例,步骤是这样的:
- 从QNX官网下载RPi4的BSP包(通常是一个
.img文件) - 用
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卡给写了,结果...嗯,你们懂的。
- 插卡、上电、接串口线(或用HDMI接显示器)
- 启动后你会看到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个线程都打印了消息,恭喜你,环境搭建成功!
libc.so.7找不到。原因是目标板上的QNX版本和SDP版本不一致。解决办法:确保目标板的BSP版本和SDP版本匹配。比如SDP 7.0就配BSP 7.0,别混用。
好了,环境搭建就到这里。下一章咱们开始真正进入虚拟化技术,我会带你写第一个虚拟机监视器(VMM)程序。到时候你会看到,QNX的虚拟化跟Linux的KVM完全是两码事。