5. 开发样例

HDML提供下面接口示例:

  • hm_dvfs_example.c: 展示如何设置后摩设备DVFS模式。

  • hm_fw_upgrade_example.c: 展示如何升级后摩设备固件镜像。

  • hm_sys_info_examples.c: 展示如何获取后摩设备状态信息。

开发样例位于:

  • Linux 环境: 安装后摩驱动后即可获得该头文件,路径为 ${HOUMO_SDK_PATH}/hal/export/samples,其中 ${HOUMO_SDK_PATH} 表示驱动的安装目录。默认安装路径为 /usr/local/houmo-sdk

  • Android 环境: 后摩驱动安装包内,路径为:

    houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2/hal/export/export/samples

5.1. 示例说明

5.1.1. 获取后摩设备状态信息

hm_sys_info_examples.c 示例展示如何获取后摩设备状态信息。示例代码基本覆盖所有HMDML支持的接口,其中主要接口说明如下:

  • 调用 hm_sys_get_device_info,获取后摩设备的逻辑ID和逻辑设备数量。每个后摩M50芯片被识别为一个独立的逻辑设备,单个后摩设备中可能包含多个逻辑设备。HMDML 接口的所有操作均以逻辑设备为单位进行管理和配置。

  • 调用 hm_sys_get_ipu_utili_rate,获取后摩设备IPU内核实时平均利用率。

  • 调用 hm_sys_get_core_count,获取后摩设备IPU内核总数。

  • 调用 hm_sys_get_ipu_frequency,获取后摩设备的 IPU 内核实时平均频率。

  • 调用 hm_sys_get_ipu_voltage,获取后摩设备的 IPU 内核实时平均电压。

  • 调用 hm_sys_get_mem_info,获取后摩设备的内存信息,包括内存总容量、已使用容量和未使用容量。

  • 调用 hm_sys_get_temperature,获取后摩设备实时温度。

  • 调用 hm_sys_get_bdf,获取后摩设备PCIe BDF。

  • 调用 hm_sys_get_board_power,获取后摩设备板卡实时功耗。

  • 调用 hm_sys_get_dvfs_mode,获取后摩设备当前使用的DVFS模式。

5.1.2. 获取和设置后摩设备DVFS模式

hm_dvfs_example.c 示例展示如何获取和设置后摩设备DVFS模式。示例代码中主要接口如下:

  • 调用 hm_sys_get_dvfs_mode,获取后摩设备当前使用的DVFS模式。

  • 调用 hm_sys_set_dvfs_mode,设置后摩设备的DVFS模式。

5.1.2.1. 参数说明

编译生成示例程序后,运行可执行文件时需指定以下参数:

  • get:查询并返回当前系统中所有逻辑设备的DVFS模式。

  • set <mode> <dev_index>:将指定逻辑设备(<dev_index>)的 DVFS 工作模式设置为 <mode><mode> 支持以下取值:

    • performance:IPU 内核始终运行在最大频率下。

    • ondemand:根据 IPU 内核的实时利用率,在指定的频率范围内,动态调整 IPU 内核运行的频率。

    DVFS模式详细说明可参看《后摩大道® 功耗和热管理使用指南》。

5.1.3. 升级后摩设备固件

hm_fw_upgrade_example.c 示例展示了固件镜像升级完整流程,覆盖单设备与多设备场景,并提供多种执行模式,满足不同应用对阻塞行为、并发能力和线程控制方式的需求。

5.1.3.1. 示例参数说明

镜像升级示例程序支持通过命令行参数指定升级模式、目标设备以及固件镜像路径:

<executable> -m <mode> -d <device(s)> -f <firmware_path>

其中 <executable> 表示用户编译生成的示例程序可执行文件。

参数说明如下:

  • -m <mode>:指定单个逻辑设备升级的执行模式。可选取值如下:

    • sync:单个逻辑设备同步升级。

    • async:单个逻辑设备异步升级。

    • custom:单个逻辑设备自定义线程升级。

  • -d <device(s)> 指定参与升级的目标逻辑设备。可设置 -d all 升级当前所有逻辑设备。

  • -f <firmware_path> 指定待升级的固件镜像文件路径。

注意事项

  • 固件升级以逻辑设备(即单颗 M50 芯片)为基本单元。详情参看 M50系列产品概览

  • 升级操作支持指定多个逻辑设备或所有逻辑设备(all),当针对多个逻辑设备执行升级时,示例将按顺序自动轮询并逐一完成各芯片的升级。

  • 当仅升级单个逻辑设备时,必须通过 -m 参数指定升级模式。

  • 当升级多个逻辑设备或所有逻辑设备时,示例程序自动进入多逻辑设备并行升级流程,此时 -m 参数不生效,无需指定。

示例

示例如下:

Single-device: <executable> -m sync -d 0 -f ./firmware.img
Multi-devices: <executable> -d 0,1 -f ./firmware.img
All devices: <executable> -d all -f ./firmware.img

5.1.3.2. 单个逻辑设备同步升级

采用阻塞方式执行升级流程。升级操作在当前线程中完成,调用返回前升级流程不会结束。该方式实现简单,流程清晰,无需额外线程管理,适用于对升级过程无并发要求的场景。

升级步骤如下:

  1. 下载固件镜像

  2. 调用 hm_fw_upgrade_init 初始化升级环境。

  3. 调用 hm_fw_upgrade_execute 升级镜像。

  4. 调用 hm_fw_upgrade_deinit 释放升级资源。

详情参看示例代码中 upgrade_device_sync 接口。

5.1.3.3. 单个逻辑设备异步升级

通过接口启动升级后,用户可周期性查询升级进度与结果。该方式无需用户自行创建线程,并支持进度轮询与状态查询。适用于需要保持主线程响应,需要实时获取升级进度的应用。

升级步骤如下:

  1. 下载固件镜像

  2. 调用 hm_fw_upgrade_init 初始化升级环境。

  3. 调用 hm_fw_upgrade_start 启动异步升级任务。

  4. 调用 hm_fw_upgrade_get_progress 查询升级进度。

  5. 调用 hm_fw_upgrade_get_result 查询升级结果。

  6. 调用 hm_fw_upgrade_deinit 释放升级资源。

详情参看示例代码中 upgrade_device_async 接口。

5.1.3.4. 单个逻辑设备自定义线程升级

用户自行创建线程,在自定义线程中调用同步升级接口执行升级流程。该方式下线程模型完全由用户控制。适用于已有统一线程管理框架,需要将升级流程纳入既有调度体系的应用。

升级步骤如下:

  1. 下载固件镜像

  2. 调用 hm_fw_upgrade_init 初始化升级环境。

  3. 调用 hm_fw_upgrade_execute 执行镜像升级。

  4. 调用 hm_fw_upgrade_get_progress 查询升级进度。

  5. 调用 hm_fw_upgrade_deinit 释放升级资源。

详情参看示例代码中 upgrade_device_custom_thread 接口。

5.1.3.5. 多个逻辑设备并行升级

对多个逻辑设备同时执行升级操作。需为每个逻辑设备独立创建升级上下文,并行执行升级流程。该方式支持同时升级多个逻辑设备,单个逻辑设备升级失败不影响其他设备执行。适用于产品中包含多颗M50芯片的固件升级场景。

升级步骤如下:

  1. 下载固件镜像

  2. 调用 hm_sys_get_device_info

  3. 调用 hm_fw_upgrade_init 初始化升级环境。

  4. 调用 hm_fw_upgrade_start 启动异步升级任务。

  5. 调用 hm_fw_upgrade_get_progress 查询升级进度。

  6. 调用 hm_fw_upgrade_get_result 查询升级结果。

  7. 调用 hm_fw_upgrade_deinit 释放升级资源。

详情参看示例代码中 upgrade_device_custom_thread 接口。

5.2. 运行示例

5.2.1. Android终端

下面介绍如何在Android终端编译与运行示例代码。

执行下面步骤运行示例:

  1. 完成 环境准备

  2. 安装驱动。详情参看《后摩大道® 软件平台驱动安装指南》。

  3. 完成 镜像升级

  4. 在Linux主机端,创建 examples 文件夹,并在该文件夹下包括下面文件:

    • 头文件:hm_sys.hhm_api.h。头文件位于驱动安装包中:

      houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2/hal/export/include

    • 库文件:libhal_xh2a.alibhal_xh2a.so。该库位于驱动安装包中:

      houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2/hal/lib

    • 示例源码文件,如 hm_sys_info_examples.c。示例位于驱动安装包中:

      houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2/hal/export/samples

  5. examples 目录下创建构建脚本。用户需创建一个 CMake 构建脚本,用于在主机端编译生成可执行文件。示例文件名为 CMakeLists.txt,主要配置内容如下:

    1. 设置 CMake 工程信息与 C++ 标准。

      • 指定 CMake 最低版本和工具链文件。

      • 设置 C++ 标准为 C++17,并开启调试信息。

    2. 配置 Android 平台信息。

      • ANDROID_NDK :替换为主机端实际 NDK 安装路径。

      • ANDROID_PLATFORM :指定 Android API 版本,例如 android-24。

      • ANDROID_ABI :指定目标架构,例如 arm64-v8a。

      • 设置 Android STL 为共享库 c++_shared

    3. 设置 HAL 库及头文件路径:

      • HAL_LIBRARY :替换为主机端驱动动态库 libhal_xh2a.so 的路径。

      • 通过 include_directories 指定头文件路径,例如工程通用头文件 ${CMAKE_BINARY_DIR}/../../common 和 Android 系统头文件 ${ANDROID_NDK}/sysroot/usr/include

    4. 添加可执行文件并链接库。

      • 通过 add_executable 设置输出可执行文件名和示例源码文件,如 hm_sys_info_examples.c

      • 通过 target_link_libraries 链接 HAL 动态库,实现驱动接口调用。

    完整示例如下,示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。

    cmake_minimum_required(VERSION 3.16)
    
    # Android特定配置 - 需通过命令行传入ANDROID_NDK路径
    if(NOT ANDROID_NDK)
        message(FATAL_ERROR "请通过-DANDROID_NDK=指定NDK路径")
    endif()
    set(CMAKE_TOOLCHAIN_FILE ${ANDROID_NDK}/build/cmake/android.toolchain.cmake)
    project(IpuTest)
    
    # 设置C++标准
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
    
    # 设置Android平台和架构
    if(NOT ANDROID_PLATFORM)
        set(ANDROID_PLATFORM android-24)  # 最低支持Android 7.0
    endif()
    
    if(NOT ANDROID_ABI)
        set(ANDROID_ABI arm64-v8a)  # 默认编译ARM64架构
    endif()
    
    # Android平台配置
    set(ANDROID_STL c++_shared)  # 使用共享STL
    set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE FALSE)
    
    # 设置库文件名称和搜索路径(Android平台)
    set(HAL_LIBRARY_NAMES hal_xh2a)
    set(LIB_SEARCH_PATHS
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/${ANDROID_ABI}/  # 按架构区分的库路径
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/  # 通用Android库路径
    )
    set(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)  # Android常用库后缀
    
    # 直接指定库文件绝对路径,替换所有 find_library 相关代码
    set(HAL_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/libhal_xh2a.so)
    if(NOT EXISTS ${HAL_LIBRARY})
        message(FATAL_ERROR "HAL库不存在:${HAL_LIBRARY}")
    endif()
    message(STATUS "找到HAL库: ${HAL_LIBRARY}")
    
    # 包含头文件目录
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    
    # 添加可执行文件
    add_executable(hm_sys_info_examples hm_sys_info_examples.c)
    
    # 链接库文件
    target_link_libraries(hm_sys_info_examples PRIVATE ${HAL_LIBRARY})
    
  6. examples 目录下,需要创建一个用于编译固件升级示例程序的 shell 脚本,并保存为 .sh 文件,例如 compile.sh。主要内容如下:

    1. 设置编译目录。在示例中,将编译产物输出到 build_android 目录。

    2. 示例中用户需根据实际环境修改变量值:

      • NDK_PATH :主机端 Android NDK 的实际安装路径。

      • HOUMO_SDK_PATH :主机端后摩驱动路径,通常位于驱动安装包中 houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2 目录下。

      • ANDROID_ABI :目标架构,如 arm64-v8a

      • ANDROID_PLATFORM :Android平台版本,如 android-27

    3. 执行 CMake 生成 Makefile,并通过 Make 编译生成可执行文件。

      完整示例如下,示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。

      #!/bin/bash
      
      # 配置编译目录
      BUILD_DIR=build_android
      rm -rf $BUILD_DIR
      mkdir -p $BUILD_DIR
      cd $BUILD_DIR
      
      # 关键:指定 NDK 路径(替换为你的实际 NDK 路径)
      NDK_PATH="/path/to/android-ndk-r27c"  # 例如:~/Android/Sdk/ndk/r27d
      HOUMO_SDK_PATH="/home/useradmin/wsy/houmo-drv-xh2/houmo-drv-xh2/"
      ANDROID_ABI="arm64-v8a"
      ANDROID_PLATFORM="android-27"
      
      # 执行 cmake 生成 Makefile(参数必须写在同一行,用空格分隔)
      cmake --fresh .. \
      -DANDROID_NDK=$NDK_PATH \
      -DANDROID_PLATFORM=android-27 \
      -DANDROID_ABI=arm64-v8a
      
      # 编译(-j4 表示使用 4 线程加速)
      make -j4
      
      # 回到原目录
      cd ..
      
  7. 编译生成可执行文件:

    cd examples
    chmod +x compile.sh
    ./compile.sh
    

    编译成功后,会在编译脚本中指定的输出目录中生成可执行文件。示例中,该目录为 build_android,可执行文件名称为 hm_sys_info_examples

  8. 传输文件至 Android 端。

    1. 将主机端的 examples 文件夹推送至 Android 端的 /data/houmo 目录:

      adb push examples /data/houmo
      
    2. 启动Android开发板并进入 shell 模式:

      adb shell
      su
      
  9. 配置环境变量。在 Android 端设置驱动库路径:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/houmo/houmo-drv-xh2/hal/lib
    
  10. 在 Android 端,进入 examples/build_android 目录:

    cd /data/houmo/examples/build_android
    
  11. 运行示例。执行以下命令运行示例:

    注意

    部分接口需要后摩设备的 eFuse 中有效数据。只有当 eFuse 已被编程后,才能获取计算能力。

    chmod +x hm_sys_info_examples
    ./hm_sys_info_examples <param>
    

部分示例需指定参数值 <param>,详情可参看示例运行提示信息。 hm_fw_upgrade_example.c 示例运行还需提供升级镜像等参数,详情参看 示例参数说明

5.2.2. Linux主机端

下面介绍如何在Linux环境下,编译与运行示例代码。

执行下面步骤运行示例:

  1. 完成 环境准备

  2. 安装驱动。详情参看《后摩大道® 软件平台驱动安装指南》。

  3. 烧写和升级后摩设备 固件 镜像。详情参看《后摩大道® HmUpdateTool 工具使用指南》。

  4. 在Linux主机端,创建 examples 文件夹,并在该文件夹下包括下面文件:

    • 头文件:hm_sys.hhm_api.h。头文件位于驱动安装后下面路径下:

      ${HOUMO_SDK_PATH}/hal/export/include

      其中 ${HOUMO_SDK_PATH} 表示驱动的安装目录。默认安装路径为 /usr/local/houmo-sdk

    • 库文件:libhal_xh2a.alibhal_xh2a.so。库文件位于驱动安装后下面路径下:

      ${HOUMO_SDK_PATH}/hal/lib

    • 示例源码文件,如 hm_sys_info_examples.c。示例位于驱动安装后下面路径下:

      ${HOUMO_SDK_PATH}/hal/export/samples

  5. examples 目录下创建构建脚本。用户需创建一个 CMake 构建脚本,用于编译生成示例的可执行文件。示例文件名为 CMakeLists.txt,主要配置内容如下:

    1. 设置 CMake 工程信息与 C++ 标准。

      • 指定 CMake 最低版本和工具链文件。

      • 设置 C++ 标准为 C++17,并开启调试信息。

      • 启用调试信息并链接 pthread 库。

    2. 设置 HAL 库及头文件路径:

      • 通过变量 HAL_LIBRARY 指定驱动动态库 libhal_xh2a.so 的完整路径。

      • 通过 include_directories 指定 hm_sys.h 头文件路径。

    3. 添加可执行文件并链接库。

      • 通过 add_executable 设置输出可执行文件名和示例源码文件,如 hm_sys_info_examples.c

      • 通过 target_link_libraries 链接 HAL 动态库和 pthread 库,以支持驱动接口调用和多线程能力。

    完整示例如下,示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。

    cmake_minimum_required(VERSION 3.10)
    project(HmsysTest)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -pthread")
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    set(HAL_LIBRARY "/path/to/houmo_drv_xh2_<release>/hal/lib/libhal_xh2a.so")
    if(NOT HAL_LIBRARY)
    message(FATAL_ERROR
        "HAL dynamic library (libhal_xh2a.so) not found in ${LIB_SEARCH_PATHS}! \n"
        "Please check if libhal_xh2a.so exists in the directory."
    )
    endif()
    message(STATUS "Found HAL dynamic library: ${HAL_LIBRARY}")  # 确认找到 .so 文件
    # 包含头文件目录
    include_directories(/path/to/houmo_drv_xh2_<release>/hal/export/include)
    # 添加可执行文件
    add_executable(device_retrieve "/path/to/houmo_drv_xh2_<release>/hal/export/samples/hm_sys_info_examples.c")
    # 链接动态库和 pthread
    target_link_libraries(device_retrieve PRIVATE ${HAL_LIBRARY} pthread)
    
  6. examples 目录下创建构建目录并进入该目录:

    cd examples
    rm -rf *
    mkdir build
    cd build
    
  7. 生成构建文件:

    cmake ..
    
  8. 编译生成可执行文件:

    make -j4
    

    编译完成后,将在 build 目录下生成可执行文件 device_retrieve

  9. build 目录下执行以下命令运行示例程序:

    注意

    部分接口需要后摩设备的 eFuse 中有效数据。只有当 eFuse 已被编程后,才能获取计算能力。

    ./device_retrieve <param>
    

部分示例需指定参数值 <param>,详情可参看示例运行提示信息。 hm_fw_upgrade_example.c 示例运行还需提供升级镜像等参数,详情参看 示例参数说明