第2章:开发环境搭建
好,咱们正式开始动手了。这一章我带你把开发环境搭起来。说实话,QNX的开发环境搭建,比Linux要繁琐一些,但也没那么玄乎。我当年第一次接触QNX时,光配交叉编译链就折腾了一下午。现在回想起来,其实就是几个关键点没搞明白。
2.1 QNX Momentics IDE安装
QNX Momentics IDE,说白了就是一套基于Eclipse的集成开发环境。QNX官方把它打包好了,你直接装就行。我个人习惯用7.0或7.1版本,这两个版本比较稳定。
安装步骤:
- 从QNX官网下载Momentics IDE安装包(需要注册账号)
- 运行安装程序,选择安装路径(建议不要有中文和空格)
- 选择组件:至少勾选“QNX SDK”和“Target Support”
- 等待安装完成,大概10-15分钟
嗯,这里要注意:安装路径别太深。我曾经把QNX装在一个很深的目录下,结果编译时路径超长报错,排查了半天才发现是这个问题。
2.2 QNX SDK配置
SDK配置是重头戏。QNX的SDK包含了头文件、库文件、以及最重要的——系统镜像。你想想看,没有SDK,你连printf都调不了。
配置SDK其实就两步:
- 设置环境变量:主要是QNX_HOST和QNX_TARGET
- 导入SDK到IDE:在Momentics里通过Preferences -> QNX -> SDK Manager导入
我建议你直接在.bashrc或.profile里加上这几行:
export QNX_HOST=/opt/qnx710/host/linux/x86_64
export QNX_TARGET=/opt/qnx710/target/qnx7
export PATH=$QNX_HOST/usr/bin:$PATH
export MAKEFLAGS=-j4
为什么要加MAKEFLAGS?因为QNX的make默认单线程编译,加上-j4能快不少。我在项目中遇到过,不加这个参数,编译一个稍大的工程要等好几分钟。
2.3 交叉编译工具链
交叉编译,说白了就是在你的PC上编译出能在ARM或x86目标板上运行的代码。QNX的工具链命名很直观:
| 目标架构 | 编译器名称 | 常见用途 |
|---|---|---|
| ARMv7 | arm-unknown-nto-qnx7.0.0eabi-gcc | i.MX6、AM335x等 |
| ARMv8 (AArch64) | aarch64-unknown-nto-qnx7.0.0-gcc | 树莓派3/4、i.MX8 |
| x86_64 | x86_64-pc-nto-qnx7.0.0-gcc | QNX虚拟机、x86工控机 |
怎么验证工具链是否可用?我一般写个最简单的hello world:
#include <stdio.h>
int main() {
printf("Hello from QNX!\n");
return 0;
}
然后用交叉编译器编译:
aarch64-unknown-nto-qnx7.0.0-gcc -o hello hello.c
如果没报错,生成了hello文件,那就说明工具链没问题。我曾经犯过一个低级错误——用错了编译器版本,编译出来的程序在目标机上跑不起来,报“Invalid ELF header”。后来才发现,目标机是ARMv7,我用了ARMv8的编译器。
避坑指南:一定要确认目标机的架构。用file命令查看编译出的二进制文件:
file hello
# 输出示例:ELF 64-bit LSB executable, ARM aarch64, ...
2.4 目标机与宿主机连接
环境搭好了,怎么把程序跑起来?你需要让宿主机(你的PC)和目标机(开发板)能通信。常用的方式有两种:
- 串口连接:调试内核、看启动日志时用
- 网络连接:传输文件、远程调试时用
我个人更推荐网络连接,速度快,还能用ssh。配置网络连接时,你需要知道目标机的IP地址。怎么获取?
- 用串口连上目标机,登录后执行
ifconfig - 或者,在QNX启动时,串口输出里会打印IP地址
拿到IP后,在宿主机上测试连通性:
ping 192.168.1.100
通了之后,就可以用QNX的qconn服务来远程调试了。在Momentics IDE里,新建一个QNX Target,填上IP地址和端口(默认8000),IDE就能自动识别目标机。
小技巧:如果网络不通,先检查防火墙。我遇到过好几次,Windows防火墙把QNX的端口给拦了。把8000端口放行就好了。
2.5 验证环境
最后一步,验证整个环境是否正常工作。我习惯写一个简单的多线程程序来测试:
#include <stdio.h>
#include <pthread.h>
void* thread_func(void* arg) {
printf("Thread running on QNX!\n");
return NULL;
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);
pthread_join(tid, NULL);
printf("Main done.\n");
return 0;
}
编译后传到目标机上运行。如果能看到两行输出,恭喜你,环境搭建成功了!
嗯,这一章的内容就这些。环境搭建虽然繁琐,但一次配好,后面就省心了。下一章我们开始讲QNX的进程管理,那才是真正有意思的部分。