在TI AM57xx/AM65x开发板上构建Android Automotive OS完整指南 1. 项目概述与核心价值如果你手头有一块德州仪器TI的AM57xx或AM65x系列开发板并且一直在琢磨如何让它跑起来一套真正为汽车座舱优化的操作系统那么这篇文章就是为你准备的。我最近花了相当长的时间在TI的BeagleBoard-X15和AM65x EVM上折腾Android Automotive OS从环境搭建、源码修改到烧录测试把整个流程完整地走了一遍。Android Automotive OSAAOS和我们手机上的Android或者车机上的Android Auto手机投屏有本质区别它是一个完整的、深度定制的、直接运行在车载硬件上的操作系统。这意味着你可以像在手机上一样在车机里直接安装和运行专为驾驶场景优化的应用比如集成的气候控制界面、车辆状态通知面板、以及符合车载安全规范的地图和音乐应用。这个项目的核心价值在于它提供了一个在嵌入式硬件上验证和开发车载信息娱乐系统IVI的绝佳平台。对于嵌入式工程师、车载系统开发者或者任何对汽车电子和Android底层感兴趣的朋友来说通过在一块实际的开发板上亲手构建并运行AAOS你能深刻理解从硬件抽象层HAL到上层应用服务的整个车载软件栈是如何协同工作的。这不仅仅是跑通一个Demo更是为未来开发真正的数字座舱产品打下坚实的技术基础。接下来我会把整个过程中涉及的环境准备、代码修改、构建部署、测试验证等所有关键步骤和踩过的坑毫无保留地分享出来。2. 环境准备与前期工作在开始修改代码和构建系统之前一个稳定、合规的构建环境是成功的基石。这一步如果没做好后续会冒出各种稀奇古怪的错误让人无从下手。2.1 硬件与软件基础要求首先你需要一块支持的TI开发板。本文主要基于AM57xx BeagleBoard-X15这是目前TI在Android开源项目AOSP中官方支持的主要平台。同时我也会提及如何将同样的工作迁移到AM65x EVM上。除了开发板你还需要一台性能足够强劲的Linux构建主机。根据Google官方的建议构建Android系统推荐至少16GB内存和250GB以上的可用磁盘空间SSD最佳。我个人的经验是内存越大越好32GB或以上可以显著减少构建时间避免因内存不足导致的构建失败。软件层面你需要一个64位的Ubuntu LTS发行版如18.04或20.04。确保你的系统已经安装了必要的依赖包。除了AOSP常规的构建依赖如git,curl,python等针对TI的平台你还需要TI提供的Processor SDK for Android。这个SDK包含了针对TI芯片优化的内核源码、U-Boot引导程序、以及一些预编译的二进制文件和工具链是成功构建的必备条件。你需要从TI官网下载对应你开发板型号和Android版本的SDK安装包。2.2 源码获取与仓库初始化AAOS的源码基于AOSP。TI维护了自己的AOSP manifest仓库其中包含了针对其硬件平台的特定配置和补丁。因此你不能直接从Google的AOSP仓库拉取代码而必须使用TI提供的manifest。第一步是安装repo工具这是Google为管理AOSP这种超大型多仓库项目而开发的工具。然后你需要为你的构建创建一个工作目录并初始化repo客户端指定TI的manifest仓库和对应的分支。例如对于Android Pie版本你可能需要使用pie-core-release分支。这个过程可能会花费一些时间因为它需要同步数十个Git仓库总体积超过100GB请确保网络通畅且有足够的磁盘空间。在同步完源码后紧接着就需要设置构建环境。这包括导入一系列环境变量和构建命令。你需要进入源码根目录执行source build/envsetup.sh脚本。这个脚本会为你提供后续关键的lunch和make等命令。lunch命令用于选择你要构建的目标设备target product和变体variant例如beagle_x15-userdebug就是为BeagleBoard-X15构建一个带调试功能的用户版本。2.3 工具链与内核配置TI的ARM平台构建需要使用特定的交叉编译工具链。在TI的Processor SDK中通常会包含一个预编译好的工具链比如gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf。你需要在构建前确保工具链的路径被正确设置到环境变量中或者TI的构建脚本已经自动处理了这一点。内核方面TI提供了与Android版本匹配的Linux内核树例如ti-android-linux-4.19.y。你不需要单独编译内核因为Android的构建系统通过make bootimage会负责内核的编译。但是如果你需要为AAOS启用特定的内核驱动或配置比如某些车载总线或传感器你可能需要进入内核目录进行自定义配置。不过对于初次启用AAOS的基本功能TI默认的内核配置通常已经足够。注意构建环境的搭建是一次性的但也是最容易出错的环节。务必严格按照TI官方提供的“Processor SDK Android Getting Started Guide”操作。常见的坑包括1磁盘空间不足导致同步失败2系统缺少某个依赖库导致编译错误3使用了错误版本的工具链或内核。建议在开始前先完整地构建一次标准的“平板”配置即beagle_x15-userdebug确保基础环境完全正确然后再进行AAOS的修改。3. 为Android Automotive修改设备树代码这是整个项目的核心环节。我们需要告诉Android构建系统“现在我要构建的不是一个平板设备而是一个汽车设备。” 这主要通过修改设备特定的Makefile和创建新的配置文件来实现。所有的修改都集中在device/ti/beagle_x15/目录下以BeagleBoard-X15为例。3.1 扩展产品列表与构建目标首先我们需要在AndroidProducts.mk文件中定义一个新的“午餐组合”lunch combo。这个文件就像一个菜单lunch命令弹出的列表就来源于此。默认情况下这里可能只有beagle_x15.mk对应的beagle_x15-userdebug。我们需要添加一个针对汽车版本的新条目。修改的关键在于将原有的单一行声明改为一个键值对映射并添加新的汽车版本目标。修改后COMMON_LUNCH_CHOICES变量中就会出现beagle_x15_auto-userdebug这个选项。当你执行lunch命令时就可以选择它来构建汽车版本。这里的“auto”后缀是一个清晰的标识方便在命令行中区分。3.2 条件化集成汽车专属策略接下来需要修改BoardConfig.mk文件。这个文件定义了开发板的硬件特性和一些全局构建配置。对于AAOS我们需要条件化地添加一些汽车专属的配置特别是安全策略SELinux policy。Android的安全模型很大程度上依赖于SELinux。汽车版本引入了一些新的服务如车辆硬件抽象层服务它们需要特定的SELinux策略规则才能正常运行。我们通过一个条件判断ifeq ($(TARGET_PRODUCT), beagle_x15_auto)确保只有在构建汽车目标时才会将汽车产品的通用策略目录packages/services/Car/car_product/sepolicy包含进来。同时我们还需要添加一个设备清单文件manifest.xml它用于向系统声明本设备提供的硬件抽象层HAL服务这对于AAOS至关重要。3.3 创建汽车专属配置目录与文件现在在device/ti/beagle_x15/目录下创建一个名为auto的子目录。所有汽车版本特有的配置都将放在这里与标准配置隔离结构清晰。首先创建auto/beagle_x15.mk文件。这是新“午餐组合”对应的顶级产品定义文件。它的核心作用是继承inherit一系列必要的Makefile。它首先继承了标准设备的device.mk以确保所有基础硬件功能得以保留。然后它继承了我们将要在auto目录下创建的device.mk用于添加汽车特有模块。接着它继承了AOSP的基础产品配置full_base.mk。最关键的一步是继承AAOS的核心定义文件car.mk位于packages/services/Car/car_product/build/。这个car.mk文件会进一步继承car_base.mk后者设置了大量汽车设备专用的系统属性例如启用演示模式的气候控制、收音机等。然后创建auto/device.mk文件。这个文件用于声明汽车版本需要额外包含的软件包和文件。最重要的一个包是android.hardware.automotive.vehicle2.0-service这就是车辆硬件抽象层Vehicle HAL的服务实现。虽然TI的通用开发板没有真实的车辆网络如CAN总线但这个服务是AAOS框架所必需的它提供了一个与车辆通信的标准化接口。此外还需要复制两个关键的权限XML文件android.hardware.type.automotive.xml将设备类型标记为“Automotive”这会触发系统加载汽车专用的框架和服务android.hardware.screen.landscape.xml声明设备支持横屏这是车载屏幕的典型布局。最后创建auto/manifest.xml文件。这是一个HAL清单文件采用HIDLHAL接口定义语言格式。它向系统声明“本设备提供了一个遵循android.hardware.automotive.vehicle2.0接口规范的HAL服务实例名为default。” 这样当AAOS框架启动时它就知道去哪里查找并绑定这个车辆HAL服务。实操心得修改Makefile时要特别注意空格和Tab键的区别。Makefile语法中命令行必须以Tab开头。如果你在复制代码时不小心将Tab转换成了空格会导致make命令执行失败并报“missing separator”错误。建议使用能高亮显示空格和Tab的文本编辑器如VSCode、Vim。另外在继承car.mk时要确认其路径在AOSP源码树中是正确的。不同版本的AOSP或TI SDKCar模块的路径可能略有差异。4. 系统构建与镜像烧录当所有代码修改完成后就可以开始构建系统并烧录到开发板了。这个过程是对前面所有准备工作的一次总检验。4.1 配置与执行构建首先进入你的AOSP源码根目录设置构建环境. build/envsetup.sh。接着运行lunch命令这时你应该能在菜单中看到新添加的beagle_x15_auto-userdebug选项选择它。选择后终端会显示一系列环境变量被设置其中TARGET_PRODUCT的值就是beagle_x15_auto这确保了后续构建会使用我们刚刚配置的汽车版本。在开始构建前还需要设置内核源码的路径。执行export KERNELDIR你的内核目录绝对路径。这个路径通常位于TI Processor SDK的board-support目录下。然后就可以启动构建了make -j核心数。这里的-j参数用于指定并行编译的作业数通常设置为你的CPU核心数或核心数的1.5倍以最大化利用多核性能显著缩短编译时间。一个完整的AAOS构建在性能较好的机器上可能需要数小时。构建成功后所有的输出镜像文件如boot.img,system.img,vendor.img,userdata.img等会生成在out/target/product/beagle_x15/目录下。这些镜像文件包含了编译好的内核、系统分区、供应商分区和用户数据分区。4.2 准备烧录环境与FastbootTI开发板通常支持通过Fastboot协议从主机USB口烧录镜像。我们需要准备一个用于烧录的工作目录。一个方便的做法是复制TI SDK中提供的prebuilt-images目录因为它里面已经包含了一些必要的引导文件如MLO、u-boot.img和设备树二进制文件.dtb。你需要将刚刚编译生成的AAOS镜像文件、以及从AOSP构建输出中提取的一些主机工具如fastboot,adb复制到这个工作目录。TI通常会提供一个fastboot.sh脚本这个脚本封装了具体的烧录命令。你需要参考这个脚本确认需要复制哪些具体的镜像文件。对于AM57xx和AM65x平台所需的文件列表略有不同主要是引导文件有差异AM65x采用了更复杂的多阶段引导tispl.bin和tiboot3.bin。4.3 连接设备与执行烧录将开发板通过USB线连接到主机并连接串口调试线如USB转TTL。打开一个串口终端例如使用picocom或minicom设置波特率为115200用于观察开发板的启动日志。给开发板上电在串口终端中快速按下任意键中断U-Boot的自动启动。在U-Boot命令行中输入fastboot 0命令这将使开发板进入Fastboot模式等待主机连接。在主机上打开另一个终端进入之前准备好的烧录工作目录emmc_files。首先给fastboot.sh脚本添加执行权限chmod x fastboot.sh。然后以root权限执行它sudo ./fastboot.sh。这个脚本会自动调用fastboot工具依次将各个镜像烧录到开发板的eMMC存储的对应分区中。烧录完成后脚本通常会执行fastboot reboot命令让开发板重启。注意事项烧录过程务必保证供电稳定USB连接可靠。如果烧录中途失败可能导致开发板无法启动。此时通常需要重新进入Fastboot模式再次烧录。串口终端是救命稻草一定要保持开启任何内核panic或启动失败的信息都会在这里打印出来。第一次启动AAOS可能会比较慢因为系统需要进行初始化设置请耐心等待几分钟。5. 兼容性测试与问题排查系统成功启动并进入AAOS的汽车界面你会看到一个带有车辆图示的启动画面和“Let‘s Drive”主界面只是第一步。为了确保系统符合Android Automotive的标准并且稳定可靠必须进行严格的测试。Google提供了两套主要的自动化测试框架兼容性测试套件CTS和供应商测试套件VTS。5.1 兼容性测试套件CTS配置与执行CTS旨在确保设备与Android API和兼容性定义文档CDD保持一致。对于汽车设备有专门的CtsCarTestCases测试模块。首先需要在你的桌面主机上安装最新版本的adb和aapt工具。虽然Android SDK里自带但最好用包管理器更新一下sudo apt-get install adb aapt。接着你需要从Google开发者网站下载与你设备Android版本和ABI架构匹配的CTS压缩包。将下载的CTS包解压到之前烧录用的emmc_files工作目录下。有时为了通过某些CTS测试你可能需要覆盖设备的首个API级别属性。这可以通过在设备的device.mk文件中添加PRODUCT_PROPERTY_OVERRIDES ro.product.first_api_level级别来实现具体的级别值需要查询Android版本代号与API级别的对应关系。测试执行时首先通过串口和ADB确保设备已连接并处于可用状态。然后进入解压后的CTS工具的tools目录运行./cts-tradefed启动CTS控制台。在控制台提示符cts-tf 下运行run cts --module CtsCarTestCases来执行汽车相关的测试用例。测试过程是自动化的会持续一段时间。完成后测试结果包括通过的、失败的和未执行的用例会以HTML和XML格式保存在android-cts/results/目录下的一个时间戳文件夹中。5.2 供应商测试套件VTS与汽车HAL测试VTS更侧重于测试设备的硬件抽象层HAL和内核的兼容性。对于AAOS车辆HALVehicle HAL是测试的重点。运行VTS也需要先启动其控制台vts-tradefed。在vts-tf 提示符下可以使用list plans查看所有测试计划。我们关注的是vts-hal-auto计划它专门用于测试汽车车辆HAL。执行命令run vts-hal-auto即可开始测试。VTS测试的结果会输出到AOSP源码构建输出的特定目录下路径类似out/host/linux-x86/vts/android-vts/results/时间戳。5.3 已知问题与调试技巧在实际测试中你可能会遇到一些已知或未知的问题。根据TI的文档和我的实践这里有几个典型的已知问题和排查思路SELinux拒绝Denial日志系统运行时可能会在dmesg日志中看到一些SELinux拒绝访问的信息。你可以使用adb shell dmesg | grep denied来查看。这些拒绝通常是因为某些汽车服务如carservice_app或hal_vehicle_default尝试访问某些资源如套接字、文件但当前的安全策略neverallow规则禁止了这些访问。在开发阶段有时可以通过audit2allow工具生成临时策略规则但最终解决方案需要向AOSP上游提交策略修改。对于原型开发你可以在userdebug版本的设备上使用setenforce 0临时禁用SELinux来快速验证功能但这绝不是生产环境的解决方案。电源管理服务错误日志中可能会出现CarPowerManagerNative: Received unknown bootReason 0或PowerTestService: Could not read bootReason!!的错误。这是因为车辆HAL服务没有上报正确的启动原因。在真实的汽车硬件上这个信息来自车辆网络。在通用开发板上车辆HAL运行在“模拟”或“默认”模式可能无法提供此信息。这个错误通常不影响基本功能的演示但意味着与电源状态深度集成的功能如深度睡眠唤醒可能无法正常工作。蓝牙测试失败在CTS的CtsCarTestCases中android.car.cts.CarBluetoothTest测试用例很可能会失败并抛出NullPointerException提示BluetoothAdapter为null。这是预期中的因为像BeagleBoard-X15和AM65x EVM这样的通用开发板其标准硬件配置可能不包含蓝牙模块或者蓝牙驱动没有正确集成到Android系统中。这个测试失败可以安全忽略除非你特意为开发板添加并配置了蓝牙硬件。排查心得当遇到启动失败或功能异常时串口日志dmesg和Android日志logcat是你最好的朋友。优先使用adb logcat -b all查看所有缓冲区的日志或者使用adb logcat | grep -iE “error|fail|exception|crash”来过滤关键错误信息。对于系统服务启动问题可以重点关注SystemServer和CarService相关的日志。另外确保你的设备有足够的存储空间/data分区被正确挂载且可读写许多诡异的问题都源于存储空间不足或权限错误。6. 向新平台迁移与未来展望成功在BeagleBoard-X15上启用AAOS后这套方法论可以迁移到其他TI平台上例如AM65x EVM。迁移工作的核心是复用和适配设备树配置。6.1 AM65x EVM迁移要点对于AM65x平台整体思路与X15完全一致在device/ti/am65xevm/目录下进行相同的修改。创建auto子目录仿照X15的步骤修改AndroidProducts.mk、BoardConfig.mk并创建对应的auto/am65xevm.mk、auto/device.mk和auto/manifest.xml文件。主要的差异点可能在于内核与引导加载程序AM65x是异构多核架构Cortex-A53 Cortex-R5其引导流程tiboot3.bin,tispl.bin和内核设备树DTS与AM57xx不同。你需要确保烧录时使用的是AM65x对应的引导文件和内核镜像。硬件配置device.mk中可能需要根据AM65x的实际硬件调整一些产品属性或者添加/移除特定的硬件HAL模块。TI源码仓库AM65x的AAOS支持可能已经合并到TI独立的Pie版本仓库中而不是AOSP主线上。因此在初始化repo时需要使用TI为AM65x提供的特定manifest仓库地址和分支。6.2 未来发展方向与挑战将AAOS移植到更贴近真实汽车的“车规级”TI平台如Jacinto系列是未来的方向。这将带来新的挑战和机遇多显示屏支持真实的数字座舱通常有多个屏幕仪表盘、中控屏、副驾屏、后排屏。Android Q及更高版本的AAOS加强了对多硬屏的支持需要为每个屏幕配置独立的显示ID、输入映射和用户体验策略。例如驾驶席屏幕有严格的应用限制而乘客屏则可以运行更多类型的应用。多用户与无头系统汽车可能有多个用户配置文件或者支持“无头”headless系统用户用于后台服务。这涉及到更复杂的用户管理、数据隔离和权限控制。多区域音频高级车载音响系统支持将不同的音频流如导航提示、主媒体、后排娱乐路由到不同的扬声器区域。AAOS的多区域音频框架需要与底层的音频HAL和策略进行细致配置。真实的车辆HAL实现在开发板上我们使用了一个默认或模拟的Vehicle HAL。在真实平台中需要实现一个与车辆网络如CAN、LIN、以太网通信的真实HAL将车辆信号车速、转速、车门状态等转换为AAOS框架可以理解的属性。功能安全与可靠性车载系统对功能安全如ISO 26262 ASIL等级和长期可靠性有极高要求。这涉及到从硬件选型、内核驱动到上层系统服务的全栈考量远超出在通用开发板上进行功能验证的范畴。这个过程让我深刻体会到在嵌入式平台上启用一个复杂的系统如AAOS远不止是敲几行命令。它要求你对Android构建系统、设备树配置、硬件抽象层、以及系统安全模型都有深入的理解。每一个步骤的细节都至关重要从Makefile的一个Tab到烧录时的一个文件都可能成为成功与失败的分水岭。希望这份详细的指南能帮你少走弯路顺利启动你的车载系统探索之旅。如果在实际操作中遇到新的问题多查日志、多翻阅AOSP和TI的官方文档社区的资源和经验分享也是解决问题的宝贵途径。