2. 开发环境搭建:QNX/Android Automotive SDK安装、交叉编译工具链配置、模拟器与真机调试环境搭建

说实话,座舱多屏开发的环境搭建,比普通手机应用开发要复杂不少。你想想看,要同时伺候QNX和Android两套系统,还要搞定交叉编译和调试环境。我刚开始接触这个领域时,光环境就折腾了一周。今天我把这些经验梳理出来,希望能帮你少走弯路。

核心要点:座舱开发环境的核心是“双系统并行”——QNX负责仪表和实时控制,Android Automotive负责中控和娱乐。两套工具链、两套SDK、两套调试方式,缺一不可。

2.1 整体环境架构

先看一张整体架构图,理清各组件之间的关系。

座舱多屏开发环境架构 主机开发环境(Ubuntu 20.04/22.04) QNX Momentics IDE | Android Studio | 交叉编译工具链 QNX SDK 7.1 | Android Automotive SDK 14+ | ADB & QNX Debugger QNX 目标系统 仪表屏 / 仪表盘域 QNX SDP 7.1 模拟器 QNX Neutrino RTOS 真机 交叉编译: aarch64-qnx / x86_64-qnx Android 目标系统 中控屏 / 副驾屏 / 后排屏 Android Automotive 模拟器 AAOS 真机 / 开发板 ADB + Android Studio Debugger 跨系统通信层 SOME/IP | DDS | QNX-Android Bridge | Socket CAN 调试与性能工具 QNX System Profiler | Android Studio Profiler | Traceview | Perfetto

我的建议:在宿主机上至少预留100GB磁盘空间。QNX SDP完整安装约15GB,Android Studio + SDK约30GB,再加上模拟器镜像和项目代码,空间很快就吃紧了。我吃过这个亏,装到一半磁盘满了,很尴尬。

2.2 QNX SDK安装与配置

QNX的开发环境,核心是QNX Software Development Platform (SDP)。目前主流版本是7.1,支持ARMv8和x86_64架构。

2.2.1 安装步骤

  1. 获取安装包:从BlackBerry QNX官网或企业授权渠道下载QNX SDP 7.1安装包(约6GB)。
  2. 执行安装:运行qnx710.run,建议安装到/opt/qnx710目录。
  3. 配置环境变量:在~/.bashrc中添加以下内容:
# QNX SDP 7.1 环境变量
export QNX_HOST=/opt/qnx710/host/linux/x86_64
export QNX_TARGET=/opt/qnx710/target/qnx7
export PATH=$QNX_HOST/usr/bin:$PATH
export QNX_CONFIGURATION=/etc/qnx

# 选择目标架构(以aarch64为例)
export QNX_ARCH=aarch64
export CC=aarch64-unknown-nto-qnx7.1.0-gcc
export CXX=aarch64-unknown-nto-qnx7.1.0-g++
  1. 验证安装:运行qcc --version,应显示QNX编译器版本信息。

注意:QNX的交叉编译器命名规则是<arch>-unknown-nto-qnx<版本>-<工具>。例如aarch64-unknown-nto-qnx7.1.0-gcc。不要搞混架构,否则编译出来的二进制在目标板上跑不起来。

2.2.2 交叉编译工具链详解

QNX的交叉编译工具链,说白了就是一套能在x86 Linux上生成ARM代码的编译器集合。我个人习惯把工具链分为三部分:

组件 路径 说明
编译器 $QNX_HOST/usr/bin/aarch64-*-gcc/g++ C/C++交叉编译器
链接器 $QNX_HOST/usr/bin/aarch64-*-ld 目标架构链接器
系统库 $QNX_TARGET/aarch64/lib 目标架构运行时库(libc、libm等)
头文件 $QNX_TARGET/aarch64/usr/include QNX系统头文件
调试器 $QNX_HOST/usr/bin/nto-aarch64-gdb 远程调试器

避坑指南:我曾经在编译一个图形库时,链接阶段一直报undefined reference。查了两天才发现,是链接库的顺序不对。QNX的链接器对库顺序敏感——被依赖的库要放在后面。比如-lfoo -lbar,如果bar依赖foo,要写成-lbar -lfoo。

2.3 Android Automotive SDK安装

Android Automotive的开发环境,和普通Android开发大同小异,但有几个关键差异点。

2.3.1 安装步骤

  1. 安装Android Studio:从developer.android.com下载最新版(建议Koala或更高版本)。
  2. 安装Automotive SDK:在SDK Manager中,选择Android 14.0 (API 34)或更高版本,勾选Automotive模块。
  3. 创建Automotive模拟器:使用AVD Manager创建Automotive模拟器,选择Automotive (1024p landscape)设备定义。
  4. 配置系统镜像:下载Android Automotive (Google APIs)系统镜像,约2.5GB。

2.3.2 与普通Android的差异

维度 普通Android Android Automotive
SDK模块 android.* android.car.*、android.automotive.*
模拟器 手机/平板 Automotive专用模拟器(1024x768或1920x1080)
权限模型 运行时权限 车辆相关权限(如android.car.permission.CAR_INFO)
UI框架 Jetpack Compose / View Car UI Library(需额外依赖)
调试方式 ADB over USB/WiFi ADB over TCP/IP(模拟器)或USB(真机)

关键点:Android Automotive的模拟器默认不包含Google Play服务。如果需要测试地图、语音等依赖GMS的功能,必须使用Google APIs系统镜像,并在模拟器中登录Google账号。

2.4 模拟器环境搭建

模拟器是开发阶段的主力。真机资源有限,不可能每人一台开发板。我建议团队里至少配一台高性能开发机,专门跑模拟器。

2.4.1 QNX模拟器

QNX SDP自带QEMU模拟器,支持ARM和x86架构。启动方式如下:

# 启动QNX ARM64模拟器
qemu-system-aarch64 \
  -M virt \
  -cpu cortex-a57 \
  -smp 4 \
  -m 2048 \
  -kernel /opt/qnx710/target/qnx7/boot/images/ifs-qnx7-aarch64.raw \
  -drive file=/opt/qnx710/target/qnx7/images/qnx7-aarch64.img,if=none,id=drive0 \
  -device virtio-blk-device,drive=drive0 \
  -netdev user,id=net0,hostfwd=tcp::1234-:1234 \
  -device virtio-net-device,netdev=net0 \
  -serial stdio

我的习惯:我会写一个start_qemu.sh脚本,把上面的命令封装起来。同时开启端口转发,这样宿主机可以通过qconn协议连接到模拟器进行调试。端口1234是QNX调试器的默认端口。

2.4.2 Android Automotive模拟器

Android Automotive模拟器可以通过命令行或Android Studio启动。我个人更习惯命令行,方便集成到CI/CD流程:

# 列出可用的Automotive模拟器
emulator -list-avds

# 启动Automotive模拟器(无界面模式)
emulator -avd Automotive_1024p_API_34 -no-window -no-audio

# 启动并开启网络端口转发
emulator -avd Automotive_1024p_API_34 -port 5554 -no-snapshot

注意:Automotive模拟器对GPU有要求。如果宿主机没有独立显卡,建议在AVD配置中关闭Host GPU选项,否则模拟器可能黑屏。我遇到过好几次,最后发现是显卡驱动不兼容。

2.5 真机调试环境搭建

真机调试是性能调优的必经之路。模拟器再像,也模拟不出真实的硬件延迟和资源争抢。

2.5.1 QNX真机调试

QNX真机调试依赖qconn服务。目标板上需要运行qconn,宿主机通过IDE或命令行连接。

  1. 目标板配置:确保qconn服务在目标板上运行(默认端口8000)。
  2. 宿主机连接:使用qconn命令或QNX Momentics IDE的Target Navigator视图。
  3. 上传二进制:使用scp或ftp将交叉编译好的程序上传到目标板。
  4. 远程调试:使用nto-aarch64-gdb进行远程调试。
# 远程调试示例
nto-aarch64-gdb my_app
(gdb) target remote 192.168.1.100:8000
(gdb) file my_app
(gdb) load
(gdb) run

2.5.2 Android Automotive真机调试

Android Automotive真机调试和普通Android类似,但有几个特殊点:

  • USB调试:需要在开发者选项中开启USB调试和OEM解锁。
  • 网络调试:如果USB口被占用(比如连接了CAN工具),可以使用adb connect <IP>:5555进行网络调试。
  • 多屏调试:使用adb shell dumpsys display查看当前连接的显示屏信息。

经验之谈:真机调试时,我建议先跑一遍CTS(Compatibility Test Suite)的Automotive相关用例。有些开发板对Automotive API的支持不完整,提前发现能省去后面排查问题的痛苦。

2.6 环境验证清单

环境搭好后,别急着写代码。先跑一遍验证清单,确保所有环节都通。

检查项 验证方法 预期结果
QNX编译器 qcc --version 显示7.1.0版本信息
交叉编译 编译一个hello.c并运行file hello 显示ELF 64-bit LSB executable, ARM aarch64
QNX模拟器 启动模拟器并执行uname -a 显示QNX Neutrino 7.1
Android SDK adb devices 显示模拟器或真机设备
Automotive API 在模拟器中运行dumpsys car_service 显示车辆属性服务信息
跨系统通信 QNX模拟器ping Android模拟器 网络互通(需配置桥接网络)

最后一个小建议:把环境搭建过程写成自动化脚本。我团队里每个新成员入职,第一件事就是跑setup_dev_env.sh。这样既保证环境一致,又节省了反复沟通的时间。脚本里可以包含SDK路径检测、环境变量检查、模拟器镜像下载等步骤。