2、QNX开发环境搭建:QNX Momentics IDE安装、QNX SDP配置、交叉编译工具链、目标机与宿主机连接
说实话,很多刚接触QNX的朋友,第一步就被环境搭建给卡住了。我当年第一次搭QNX开发环境时,光是把IDE跑起来就折腾了大半天。后来做项目多了,才发现其实流程很清晰,只是有些细节容易被忽略。
这一章,我就带你一步步把环境搭好。咱们的目标很简单:让宿主机(你的电脑)能编译代码,让目标机(开发板)能跑起来,并且两者能愉快地通信。
2.1 QNX Momentics IDE安装
QNX Momentics IDE,说白了就是基于Eclipse的一套集成开发环境。它把编辑器、编译器、调试器、性能分析工具都打包在一起了。我个人习惯用IDE来写代码和调试,效率确实高。
2.1.1 获取安装包
你需要从BlackBerry的QNX官网下载安装包。注意,不同版本的QNX SDP对应不同的IDE版本。我建议你直接用SDP 7.0或7.1,这两个版本比较稳定。
- QNX SDP 7.0:对应Momentics IDE 7.0
- QNX SDP 7.1:对应Momentics IDE 7.1
- QNX SDP 8.0:较新,但部分旧驱动库可能不兼容
嗯,这里要注意:IDE版本必须和SDP版本匹配。我曾经见过有人装了SDP 7.1却用IDE 7.0,结果编译出来的二进制文件在目标机上跑不起来,排查了半天才发现是版本不匹配。
2.1.2 安装步骤
安装过程其实很简单,但有几个坑我得提前告诉你:
- 解压安装包:下载下来的是一个tar.gz文件。在Linux上直接解压就行。
- 运行安装脚本:进入解压后的目录,执行
./install。它会启动图形化安装向导。 - 选择安装路径:我建议不要用默认路径,而是放在
/opt/qnx下。这样后续管理多个版本方便。 - 选择组件:全选就行,别省那点硬盘空间。摄像头驱动开发需要用到很多库和头文件。
2.2 QNX SDP配置
SDP(Software Development Platform)是QNX的软件开发平台。它包含了编译器、链接器、库文件、头文件等所有你需要的东西。安装完IDE后,第一件事就是配置SDP。
2.2.1 设置环境变量
这是最关键的一步。你需要告诉系统,QNX的工具链在哪里。我个人习惯把下面这段加到 ~/.bashrc 里:
# QNX SDP 7.1 环境变量
export QNX_HOST=/opt/qnx/qnx710/host/linux/x86_64
export QNX_TARGET=/opt/qnx/qnx710/target/qnx7
export PATH=$QNX_HOST/usr/bin:$PATH
export MAKEFLAGS=-j4
为什么要设这些变量?QNX_HOST 指向宿主机上的工具链,QNX_TARGET 指向目标机上的库和头文件。说白了,编译时用的工具在 QNX_HOST 里,运行时需要的库在 QNX_TARGET 里。
重点:每次打开新终端,都要先 source ~/.bashrc 或者重新登录。不然编译器会报 "command not found"。
2.2.2 验证SDP配置
配置完环境变量后,验证一下是否生效:
which qcc
# 应该输出:/opt/qnx/qnx710/host/linux/x86_64/usr/bin/qcc
qcc --version
# 应该显示QNX编译器的版本信息
如果 qcc 找不到,说明环境变量没设对。检查一下路径是否存在。
2.3 交叉编译工具链
交叉编译,说白了就是在你的电脑(x86架构)上编译出能在ARM开发板上运行的代码。QNX用的是自己定制的GCC编译器,叫 qcc。
2.3.1 理解qcc与gcc的区别
你可能会问:为什么不用标准的gcc?原因很简单——QNX有自己的C库和系统调用。标准gcc编译出来的程序,在QNX上根本跑不起来。
qcc 其实是对底层gcc的一层封装。它会自动帮你指定正确的头文件路径、库路径和链接参数。你想想看,如果每次编译都要手动加一堆 -I 和 -L 参数,那得多痛苦。
2.3.2 编译第一个QNX程序
来,写个简单的Hello World试试:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Hello from QNX!\n");
return EXIT_SUCCESS;
}
编译命令很简单:
qcc -Vgcc_ntoaarch64le hello.c -o hello
这里 -Vgcc_ntoaarch64le 指定了目标架构。aarch64le 就是64位ARM小端模式。如果你用的是32位ARM,就改成 gcc_ntoarmv7le。
file hello 命令检查编译出来的二进制文件。如果显示 "ELF 64-bit LSB executable, ARM aarch64",说明交叉编译成功了。如果显示 "x86-64",那说明你忘了加 -V 参数。
2.3.3 常用编译选项
做摄像头驱动开发时,我常用的编译选项有这些:
| 选项 | 说明 | 示例 |
|---|---|---|
-V |
指定目标架构 | -Vgcc_ntoaarch64le |
-O2 |
优化级别,驱动一般用O2 | -O2 |
-g |
添加调试信息 | -g |
-D |
定义宏,常用于条件编译 | -DDEBUG=1 |
-I |
添加头文件搜索路径 | -I./include |
-L |
添加库文件搜索路径 | -L./lib |
-l |
链接库文件 | -lcamera |
2.4 目标机与宿主机连接
环境搭好了,代码也能编译了。下一步就是让目标机(开发板)和宿主机(你的电脑)连起来。QNX支持多种连接方式,我重点讲最常用的两种:网络连接和串口连接。
2.4.1 网络连接(推荐)
网络连接是最方便的方式。你可以通过SSH登录到目标机,也可以用QNX的 qconn 服务进行通信。
第一步:配置目标机IP
在目标机上,用 ifconfig 查看或设置IP地址:
# 查看当前网络状态
ifconfig
# 设置静态IP(假设网口是 en0)
ifconfig en0 192.168.1.100 netmask 255.255.255.0 up
第二步:启动qconn服务
qconn 是QNX的远程连接服务。IDE就是通过它来调试目标机的:
# 启动qconn服务
qconn &
# 验证是否启动成功
pidin | grep qconn
第三步:在IDE中配置目标机
打开Momentics IDE,点击菜单栏的 Window → Show View → Target Navigator。然后在空白处右键,选择 New QNX Target。填入目标机的IP地址和端口(默认是8000)。
注意:宿主机和目标机必须在同一个网段。如果连不上,先 ping 一下目标机的IP。我遇到过很多次,问题出在防火墙把8000端口给封了。
2.4.2 串口连接(备用方案)
有时候网络环境受限,或者目标机还没配好网络,串口就是救命稻草。串口连接虽然慢,但胜在稳定可靠。
宿主机端配置:
# 安装串口终端工具(Linux)
sudo apt-get install minicom
# 配置minicom
minicom -s
# 设置串口参数:
# 波特率:115200
# 数据位:8
# 停止位:1
# 校验位:无
目标机端配置:
在QNX系统启动时,串口默认就是控制台。你只需要用串口线连接开发板的UART口和电脑的USB转串口适配器就行。
2.4.3 文件传输
代码编译好了,怎么传到目标机上?我常用两种方式:
方式一:scp(基于SSH)
# 从宿主机传到目标机
scp hello qnxuser@192.168.1.100:/home/qnxuser/
# 从目标机传到宿主机
scp qnxuser@192.168.1.100:/home/qnxuser/log.txt .
方式二:mount(网络文件系统)
这种方式更高级——直接把目标机的目录挂载到宿主机上:
# 在宿主机上执行
mount -t nfs 192.168.1.100:/home/qnxuser /mnt/qnx_target
挂载后,你在 /mnt/qnx_target 里放文件,目标机上立刻就能看到。调试驱动时特别方便,不用反复scp。
sync 命令强制刷新缓存,或者挂载时加 -o noac 参数禁用属性缓存。
2.5 验证环境是否搭建成功
最后,我们来验证一下整个环境是否正常工作。写一个简单的测试程序,编译后传到目标机上运行:
# 宿主机上编译
qcc -Vgcc_ntoaarch64le -o test_env test_env.c
# 传到目标机
scp test_env qnxuser@192.168.1.100:/tmp/
# SSH登录目标机并运行
ssh qnxuser@192.168.1.100
cd /tmp
./test_env
如果看到程序正常输出,恭喜你——环境搭建成功了!
嗯,到这里,QNX开发环境就全部搭好了。下一章,我们会正式开始写摄像头驱动。到时候你会发现,今天花时间把环境搭扎实了,后面写代码会顺畅很多。