4.2. 硬件点亮指引

硬件点亮( Bring up)是嵌入式系统开发的第一步,是将硬件设计从图纸变为实际可用设备的关键环节。通过点亮过程,可以验证硬件设计的正确性、初步运行最小系统、并为后续功能开发打下基础。以下将从 最小系统制作硬件回板检查与调试系统功能初步验证 等方面,详细介绍硬件点亮的基本流程和关键步骤。

4.2.1. 硬件点亮基本流程

这一章节将梳理硬件点亮的整体流程,为之后的开发提供清晰的指引。在接下来的章节中,我们将对每个阶段涉及的开发任务进行详细说明,帮助用户按步骤完成开发工作。

4.2.1.1. 最小系统准备阶段

在硬件回板前,软件上可以提前完成以下开发,当硬件回板时快速进行验证调试。

  • 板级配置与基本驱动开发

    • 在 BSP(源码在 SDK 交付包的 board_support_package/platform_source_code.tar.gz)代码中新增板级配置文件,例如 board_xxx_config.mkxxx 是用户自定义的名称,例如 x5_evb_release),以适配新硬件平台。

    • 在 U-Boot 中添加新硬件的 Board ID。

    • 在 U-Boot 和 Kernel 中添加相关配置文件和设备树( DTB),包括管脚复用配置、功能开关设置等。

    • 根据硬件设计完成低速总线外设驱动(如 UART、 I2C、 SPI、 PWM 等)的移植,确保完成以太网和 USB 等的驱动适配。

    • 根据产品设计需求规划分区表。

  • 硬件设计检查与电压域配置

    • 根据设计确认所有功能模块的管脚电压域配置,确保与硬件电路设计一致。

    • 特别注意:错误的电压域配置可能导致芯片损坏或设备不可预测行为,应格外重视。

参与人: 软件工程师为主,硬件工程师配合澄清硬件设计上的规格。

4.2.1.2. 硬件回板检查与调试

  • 硬件检查

    • 外观检查:确保元器件无漏贴、错贴或焊接问题。

    • 供电检查:上电后,使用万用表或示波器测量芯片供电是否稳定、符合设计要求。

  • 初步功能验证

    • 通过串口连接设备,观察 debug 串口输出日志:

      • 无日志:需重点检查供电、复位信号及时钟源是否正常。

      • 日志异常:根据错误提示定位问题原因。

      • 正常日志: 为烧录系统镜像的硬件,上电启动时,正常会进入串口下载模式,在串口上连续打印 C 字符。

  • 系统烧录

参与人: 硬件工程师为主,软件工程师提供系统镜像,同步协调完成系统烧录。

4.2.1.3. 启动异常排查

  • miniboot 阶段卡住

    • 检查 DDR 的型号、容量是否识别正确,确保参数 Training 成功。

    • 确认 U-Boot 加载流程无异常。

  • U-Boot 阶段卡住

    • 检查硬件 Board ID 是否识别正确。

    • 检查 Kernel 加载参数( bootargs/cmdline)是否正确。

    • 检查是否加载了正确的设备树。

参数人: 软件工程师为主,硬件工程师配合澄清硬件设计上的规格。

4.2.1.4. 系统功能摸底

  • 内核启动验证

    • 检查内核启动日志,确认驱动模块加载和设备驱动初始化无误。

    • 验证根文件系统、应用程序( app)、用户数据分区( userdata)挂载是否正常。

  • 功能接口测试

    • 测试网络接口(如 SSH 登录)、 USB 端口功能(如 ADB 连接)是否正常。

    • 硬件上有以太网的情况下,确保系统可以进入 shell 并完成基本操作。

    • 硬件上有 USB 从设备接口的情况下,确保系统可以进入 adb shell 并完成基本操作。

参与人: 软件工程师。

4.2.1.5. 系统稳定性测试

  • 压力测试

    • 对 CPU、 DDR、 BPU 、 eMMC / Nand Flash 等核心硬件进行高负载测试。

    • 根据具体产品需求测试特定功能模块的性能和稳定性。

参与人: 测试工程师为主,软件工程师提供必要的测试软件和环境搭建方法。

4.2.2. 新增板级配置

板级配置是系统开发中,为特定硬件平台定制的编译和运行环境设置文件。通过板级配置,开发者可以定义硬件的关键参数,如芯片型号、架构、交叉工具链路径、分区信息以及根文件系统等。这些配置文件确保编译系统能够生成适配目标硬件的固件,同时简化了不同硬件版本之间的切换和维护。

在多硬件平台共用一套代码的场景中,每款硬件需要单独的板级配置文件,以便根据硬件特性启用特定功能、加载对应驱动,并保证系统的兼容性和稳定性。

以下是 device/horizon/x5/board_x5_evb_release_config.mk 的示例内容,展示了典型的板级配置文件结构和设置:

#!/bin/bash

export HR_TARGET_VENDOR="horizon"
export HR_TARGET_CHIP="x5"
export HR_SECURE_CHIP=y
export HR_TARGET_BIT="64"
export HR_TARGET_MODE="release"

# 板级名称,对应每一个新的硬件型号
export HR_BOARD_TYPE="soc"

# 编译 out 目录
export HR_BUILD_OUTPUT_DIR=${HR_TOP_DIR}/out
# 编译中间文件输出目录,如 uboot、 kernel、 hbre 的编译目录
export HR_TARGET_BUILD_DIR=${HR_BUILD_OUTPUT_DIR}/build
# 产出镜像输出路径,本目录下的镜像文件用于烧录和发布
export HR_TARGET_PRODUCT_DIR=${HR_BUILD_OUTPUT_DIR}/product
# 从 build 到 product 的中间产物,如内核、设备树、根文件系统的原始目录和文件
export HR_TARGET_DEPLOY_DIR=${HR_BUILD_OUTPUT_DIR}/deploy
# 编译日志保存目录
export HR_BUILD_LOG_DIR=${HR_BUILD_OUTPUT_DIR}/build_log

# 板级配置文件存放目录
export HR_BOARD_CONF_DIR=${HR_TOP_DIR}/"device/horizon/${HR_TARGET_CHIP}/board_cfg/${HR_BOARD_TYPE}"

# 配置交叉编译工具链
export ARCH="arm64"
export TOOLCHAIN_PATH=/opt/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu
export CROSS_COMPILE=${TOOLCHAIN_PATH}/bin/aarch64-none-linux-gnu-

# 使能 ccache,加速编译
export HR_CCACHE_SUPPORT=y
export CCACHE_COMMAND="ccache"
export HR_APPEND_CXX_OPTIONS="-DCMAKE_CXX_COMPILER=\"${CCACHE_COMMAND}\" -DCMAKE_CXX_COMPILER_ARG1=\"${CROSS_COMPILE}g++\" -DCMAKE_C_COMPILER=\"${CCACHE_COMMAND}\" -DCMAKE_C_COMPILER_ARG1=\"${CROSS_COMPILE}gcc\""
export HR_CCACHE_DIR="$HOME/.ccache"

# 构建系统常用的工具软件存放路径,比如 fiptool
export HR_BUILD_TOOL_PATH=${HR_TOP_DIR}/build/tools
# 分区表, mbr, gpt 内容处理的工具软件存放路径
export HR_PARTITION_TOOL_PATH=${HR_TOP_DIR}/build/tools/partition_tools
# avbtools 工具脚本存放路径,在对 kernel 和分区文件系统添加校验信息时需要使用到( mk_system.sh)
export HR_AVB_TOOLS_PATH=${HR_TOP_DIR}/build/tools/android_tools/avbtools
export HR_BD_IMG_TOOLS_PATH=${HR_TOP_DIR}/build/tools/android_tools/build_image

# 分区表配置文件所在目录和文件名
export HR_PART_CONF_FILENAME=${HR_BOARD_CONF_DIR}/x5-soc-release-gpt.json
export BLK_SZ=512
export MMC_UFS_ERASE_SIZE=524288
export NOR_ERASE_SIZE=32768
export HYPER_ERASE_SIZE=262144

# uboot 编译配置文件
export HR_UBOOT_CONFIG_FILE=hobot_x5_auto_defconfig
export HR_ARCH_UBOOT="arm"
# 指定 uboot 源码的输出目录,如果不设置,则在源码目录下编译
export HR_UBOOT_OUTPUT_DIR=${HR_TARGET_BUILD_DIR}/uboot

# kernel 配置
# kernel 编译配置文件
export HR_KERNEL_CONFIG_FILE=hobot_x5_soc_perf_defconfig
export HR_ARCH_KERNEL="arm64"
# 指定内核源码的输出目录,如果不设置,则在源码目录下编译
export HR_KERNEL_OUTPUT_DIR=${HR_TARGET_BUILD_DIR}/kernel

# system 配置
# 指定根文件系统类型和预编译的文件系统路径
export HR_SYSTEM_TYPE="buildroot"
export HR_SYSTEM_DIR=${HR_TOP_DIR}/system/buildroot/prebuilt
# 根文件系统的分区名,需要和分区表配置对应
export HR_SYSTEM_PART_NAME="system"
# system verify method: dm-verity, crypt
export HR_SYSTEM_VERIFY="dm-verity"

# 设置 SDK 版本
source "${HR_TOP_DIR}/device/${HR_TARGET_VENDOR}/${HR_TARGET_CHIP}/dr_release_version.mk"
export HR_BUILD_VERSION="${HR_RELEASE_VERSION}"

# antirollback version
export ANTIROLLBACK_SEC_UPDATE="false"
export ANTIROLLBACK_SEC_VER=0
export ANTIROLLBACK_NOSEC_UPDATE="false"
export ANTIROLLBACK_NOSEC_VER=0

# 环境变量配置标志,用来标识当前 env 环境已经完成了板级配置项的设置
export HR_IS_BOARD_CONFIG_EXPORT="true"

4.2.2.1. 关键配置项解析

  1. 目标硬件信息

    • HR_TARGET_VENDORHR_TARGET_CHIP 定义了目标硬件的供应商和芯片型号。

    • HR_BOARD_TYPE 用于区分具体的硬件板型。

  2. 编译输出路径

    • HR_BUILD_OUTPUT_DIR 是所有编译产物的总目录,HR_TARGET_PRODUCT_DIR 用于存放最终产出的镜像文件。

  3. 工具链配置

    • 使用 CROSS_COMPILE 配置交叉编译工具链,支持指定编译架构和工具路径。

  4. 分区表选择

    • 使用 HR_BOARD_CONF_DIRHR_PART_CONF_FILENAME 指定使用的分区表配置文件。

  5. 模块配置

    • 包括 U-Boot、 Kernel、系统分区表等模块的编译配置文件和路径设置。

  6. 优化与工具支持

    • 启用 ccache 可以加速编译,通过工具路径定义便于调用构建工具和分区工具。

4.2.2.2. 分区配置

分区表的配置通过 HR_BOARD_CONF_DIRHR_PART_CONF_FILENAME 关键选项指定:

# 板级配置文件存放目录
export HR_BOARD_CONF_DIR=${HR_TOP_DIR}/"device/horizon/${HR_TARGET_CHIP}/board_cfg/${HR_BOARD_TYPE}"

# 分区表配置文件所在目录和文件名
export HR_PART_CONF_FILENAME=${HR_BOARD_CONF_DIR}/x5-soc-release-gpt.json

分区表定义了存储设备上的数据布局,包含关键的分区信息,如系统、用户数据、引导分区等。开发新硬件时,需要根据硬件特性和产品需求调整分区表配置文件。

分区表文件说明

分区表文件位于 device/horizon/x5/board_cfg/*,文件一般以 gpt.json 结尾。

device/horizon/x5/board_cfg/soc/x5-soc-release-gpt.json 为例:

{
        "gpt": {
                "size": "20k"
        },
        "mbr": {
                "size": "4k"
        },
        "miniboot": "sub_config/miniboot.json",
        "misc": {
                "size": "4k"
        },
        "uboot": {
                "part_type": "GOLDEN",
                "size": "2m"
        },
        "ubootenv": {
                "size": "256k"
        },
        "vbmeta": {
                "part_type": "GOLDEN",
                "size": "16k"
        },
        "boot": {
                "part_type": "GOLDEN",
                "size": "12m"
        },
        "system": {
                "fs_type": "ext4",
                "part_type": "GOLDEN",
                "size": "250m"
        },
        "hbre": {
                "fs_type": "ext4",
                "part_type": "GOLDEN",
                "size": "200m"
        },
        "app": {
                "fs_type": "ext4",
                "part_type": "GOLDEN",
                "size": "700m"
        },
        "private": {
                "fs_type": "ext4",
                "part_type": "GOLDEN",
                "size": "256k"
        },
        "userdata": {
                "fs_type": "ext4",
                "size": "50m"
        }
}

分区字段说明:

  • gpt: 此分区表镜像保存位置,U-Boot 、Kernel 和 用户态的 parted、fdisk 工具会读取此信息获得系统得分区表。

  • mbr: 此分区存放 ROMCODE 能解析的分区信息,记录 BL2、DDR 参数、BL3x 等固件在镜像中的存放位置。

  • miniboot: 该定义是一个分区子集,在 sub_config/miniboot.json 文件中包含 miniboot.img 镜像内部的分区情况。用户不需要去修改它,否则会带来不必要的适配开发工作。

  • misc: 在运行时此分区记录升级信息,并在 AB 分区模式下保存当前使用的分区编号。

  • uboot: miniboot 分区之后 必须是以 uboot 或者 u-boot 为前缀命名的分区名, miniboot 的镜像的整体打包会依赖该分区名做为分界线。

  • ubootenv: 在 U-Boot 下执行 saveenv 后会保存 U-Boot 环境变量到该分区。

  • boot、system、vbmeta: vbmeta 分区默认会储存 boot、 system 的 avb 验证信息。如果开启安全启动功能的情况下,这三个分区需要同步更新。如果用户想要修改这三个分区的命名,需要在 uboot 中修改对应的代码。根文件系统里面需要修改 hb-fstab 调整分区挂载配置。

  • 其他分区: 其他分区用户可以根据产品实际需要进行调整。

必选属性说明:

  • fs_type: 定义该分区镜像的文件系统类型,必须提供。可以选择以下之一:

    • raw/null: 表示原始数据类型的镜像。

    • ext4/fat32:表示具体文件系统类型。

  • size: 表示该分区镜像的总占用空间,必须提供(单位为 k、 m、 g)。在 NOR Flash 存储器上,必须按照 64KB 对齐;在 eMMC 存储上,必须按照 4KB 对齐。确保分区镜像的总占用空间等于分区组件占用空间之和。

可选属性说明(不配置时可为空)

  • part_type: 定义分区升级类型(可选属性)。可选择以下之一:

    • AB: 双分区,用于 A/B 系统更新。

    • BAK: 备份分区,当主分区无法正常使用时,会尝试从备份分区启动,是保证系统稳定性的一种策略。

    • GOLDEN: 单分区,用于常规系统更新。

    • PERMANENT: 永久性分区,不会进行升级的分区。若不配置,默认为本属性

  • ota_is_update: 定义分区是否可以进行 OTA 升级(可选属性)。可选择以下之一:

    • true: 支持进行 OTA 升级。

    • false: 不支持进行 OTA 升级。若不配置,默认为本属性

  • ota_update_mode: 定义分区的 OTA 升级方式(ota_is_update 必须为 true)。可选择以下之一:

    • image: 镜像全量升级。

  • medium: 表示这个分区镜像烧录的介质。

  • fde_type: 定义用户分区的加密方式,可选择以下方式:

注意

如果要在 NAND 上增加新分区,请使用 ubi 类型的分区格式,分区的 ubi 镜像正常输出到 “out/product/” 下。如果此分区要支持 OTA 升级,请将 ubi 镜像中的卷镜像和 ubi 配置文件输出到 “out/deploy/ubi/” 下,卷镜像的后缀名可以是 { 卷名 }.bin|.img|.ubifs,配置文件名是 {ubi 分区名 }.cfg

4.2.2.3. U-Boot 选项配置

板级配置文件 board_xxx_config.mk 会指定 U-Boot 使用的选项配置文件,相关选项在 板级配置文件 中配置如下:

# 建议:每次新增硬件时都对应添加一套 HR_BOARD_TYPE、 HR_UBOOT_CONFIG_FILE、 HR_KERNEL_CONFIG_FILE、 uboot 和 kernel 下的 dts 设备树

# uboot 编译配置文件
export HR_UBOOT_CONFIG_FILE=hobot_x5_auto_defconfig
export HR_ARCH_UBOOT="arm"
# 指定 uboot 源码的输出目录,如果不设置,则在源码目录下编译
export HR_UBOOT_OUTPUT_DIR=${HR_TARGET_BUILD_DIR}/uboot

为确保系统兼容性,建议每款硬件新增专属的 U-Boot 选项配置文件和设备树文件。这些文件分别位于 U-Boot 源码树的以下目录中:

  • 配置文件路径:configs/

  • 设备树文件路径:arch/arm/dts/

建议每次新增核心板时,均同步更新以下内容:

  • HR_UBOOT_CONFIG_FILE( U-Boot 配置文件)

  • U-Boot 设备树文件

4.2.2.4. Kernel 选项配置

板级配置文件 board_xxx_config.mk 会指定 Kernel 使用的选项配置文件,相关选项在 板级配置文件 中配置如下:

# kernel 编译配置文件
export HR_KERNEL_CONFIG_FILE=hobot_x5_soc_perf_defconfig
export HR_ARCH_KERNEL="arm64"
# 指定内核源码的输出目录,如果不设置,则在源码目录下编译
export HR_KERNEL_OUTPUT_DIR=${HR_TARGET_BUILD_DIR}/kernel

为确保系统兼容性,建议每款硬件新增专属的 Kernel 选项配置文件和设备树文件。对应文件存储路径如下:

  • 配置文件路径:arch/arm64/configs/

  • 设备树文件路径:arch/arm64/boot/dts/hobot/

新增硬件时,请确保以下内容得到更新:

  • HR_KERNEL_CONFIG_FILE( Kernel 配置文件)

  • Kernel 设备树文件

4.2.3. 在 U-Boot 下新增硬件

当用户需要为新型号的硬件开发适配时,为了确保同一套软件固件能够兼容不同的硬件平台,需要进行以下步骤:

  1. 定义新的 Board ID

    为新硬件分配一个唯一的 Board ID,这样可以在系统中区分不同的硬件平台。在 X5 平台上, Board ID 通过 4 个 ADC 通道来定义,基于不同的外部电压值进行硬件识别。该 Board ID 在系统启动时用于确定当前硬件平台的配置,并据此加载相应的固件或驱动。

    有关 Board ID 的详细信息,请参阅 硬件 Board ID 概述

    :在 U-Boot 调试阶段,用户也可以选择在软件中强制定义 Board ID,而无需依赖硬件的 ADC 通道。这种方法可以方便地在开发和测试阶段进行硬件适配和调试。

  2. 在 U-Boot 中进行移植

    在 U-Boot 中,需要根据新硬件的特性进行适配,修改或添加相应的配置文件。具体的移植工作包括:

    • 新增 U-Boot 配置文件。

    • 添加或修改硬件相关的设备树( Device Tree)文件,以支持新硬件的外设和功能。

通过这些步骤,用户可以确保同一套固件在多个硬件平台上正常运行,简化了不同硬件型号的开发和维护工作。

4.2.3.1. 硬件 Board ID 概述

在 X5 平台上, Board ID 通过 4 个 ADC 通道来定义,基于不同的外部电压值进行硬件识别。当前 ADC 通道( ADC_VINS )的配置情况如下:

  • ADC_VINS0 :主板类型,即不同的 X5 项目用不同的 ID 区分。比如:用户内部有两个 X5 项目序列,那么可以使用 VIN0 外部配置不同分压,以进行区分。

  • ADC_VINS1 :用于在某一项目序列下,区分不同的硬件版本。比如:第一次硬件发板、第二次硬件发板。

  • ADC_VINS2 : DDR 参数配置,用户应当根据对应主板 BOM 的 DDR 配置,必须严格按照官方硬件参考设计选择对应档位

  • ADC_VINS6 :预留档位,建议用户 NC。如有 ADC 需求,优先选用其他 ADC 通道( ADC_VIN )。

硬件 Board ID 的硬件参数设计如下,为确保 ADC 端口能够准确读取电压值,需要在其电路中设计 100nF 去耦电容和对应的分压电阻。

image-20241225152523451

ADC 外部分压电阻的选择:

参考官方硬件参考设计,对上拉、下拉电阻进行选型,电阻值和不超过 50K Ω 。一般来说,大电阻(尤其上百 K Ω )的时候,有如下问题:

  • 高阻值电阻,会导致内部 ADC 采样存在明显的 RC 效应,影响采样精度。

  • 高阻值电阻更容易引入噪声。

  • ADC 在应用时,大部分时候都会在 50K Ω 以内, 100K Ω 以上应用很少见。

如下分压电阻组合,供参考:

模拟电压配置 R1 R2 精度
100mV 16K 1K 1%
200mV 16K 2K 1%
300mV 10K 2K 1%
400mV 23.7K 6.8K 1%
500mV 5.1K 2K 1%

ADC 电压档位设计要求及建议:

建议用户按照本章节提供的参考值区分模拟电压,不要自定义模拟电压区间。即,各档位典型值必须是 100mV、 200mV,以此类推。因此,每个字段最多支持 17 档位( ADC 电压范围 0.1 ~ 1.7 V)。

每一个模拟电压对应的软件档位序次(比如, 100mV 在软件内映射为 ID = 1 ),为软件自定义映射,无强制要求。

ADC_VINS2 为强制约束,与 DDR Type 相关,具体说明如下:

  • X5 平台支持的 DDR 规格为 总位宽 32 位,采用 2 通道设计,每通道位宽为 16 位(即 2CH x 16 = 32 位)。 DDR 颗粒架构中的各个 Die 位宽要求为 x16。在设计中需确保 DDR 的频率、容量满足平台性能需求,同时注意 PCB 布线的信号完整性和等长设计,以确保系统稳定性和兼容性。

  • X5 支持 LPDDR4 和 LPDDR4X 两种模式;支持单 Rank 和双 Rank 两种模式,需要通过 ADC_VINS2 区分。

  • ADC_VINS2 的档位无需体现 DDR 容量, 目前支持 1GB / 2GB / 4GB / 8GB 容量的 DDR。

  • 具体支持的型号,请参考 Approved Vendor List

特别提示:档位值请按照1~17来配置,切勿直接将 ADC 输入下拉(档位0)或接上拉电源(档位18)。

ADC 采样范围、分压值、档位值分配参考如下表所示:

image-20241225160051067

4.2.3.2. 新增 U-Boot 选项配置文件

以创建一个名为 som 的新硬件为例,说明开发和移植所需的具体步骤:

  1. 进入 U-Boot 源码树

    首先进入 U-Boot 的源码目录,并导航到 configs 子目录。

  2. 复制基础配置文件

    使用现有的 hobot_x5_auto_defconfig 作为基础配置文件,为新硬件生成专属配置文件。例如,对于一个名为 som 的核心板,可以按以下命令命名新的配置文件为 hobot_x5_som_defconfig

    cd configs
    cp hobot_x5_auto_defconfig hobot_x5_som_defconfig
    
  3. 修改配置项

    根据新硬件的产品设计需求,编辑 hobot_x5_som_defconfig 文件,调整其中的配置项,例如启动参数、存储接口、外设支持等内容,以适配硬件特性。

4.2.3.3. 新增软件 Board ID 的定义

在适配新硬件时,需要为其分配一个唯一的 Board ID,以区分不同硬件平台。 硬件 Board ID 通过 ADC 通道的电压值读取出来的硬件识别信息。为了增强灵活性和适配性,系统还需要定义 软件 Board ID软件 Board ID 会映射到 硬件 Board ID

以创建一个名为 som 的新硬件为例,说明新增软件 Board ID 的步骤:

修改 Kconfig 文件

drivers/horizon/Kconfig 文件中,为新硬件添加一个 choice 项,用于选择新硬件的 Board ID。以下是示例代码:

config HOBOT_X5_SOM
        bool "X5SOM"
        help
          Select this option for Board Type X5 SOM.

该选项允许在编译时选择新硬件类型 X5 SOM

修改 Board ID 的宏定义

include/dt-bindings/board/hb_board_id.h 文件中:

  • 新增软件 Board ID 的宏定义

    为新硬件分配一个唯一的 ID,例如:

    #define HOBOT_X5_SOM_ID 0x2000
    
  • 添加宏条件判断

    将新的宏定义与对应的配置选项绑定,确保系统在识别硬件时正确加载相应的 Board ID。示例如下:

    #if defined(CONFIG_HOBOT_X5_FPGA)
        #define HOBOT_X5_BOARD_ID HOBOT_X5_FPGA_ID
    #elif defined(CONFIG_HOBOT_X5_EVB)
        #define HOBOT_X5_BOARD_ID HOBOT_X5_EVB_ID
    #elif defined(CONFIG_HOBOT_X5_SOM)
        #define HOBOT_X5_BOARD_ID HOBOT_X5_SOM_ID
    #elif !defined(CONFIG_HOBOT_ADC_BTYPE)
        #define CONFIG_HOBOT_ADC_BTYPE
    #endif
    

避免软件 Board ID 冲突

官方 BSP 中使用 0x0000 ~ 0x1FFF 范围的软件 Board ID。为避免与 BSP 的后续更新发生冲突,建议用户新增的软件 Board ID 避免使用此范围,推荐分配范围在 0x2000 及以上

检查新增内容

使用 git diff 检查代码改动,确保新增内容正确且完整。例如:

diff --git a/include/dt-bindings/board/hb_board_id.h b/include/dt-bindings/board/hb_board_id.h
index 8ed2b921ee..b12f4b5505 100644
--- a/include/dt-bindings/board/hb_board_id.h
+++ b/include/dt-bindings/board/hb_board_id.h
@@ -13,6 +13,7 @@
 #define HOBOT_X5_EVB_ID    0x0201
 #define HOBOT_X5_EVB_V2_ID 0x0202
 #define HOBOT_X5_RDK_ID    0x0301
+#define HOBOT_X5_SOM_ID    0x2000

 #if defined(CONFIG_HOBOT_X5_FPGA)
     #define HOBOT_X5_BOARD_ID HOBOT_X5_FPGA_ID
@@ -24,6 +25,8 @@
     #define HOBOT_X5_BOARD_ID HOBOT_X5_EVB_ID
 #elif defined(CONFIG_HOBOT_X5_EVB_V2)
     #define HOBOT_X5_BOARD_ID HOBOT_X5_EVB_V2_ID
+#elif defined(CONFIG_HOBOT_X5_SOM)
+    #define HOBOT_X5_BOARD_ID HOBOT_X5_SOM_ID
 #elif !defined(CONFIG_HOBOT_ADC_BTYPE)
     #define CONFIG_HOBOT_ADC_BTYPE
 #endif

硬件 Board ID 和软件 Board ID 的关系

  • 硬件 Board ID 是通过 ADC 通道的电压值,读取的唯一标识,用于启动时识别硬件平台。

  • 软件 Board ID 是在开发和编译过程中定义与硬件 Board ID 有映射关系的软件定义。

通过这种方式,硬件和软件 Board ID 的结合能够灵活适配不同的硬件平台,同时支持定制化功能开发。

4.2.3.4. 新增 U-Boot 下的设备树

以创建一个名为 som 的新硬件为例,说明为其添加设备树定义的步骤:

创建设备树文件

进入 U-Boot 的设备树目录 arch/arm/dts,复制现有的 x5-soc.dtsi 文件并命名为 x5-som.dtsi

cd arch/arm/dts
cp x5-soc.dtsi x5-som.dtsi

在新文件 x5-som.dtsi 中修改以下内容:

  • 修改 supported-btype 节点的值为 HOBOT_X5_SOM_ID (在新增软件 Board ID 的定义章节中添加的定义)。

btype-dev = &board_type;
supported-btype =
        <
        HOBOT_X5_SOM_ID
        >;
  • 把 x5-som.dtsi 文件中所有的 x5_soc 替换为 x5_som

在主设备树文件中添加新文件

将新增的 x5-som.dtsi 文件包含到主设备树文件 arch/arm/dts/x5.dtsi 中。在文件末尾添加如下内容:

#include "x5-soc.dtsi"
#include "x5-som.dtsi"

修改 board_type 配置

arch/arm/dts/x5.dtsi 文件中,更新 board_type 节点以支持新的硬件 Board ID,步骤如下:

  1. board_type_array 中新增 HOBOT_X5_SOM_ID 的定义。例如新增 <51 140 151 240 HOBOT_X5_SOM_ID 5 0 0 1 4>

    board_type: board_type {
            compatible = "hobot,btype";
            adc_dev = &adc, &adc;
            adc_channel = <0 1>;
            board_type_array =
                            ... ( 省略 ) ...
                            <51 140 151 240 HOBOT_X5_SOM_ID 5 0 0 1 4>,
                            ... ( 省略 ) ...
            hardware_array = "x5-fpga", "x5-soc", "x5-svb", "X5_EVB_LP4", "X5_EVB_LP4X", "X5-SOM";
            ethact_array = "default";
            net_eth0_ipaddr = "192.168.1.10";
            pmic_type = "dual-pmic", "single-pmic";
            board_version = "1_A", "1_B", "V1P2", "V1P3", "V0P1";
    };
    
  2. 确保 hardware_array 中新增对应的硬件名称 "X5-SOM"

    hardware_array = "x5-fpga", "x5-soc", "x5-svb", "X5_EVB_LP4", "X5_EVB_LP4X", "X5-SOM";
    

board_type_array 中的各字段含义如下:

  • 前 4 个字节定义了 ADC 通道的电压值范围,用于硬件识别:

    • 51 140:对应 ADC_VINS0 通道的电压范围( 51 ~ 140 mV),用于区分硬件类型。硬件上的分压电路将电压分压至 100 mV 左右,设置该范围以适应可能的电压波动。

    • 151 240:对应 ADC_VINS1 通道的电压范围( 151 ~ 240 mV),用于区分硬件版本。硬件上的分压电路将电压分压至 200 mV 左右,设置该范围以适应可能的电压波动。

  • 第 5 个字节表示软件 Board ID ( HOBOT_X5_SOM_ID)

    • 硬件与软件 Board ID 的绑定逻辑如下:

      如果 U-Boot 选项中启用 CONFIG_HOBOT_ADC_BTYPE,系统会通过 hb-btype.c 驱动读取硬件板卡的 ADC 通道电压值,并与设备树 board_type_array 中定义的电压值范围进行匹配,以确定对应的硬件类型和硬件版本。匹配成功后,系统会将硬件 Board ID 映射为对应的软件 Board ID,用于后续的设备识别和适配。

      例如,对于 board_type_array 定义 <51 140 151 240 HOBOT_X5_SOM_ID 5 0 0 1 4>,当硬件的 ADC_VINS0 通道检测到电压值在 51 ~ 140 mV 范围内,且 ADC_VINS1 通道检测到电压值在 151 ~ 240 mV 范围内时,系统会识别当前硬件为 HOBOT_X5_SOM_ID

  • 其他字段含义

    HOBOT_X5_SOM_ID 开始,每个字段对应不同的硬件特性配置数组,数字代表对应数组的下标:

    • 硬件型号命名 (hardware_array)

    • 以太网配置 (ethact_array)

    • IP 地址 (net_eth0_ipaddr)

    • 硬件使用的单个 PMIC 还是双 PMIC (pmic_type),绝大部分情况都只使用 single-pmic

    • 硬件版本 (board_version)

    例如 <51 140 151 240 HOBOT_X5_SOM_ID 5 0 0 1 4> 中的 5 对应 hardware_array 中的 X5-SOM,其他字段同理。

注意事项

  • 字符串长度限制

    hardware_array 和 board_version 中的字符串会传递到 Kernel 的设备树中,影响 socinfo 驱动的以下字段:

    • hw_name

    • board_version

    • hw_info

​ 需确保字符串长度不超过 Kernel 中的占位符限制,否则会导致 socinfo 驱动加载失败。

  • 必要调整

    如果字符串长度超出限制,请同时更新 Kernel 的设备树占位符,具体参考 boardinfo 调试指南

4.2.3.5. 在 U-Boot 配置中应用 Board ID

完成新硬件的 Board ID 定义、选项配置文件、设备树修改后,需要重新配置 U-Boot,以设置 CONFIG_HOBOT_X5_SOM 宏为新增的 Board ID。以下是详细步骤:

使用新增的选项配置文件

执行以下命令,加载新硬件的配置文件:

make ARCH=arm hobot_x5_som_defconfig
make ARCH=arm menuconfig
Location:
       -> Device Drivers
     (1)   -> Horizon SOC drivers

menuconfig 界面中,导航至 Horizon SOC drivers,选择与新硬件对应的 Board ID(如 HOBOT_X5_SOM),确保配置正确:

uboot_boardid

保存配置

menuconfig 界面中保存已配置的选项,然后使用以下命令将最简洁的选项保存到配置文件中:

# 使用 savedefconfig 保存最小化的配置项
make ARCH=arm savedefconfig

# 对比修改内容(如果使用 git 管理代码,可以跳过此步骤,直接使用 git diff 查看修改)
diff defconfig configs/hobot_x5_som_defconfig

# 确认无误后,将配置覆盖到源文件
cp defconfig configs/hobot_x5_som_defconfig

通过上述步骤,您已成功将新增的 Board ID 应用到 U-Boot 配置中,并为新硬件适配做好准备。

4.2.4. 在 Kernel 下新增硬件

相对于 U-Boot,在 Kernel 中新增硬件支持有以下区别和特点:

  • 不需要再定义 Board ID, U-Boot 下的定义会直接传导过来

  • U-Boot 下的设备树配置更加简单,只需保证基本的初始化和引导系统启动。 Kernel 负责操作系统加载后硬件功能的全面管理,配置文件和设备树更细致,涵盖了完整的外设驱动支持(如 GPIO、 I2C、 SPI、显示设备)和功能模块的使能 / 禁用。

  • Kernel 下增加的设备树文件全都可以独立编译成 DTB 文件,用户可以选择使用。 U-Boot 下的设备树文件都包含在一个 DTB 文件中,驱动根据硬件 Board ID 完成匹配。

4.2.4.1. 新增 Kernel 配置文件

进入 Kernel 源码树后,导航到配置文件目录 arch/arm64/configs,复制现有的 hobot_x5_soc_defconfig 文件并重命名为新硬件的配置文件(例如 hobot_x5_som_defconfig):

cd arch/arm64/configs
cp hobot_x5_soc_defconfig hobot_x5_som_defconfig

根据产品设计需求,修改该文件中的配置项以适配新硬件。

4.2.4.2. 新增设备树

Kernel 设备树文件位于目录 arch/arm64/boot/dts/hobot,目录结构如下:

.
├── Makefile
├── pinmux-func.dtsi
├── pinmux-gpio.dtsi
├── x5-evb-lp4-1_a.dts
├── x5-evb-lp4-1_b.dts
├── x5-evb-lp4-v1p2.dts
├── x5-evb-lp4-v1p3.dts
├── x5-evb-lp4-v2p0.dts
├── x5-evb-lp4x-v0p1.dts
├── x5-evb.dtsi
├── x5-fpga.dts
├── x5-md-v0p1.dts
├── x5-md-v0p2.dts
├── x5-memory.dtsi
├── x5-rdk-v1p0.dts
├── x5-rdk.dts
├── x5-rdk.dtsi
├── x5-som.dts
├── x5-svb.dts
└── x5.dtsi
  • pinmux-func.dtsi:定义各个 PIN 的功能组。板级设备树 .dts 文件通过以下方式包含:

    #include "pinmux-func.dtsi"
    
  • pinmux-gpio.dtsi:定义 GPIO 组,用户可直接引用具体 GPIO 组(PINGRP)。

  • x5.dtsi:定义 X5 平台上所有模块的默认配置,作为底层功能描述,不建议用户修改里面配置。

  • x5-evb.dtsi: 定义了不同 EVB 硬件版本间的通用配置项,包含 x5.dtsi 的默认配置。

  • x5-<板级产品>.dts:板级产品设备树文件,包含 x5.dtsi 的默认配置,同时完成功能模块的启用 / 禁用和与硬件强相关外设的定义。 EVB 相关的 dts 配置是包含 x5-evb.dtsi, 然后在 dts 里面描述有差异的配置项。

以现有设备树文件为模板,新建新硬件的设备树文件,例如:

cd arch/arm64/boot/dts/hobot
cp x5-evb-lp4-1_b.dts x5-som.dts

根据新硬件的设计需求,修改 x5-<new_board>.dts 文件的内容,确保正确配置外设和模块。

4.2.4.3. 模块默认状态说明

  • 外设及显示相关模块默认不使能

  • 图像处理及其他基础模块默认使能

  • 低速总线默认不使能,用户根据硬件设计进行开启

4.2.4.4. 编辑板级设备树

在板级设备树文件 x5-< 板级产品 >.dts 中:

  1. 引用所有基础 dtsi 文件

    设备树文件需要直接包含板级产品相关的所有 dtsi 文件。例如:

    #include "x5.dtsi"
    
  2. 配置时钟源和内存分布

    定义当前硬件的时钟源频率、内存分布。

  3. 定义外设和模块配置

    将外设及其他模块的具体配置写入对应的 dtsi 文件,并根据硬件设计需求调整启用状态。

4.2.4.5. 软件 Board ID 与设备树( DTB)的匹配说明

在内核中,设备树( DTS)需要与 Board ID 进行关联,以确保系统能够正确加载适配当前硬件的设备树。以下以 SOM 硬件为例,说明如何完成 Board ID 与设备树的匹配配置。

配置 its 文件以新增设备树

在内核镜像的 fit 包中,需要修改对应的配置文件。路径: device/horizon/x5/board_cfg/soc/boot_its/x5-common.its

  1. 将新增的设备树文件(如 x5-som.dts 生成的 x5-som.dtb)打包到 boot.img 中。 在 its 文件中按以下格式添加设备树配置项:

    /dts-v1/;
    / {
            description = "U-Boot FIT for x5";
            #address-cells = <1>;
    
            images {
            	... ( 省略 ) ...
                fdt2 {
                        description = "FDT-SOM";
                        data = /incbin/("x5-som.dtb");
                        type = "flat_dt";
                        arch = "arm64";
                        compression = "none";
                        /*
                        hash-1 {
                                algo = "sha1";
                        };
                        */
                };
                ... ( 省略 ) ...
           };
           ... ( 省略 ) ...
    }
    
  2. configurations 节中,将 Board ID 与设备树关联:

    /dts-v1/;
    / {
            description = "U-Boot FIT for x5";
            #address-cells = <1>;
    
            ... ( 省略 ) ...
            configurations {
                    default = "boardid-0x0201";
                    ... ( 省略 ) ...
                    boardid-0xFE01 {
                            description = "x5-som";
                            kernel = "kernel";
                            fdt = "fdt2";
                    };
                    ... ( 省略 ) ...
            };
    };
    

注意事项

  1. Board ID 格式:

    • 配置项中的 boardid-0x0201 对应 U-Boot 中新增的 Board ID,例如 HOBOT_X5_SOM_ID 的值。

    • boardid-0x0201 会在 U-Boot 中被解析为字符串形式。 如果 Board ID 中包含字母,必须 使用大写字母,如 0xff10 应写作 0xFF10

  2. FDT 参数:

    • fdt 字段需要对应新增的设备树配置项名称。例如,boardid-0xFE01 使用 fdt2,即 x5-som.dtb

U-Boot 引导内核流程

在系统启动过程中, U-Boot 会根据当前硬件的 Board ID 选择对应的内核和设备树。引导命令如下:

bootm ${kernel_addr}#boardid-${hb_board_id}

此命令中,${hb_board_id} 为当前硬件的软件 Board ID 值。 U-Boot 根据软件 Board ID 匹配到 its 文件中的 fdt 配置,加载正确的设备树与内核。

4.2.5. 调试最小系统

在设备上电后,用户可通过调试串口检查是否有日志输出。如果没有日志输出,请检查以下问题:

  • 芯片供电是否正常

  • BOOTSEL 管脚配置是否正确

  • 调试串口与 PC 终端软件波特率是否匹配

4.2.5.1. 空片状态下的串口日志

当设备为空片状态时,芯片上电后的串口日志如下所示,最终进入 DFU 下载模式:

SNOTICE:  Welcome to Horizon X5 ASIC BOOTROM - V4.1
NOTICE:                 OTP config:
NOTICE:                         otp exist: true
NOTICE:                         test region size: 304
NOTICE:                         secure region size: 120
NOTICE:                         none secure region size: 56
NOTICE:   Enable MMU
NOTICE:  Booting Trusted Firmware
NOTICE:  BL1: v2.8(release):
NOTICE:  BL1: Built : 17:42:12, Oct 19 2023
NOTICE:  Enter eMMC Mode......
NOTICE:  USER AREA.
NOTICE:   eMMC clk_rate = CLK_12_5M
NOTICE:   eMMC emmc_data_width == WIDTH_DATA_1
NOTICE:   eMMC emmc_cfg.emmc_clk_latch == CLK_FALLING
NOTICE:  Enter media_source_select process(1).
ERROR:   horizon_emmc_read_blocks fail!!   checksum = 0x0 (0x0) 0x0
ERROR:    plat_error_handler 0
... ( 省略部分日志 ) ...
NOTICE:  Enter eMMC Mode......
NOTICE:  USER AREA.
NOTICE:   eMMC clk_rate = CLK_12_5M
NOTICE:   eMMC emmc_data_width == WIDTH_DATA_1
NOTICE:   eMMC emmc_cfg.emmc_clk_latch == CLK_FALLING
NOTICE:  Currtenly use dfu-util to download file
NOTICE:  Download file via USB
NOTICE:  DFU Start...

4.2.5.2. 系统刷机

确认设备可以正常输出日志后,用户可将预先制作好的最小系统烧录到设备中。具体的刷机方法详见: 系统镜像烧写

若刷机后系统启动异常,可根据故障阶段进行逐步调试。

4.2.5.3. 各阶段启动调试

1. miniboot 启动异常

miniboot 负责完成 DDR 的初始化( Training),并按顺序加载 BL2BL31U-Boot,最终跳转到 U-Boot。若 miniboot 启动失败,可能的原因包括:

  • 镜像打包错误

  • eMMC 或 Nand Flash 无法正确识别或数据读写失败

  • DDR Training 未通过

  • U-Boot 加载异常

2. U-Boot 启动异常

U-Boot 用于引导 Linux 内核,启动失败的常见原因如下:

  • Kernel 分区加载异常

  • cmdline 参数配置错误

调试时,可通过 U-Boot 的日志确定具体问题。此外,应结合硬件设计确认常用模块功能是否正常,如网口、 USB 接口等。

确认 USB Device 功能 在 U-Boot 中切换到 Fastboot 模式,通过主机查看设备是否被识别:

Hobot> fastboot 0
select emmc(0) as flash medium
do fastboot usb

3. Kernel 启动异常

若内核启动异常,可按以下步骤检查:

  • 检查内核启动日志: 确认内核模块和设备驱动初始化正常

  • 检查文件系统挂载: 确认根文件系统、appuserdata 分区是否挂载成功

  • 检查终端登录: 确认系统可正常进入 Shell 终端,并通过串口登录

  • 检查外设功能: 确认网络接口和 USB 接口工作正常

4.2.6. 系统稳定性测试

完成硬件点亮后,需要针对新硬件的各个主要模块进行稳定性和压力测试,详细压测方法请参考 驱动功能单元测试