ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Halide 裸机(Baremetal)交叉编译实战:HelloBaremetal 无 OS 目标移植指南

Halide 裸机(Baremetal)交叉编译实战:HelloBaremetal 无 OS 目标移植指南 编译器图像处理编程语言高性能计算【免费下载链接】Halidea language for fast, portable>项目地址https://gitcode.com/gh_mirrors/ha/Halide点击查看免费下载本篇技术指南以 Halide 仓库中的apps/HelloBaremetal示例应用为核心系统讲解如何将 Halide 生成的函数交叉编译到没有操作系统的裸机baremetal目标平台上运行覆盖工具链配置、三种 CMake 交叉编译组织方式、NEON 启动引导与 QEMU 半主机semihosting仿真运行。读完本文你将掌握arm-32-noos-semihosting这类 Halide Target 的实际用法并具备把任意 Halide 生成器Generator移植到裸机环境、借助ctest在模拟器上自动化验证的完整实战能力。一、示例定位为什么需要 HelloBaremetalapps/HelloBaremetal/README.md开篇即点明其定位这是一个示例应用用来演示如何将 Halide 生成的函数与应用程序一起交叉编译cross-compile到没有操作系统的裸机目标系统上运行。Halide 通常被用于生成高性能的本地代码其运行目标大多是有 OS 的平台Linux、Android、macOS 等由 OS 提供线程调度、动态链接、内存管理等能力。但裸机环境恰恰相反没有进程、没有线程std::thread与 Halide 的parallel()调度均不可用没有 libdl、没有共享库运行时无法动态加载标准 C 库newlib能力有限PNG/JPEG 这类依赖外部库的图像格式不可直接使用连 NEON/VFP 浮点单元默认都是关闭的需要上电引导阶段手动开启。HelloBaremetal 的价值就在于用一份完整的、可运行的代码把上述所有坑位全部趟平并沉淀为三种可复用的 CMake 组织范式供真实项目照搬。二、验证过的开发环境SetupREADME 明确指出裸机系统千差万别本示例只针对其中一种经过验证的配置组合并非通用万能。其测试条件如下项目版本/规格编译工具链Arm GNU Toolchain 12.2AArch32 bare-metal 目标arm-none-eabi目标 CPUArm 32 位、带 NEON 的 Cortex-A9运行平台Arm Realview 开发板QEMU Arm System 模拟器版本 7.2.50运行模式semihosting 半主机模式目标与宿主之间具备有限 I/O例如printf()可输出到 stdout关键结论semihosting 是这个示例能跑起来 能看到输出的前提。因为裸机没有终端设备输出必须借道宿主机。而 Halide 运行时为此专门提供了halide_target_feature_semihosting特性它与Target::NoOS组合使用正是为基于 semihosting 库构建、并以 semihosting 模式运行的裸机目标准备的见 src/runtime/HalideRuntime.h。由于无法依赖 OS 提供的抽象若你的目标平台不同README 也明确提醒很可能需要自行修改部分代码尤其是工具链文件中的 CPU 相关编译选项与启动引导代码。三、应用整体结构从源码看它做了什么先看apps/HelloBaremetal/目录的文件布局apps/HelloBaremetal/ ├── README.md # 本文所依据的说明文档 ├── add_generator.cpp # Halide Generator定义 add 算法与调度 ├── filter.cpp # 主程序读图 → 调用 add → 写图 ├── run_baremetal.sh # QEMU semihosting 运行脚本 ├── cmake/ │ ├── toolchain.noos-arm32-sample.cmake # 交叉编译工具链文件 │ └── noosrt.s # NEON 启动 trampoline entropy 桩 ├── cmake-twice/ # 方案一构建两次host target ├── cmake-super_build/ # 方案二ExternalProject 超级构建 └── cmake-external_project/ # 方案三ExternalProject IMPORTED 目标整个应用只做一件极其简单的事读入一张灰度图为每个像素加上一个偏移量再写回一张新图。算法如此简单恰恰是为了把交叉编译基础设施这一主题暴露到最大——读者应该把注意力放在构建组织方式上而不是算法本身。3.1 Generatoradd_generator.cppadd_generator.cpp 使用 Halide 的 Generator 框架定义算法class Add : public Halide::GeneratorAdd { public: InputBufferuint8_t, 2 input{input}; Inputuint8_t offset{offset}; OutputBufferuint8_t, 2 output{output}; void generate() { // Algorithm output(x, y) input(x, y) offset; // Dont care overflow/saturation } void schedule() { input.set_estimates({{0, 256}, {0, 426}}); output.set_estimates({{0, 256}, {0, 426}}); if (!using_autoscheduler()) { // NOTE: In baremetal, .parallel() doesnt make sense as thread support is unavailable. const int vector_width get_target().natural_vector_size(output.types()[0]); output .compute_root() .vectorize(x, vector_width); } } Var x{x}, y{y}; }; HALIDE_REGISTER_GENERATOR(Add, add)值得注意的裸机相关细节set_estimates为自动调度器提供边界估计输入/输出均为256×426的二维uint8_t缓冲与测试图片 apps/images/gray_small.pgm 的尺寸一致。禁用.parallel()源码注释明确指出在裸机环境中.parallel()没有意义因为没有线程支持。这是 Halide 调度代码里典型的平台约束分支。自动向量化利用get_target().natural_vector_size()获取当前 target 的原生向量宽度并vectorize(x, ...)。在arm-32-noos-semihosting目标上这会让内层循环使用 NEON 向量指令——前提是启动代码已把 NEON 打开见下文noosrt.s。自动调度器并行度置 1若使用自动调度器Mullapudi2016必须通过autoscheduler.parallelism1关闭并行CMake 配置中的PARAMS原因同样是裸机没有线程。3.2 主程序filter.cppfilter.cpp 是运行在目标机上的主程序int main(int argc, char **argv) { if (argc ! 4) { printf(Usage: %s in offset out\n, argv[0]); return 1; } // In baremetal target, some image file formats such as ppm/pgm are supported but others are not. // e.g. PNG and JPEG are unavailable unless you integrate your own libpng and libjpeg. Halide::Runtime::Bufferuint8_t, 2 input load_and_convert_image(argv[1]); Halide::Runtime::Bufferuint8_t, 2 output(input.width(), input.height()); uint8_t offset std::atoi(argv[2]); add(input, offset, output); convert_and_save_image(output, argv[3]); printf(Success!\n); return 0; }三个命令行参数in输入图像、offset偏移量、out输出图像。运行时通过 Halide 的halide_image_ioHalide::Tools命名空间完成 PPM/PGM 的读写。源码注释强调了一个容易被忽略的裸机限制在裸机目标上只有 ppm/pgm 等简单格式可用PNG 和 JPEG 不可用除非你自行集成 libpng 与 libjpeg。这是因为halide_image_io对 PNG/JPEG 的解析依赖外部编解码库而裸机环境默认不携带它们。四、构建三种 CMake 交叉编译方案逐一拆解与仓库中大多数应用不同apps/HelloBaremetal没有顶层CMakeLists.txt。目录下三个cmake-xxx子目录各自是独立的 CMake 工程直接构建即可。README 明确指出Halide 的 CMake 交叉编译很棘手本示例用具体代码演示了三种实现方式cmake-twice—— 构建两次cmake-super_build—— 超级构建super-buildcmake-external_project—— 直接使用ExternalProject三者背后的共同难题是CMake 很难在同一个构建树中同时为主机和目标平台编译而 Halide 的 Generator 可执行文件几乎总是必须在主机上运行因为它在编译期生成代码。关于交叉编译的一般方法论README 指引读者阅读 doc/HalideCMakePackage.md 的 Cross compiling 一节那里归纳了五种策略add_halide_generator两次构建、super-build、直接ExternalProject、借助CMAKE_CROSSCOMPILING_EMULATOR在模拟器/真机上跑 Generator、以及绕过 CMake 手动生成。下面三个方案正是前三种策略的具体落地。4.1 方案一cmake-twice构建两次核心思路先用宿主编译器构建 Generator并打包成find_package可发现的包再切换到交叉工具链构建应用此时只需导入之前构建好的 Generator 可执行文件并调用它。其 build.sh 脚本清晰地展示了两个阶段set -eo pipefail cd $(dirname ${BASH_SOURCE[0]}) readonly TOOLCHAIN_FILE${PWD}/../cmake/toolchain.noos-arm32-sample.cmake readonly GEN_PACKAGEHelloBaremetal-halide_generators export CMAKE_BUILD_TYPE${CMAKE_BUILD_TYPE:-Release} # Step 1: Build generator executable with host compiler # and export as a package for CMake find_package() cmake -S . -B build-host cmake --build build-host --target ${GEN_PACKAGE} # Step 2: Build application with cross compiler, # where the generator executable built in Step 1 is just imported and called cmake -S . -B build-target \ --toolchain ${TOOLCHAIN_FILE} \ -D${GEN_PACKAGE}_ROOT:FILEPATHbuild-host \ --fresh cmake --build build-target对应的 cmake-twice/CMakeLists.txt 中关键模式是find_package(Halide REQUIRED) # Setup Generator add_halide_generator(add.generator SOURCES ${SRC_DIR}/add_generator.cpp) # Generate filter function add_halide_library( add FROM add.generator GENERATOR add FEATURES debug # 在工具链文件设定的 target 之外追加特性 AUTOSCHEDULER Halide::Mullapudi2016 PARAMS autoscheduler.parallelism1 # baremetal 无线程关闭并行 ) add_executable(add_filter ${SRC_DIR}/filter.cpp) target_link_libraries(add_filter PRIVATE Halide::ImageIO add)要点解读主机侧构建build-hostadd_halide_generator生成add.generator构建目标HelloBaremetal-halide_generators即是把 Generator 打包导出为 CMake 包。目标侧构建build-target通过--toolchain指定交叉工具链文件-D${GEN_PACKAGE}_ROOT:FILEPATHbuild-host告知find_package去哪里找已构建好的 Generator 包。正如doc/HalideCMakePackage.md所描述的目标侧构建只需要find_package(Halide REQUIRED)它不会拉入编译好的 Halide 编译器而是优先导入宿主机构建的 generators 包。--fresh用于强制以交叉工具链重新配置避免缓存残留。4.2 方案二cmake-super_build超级构建核心思路最外层工程只负责协调用ExternalProject把Generator 子工程主机编译和应用子工程交叉编译隔离成两个独立的 CMake 工程两个工程通过约定好的 CMake 变量通信。外层 cmake-super_build/CMakeLists.txtinclude(ExternalProject) # The following variables are for 2 sub-projects to communicate. set(GEN_PACKAGE HelloBaremetal-add_generator) set(GEN_NAMESPACE HelloBaremetal::generators::) set(GEN_EXE add.generator) set(GEN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/generator) # Step 1: Build generator executable with host compiler in external child project # and export as a package for CMake find_package() ExternalProject_Add( gen_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/generator BINARY_DIR ${GEN_BINARY_DIR} INSTALL_COMMAND CMAKE_ARGS -DCMAKE_PREFIX_PATH${CMAKE_PREFIX_PATH} -DGEN_PACKAGE${GEN_PACKAGE} -DGEN_NAMESPACE${GEN_NAMESPACE} -DGEN_EXE${GEN_EXE} CONFIGURE_HANDLED_BY_BUILD TRUE ) # Step 2: Build application with cross compiler ExternalProject_Add( app_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/app BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/app INSTALL_COMMAND DEPENDS gen_project # 保证 generator 先就绪 CMAKE_ARGS -DCMAKE_PREFIX_PATH${CMAKE_PREFIX_PATH} -DCMAKE_TOOLCHAIN_FILE${APP_TOOLCHAIN_FILE} -DCMAKE_RUNTIME_OUTPUT_DIRECTORY${CMAKE_CURRENT_BINARY_DIR}/bin -D${GEN_PACKAGE}_ROOT:FILEPATH${GEN_BINARY_DIR} -DGEN_TARGET${GEN_NAMESPACE}${GEN_EXE} CONFIGURE_HANDLED_BY_BUILD TRUE )子工程 cmake-super_build/generator/CMakeLists.txt 接收GEN_EXE/GEN_PACKAGE/GEN_NAMESPACE三个变量并构建、导出 Generatoradd_halide_generator( ${GEN_EXE} SOURCES ${SRC_DIR}/add_generator.cpp PACKAGE_NAME ${GEN_PACKAGE} PACKAGE_NAMESPACE ${GEN_NAMESPACE} )子工程 cmake-super_build/app/CMakeLists.txt 在交叉工具链下导入 Generator 包并生成库find_package(Halide REQUIRED) # Import pre-built Generator as package, which lets TARGET add.generator available find_package(HelloBaremetal-add_generator REQUIRED) add_halide_library( add FROM ${GEN_TARGET} # HelloBaremetal::generators::add.generator GENERATOR add FEATURES debug AUTOSCHEDULER Halide::Mullapudi2016 PARAMS autoscheduler.parallelism1 )关键点CONFIGURE_HANDLED_BY_BUILD TRUE使得配置阶段延迟到构建阶段执行解决ExternalProject常见的配置发生在依赖构建之前的时序问题。app_project通过DEPENDS gen_project保证依赖顺序。隔离的关键在于外层工程本身不设置工具链由内层app_project通过-DCMAKE_TOOLCHAIN_FILE${APP_TOOLCHAIN_FILE}单独套用交叉工具链。这里的APP_TOOLCHAIN_FILE由构建脚本传入指向 cmake/toolchain.noos-arm32-sample.cmake。4.3 方案三cmake-external_projectExternalProject IMPORTED核心思路与方案二类似用ExternalProject构建 Generator但外层工程本身就以交叉工具链配置这里没有第二条工具链切换手动创建一个IMPORTED可执行目标指向外包子工程产出的 Generator 二进制再交给add_halide_library。cmake-external_project/CMakeLists.txt 的核心片段set(GEN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/generator) # Step 1: Build generator executable with host compiler in external child project include(ExternalProject) ExternalProject_Add( gen_project SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/generator BINARY_DIR ${GEN_BINARY_DIR} INSTALL_COMMAND CMAKE_ARGS -DCMAKE_PREFIX_PATH${CMAKE_PREFIX_PATH} CONFIGURE_HANDLED_BY_BUILD TRUE ) # Step 2: NOTE : find_package(HelloBaremetal-add_generator REQUIRED) is not ready # at configuration time. # Instead, declare the generator executable as imported, which is built in external project add_executable(add.generator IMPORTED) set_property(TARGET add.generator PROPERTY IMPORTED_LOCATION ${GEN_BINARY_DIR}/add.generator) add_dependencies(add.generator gen_project) add_halide_library( add FROM add.generator GENERATOR add FEATURES debug AUTOSCHEDULER Halide::Mullapudi2016 PARAMS autoscheduler.parallelism1 )其中 cmake-external_project/generator/CMakeLists.txt 是极简的主机侧 Generator 工程只做find_package(Halide REQUIRED)add_halide_generator(add.generator SOURCES ...)。代码注释点破了这个方案的核心约束在配置阶段find_package(...add_generator)尚不可用外包子工程还未构建所以改为先声明IMPORTED可执行目标、指定IMPORTED_LOCATION指向预期的二进制路径再用add_dependencies把该目标与外包子工程挂钩从而在需要它时自动触发构建。需要说明的是对应doc/HalideCMakePackage.md的论述这个方案的主要缺点是手动创建精确的IMPORTED目标比较困难因为跨平台、跨生成器时二进制命名与位置难以预测例如交叉 OS 场景下的可执行文件扩展名。4.4 三种方案的取舍小结方案组织方式工具链切换位置特点cmake-twice同一 CMakeLists 构建两次host / target 两个构建目录第二次配置时--toolchain结构最简单与官方add_halide_generator两阶段构建文档一致cmake-super_build外层仅协调两个内层子工程各用一套工具链内层 app_project 通过变量传入工具链文件隔离彻底工程结构清晰但多一层嵌套cmake-external_project外层直接套交叉工具链Generator 用外包子工程产出外层配置时指定只构建一次但需手工维护IMPORTED目标可移植性较弱五、交叉工具链文件详解无论是哪种方案最终都要落到 cmake/toolchain.noos-arm32-sample.cmake 这份工具链文件上。它既是交叉编译的入口也是裸机适配信息最密集的文件set(CMAKE_SYSTEM_NAME none) # 无操作系统 set(CMAKE_SYSTEM_PROCESSOR arm) set(CROSS_PREFIX arm-none-eabi-) set(CMAKE_C_COMPILER ${CROSS_PREFIX}gcc) set(CMAKE_CXX_COMPILER ${CROSS_PREFIX}g) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # 查找程序不重定位到目标根 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) # For newlib (standard C library) and semihosting mode set(C_COMMON_FLAGS -specsrdimon.specs) # Target CPU dependent flags to use NEON. Please modify for your target. string(APPEND C_COMMON_FLAGS -marcharmv7-a -mfpuneon -mfloat-abihard) set(CMAKE_CXX_FLAGS_INIT ${C_COMMON_FLAGS}) set(CMAKE_C_FLAGS_INIT ${C_COMMON_FLAGS}) set(CMAKE_ASM_FLAGS_INIT ${C_COMMON_FLAGS}) # Halide target for Halide Generator set(Halide_TARGET arm-32-noos-semihosting) # To prevent Threads and DL libs from being linked to runtime, as this toolchain doesnt have them set(Halide_RUNTIME_NO_THREADS ON) set(Halide_RUNTIME_NO_DL_LIBS ON)逐项解析CMAKE_SYSTEM_NAME none告诉 CMake 这是无 OS 的裸机目标直接影响交叉编译行为判定CMAKE_CROSSCOMPILING为真进而启用测试注册。arm-none-eabi-gcc/gArm 官方裸机工具链前缀EABI 表示嵌入式应用二进制接口。-specsrdimon.specs链接 newlib 与 RedBoot semihosting 运行库这是printf()输出到宿主的关键开关——没有它程序无法在 QEMU 下打印任何内容。-marcharmv7-a -mfpuneon -mfloat-abihard目标 CPU 相关选项开启 NEON 与硬浮点。文件注释明确提示针对不同目标平台请自行修改。Halide_TARGET arm-32-noos-semihostingGenerator 实际生成的 Halide Target 字符串。noos对应Target::NoOSsemihosting对应 src/runtime/HalideRuntime.h 中声明的halide_target_feature_semihosting特性——与Target::NoOS组合使用用于基于 semihosting 库构建并以 semihosting 模式运行的裸机目标。arm-32则声明 32 位 Arm 架构。Halide_RUNTIME_NO_THREADS ON/Halide_RUNTIME_NO_DL_LIBS ON跳过把 Threads 库和 DL 库链接进 Halide 运行时。doc/HalideCMakePackage.md中对这两个变量的说明正是当你的工具链不支持它们时例如裸机应当设置。noosrt.sNEON 启动引导与熵桩工具链文件的下半部分构建并链接了一个特殊的目标文件noosrt.s见 cmake/noosrt.s。它的作用有两个缺一不可NEON 使能 trampoline_enable_neon裸机 CPU 上电后 NEON/VFP 默认是关闭的必须通过协处理器访问控制寄存器打开。汇编流程为MRC p15,0,r0,c1,c0,2读 CP Access 寄存器ORR r0,r0,#0x00f00000允许协处理器 10、11NEON/VFP的全部访问MCR p15,0,r0,c1,c0,2写回ISB指令同步屏障MOV r0,#0x40000000; VMSR FPEXC,r0置位 FPEXC 的 EN 位正式打开 VFP/NEON 硬件BL _mainCRTStartup跳转 C 运行库入口文件注释提醒启动序列与所链接的运行库不同时这个标签名可能需要调整。该入口通过工具链文件末尾的CMAKE_EXE_LINKER_FLAGS_INIT -z noexecstack --entry_enable_neon指定为可执行文件入口因此在main()乃至 C 运行库启动之前 NEON 就已经就绪Halide 生成的 NEON 向量代码可以放心执行。_getentropy桩rdimon.specssemihosting没有熵系统调用但 libstdc 的std::random_device会经由普通std::set/std::string的使用间接引用它。这个桩直接MVN r0,#0返回-1表示失败运行时永远不会真正调用它从而保证链接不因缺失该符号而失败。文件注释还解释了一个重要链接细节这个支持对象必须保持为普通.o而非归档进.a。因为_getentropy是编译器在末尾隐式追加的-lc/-lrdimon过程中才被解析的符号此时普通归档库早已被扫描完毕因此它通过CMAKE_C_STANDARD_LIBRARIES/CMAKE_CXX_STANDARD_LIBRARIES直接以对象文件形式链接进每个可执行文件复用工具链自身链接 libgcc/libc 的同一机制。六、构建步骤裸机目标与宿主目标6.1 裸机目标构建前置条件先在宿主机安装上述arm-none-eabi工具链版本 12.2。工具链的具体配置集中在 cmake/toolchain.noos-arm32-sample.cmake根据你的目标裸机系统可能需要修改。然后进入任意一个方案子目录执行构建脚本cd cmake-xxx/ # 替换为 cmake-twice / cmake-super_build / cmake-external_project ./build.sh三个子目录的build.sh均实现了各自方案的完整流程以cmake-twice/build.sh为例即上文第五节的 Step 1 Step 2。6.2 宿主目标构建这个应用也可以不交叉编译直接在宿主机上构建运行cd cmake-xxx/ cmake -DCMAKE_PREFIX_PATHpath/to/halide install -B build . cmake --build build/其中path/to/halide install指向已安装 Halide 的路径对应find_package(Halide REQUIRED)的搜索位置。七、运行与自动化验证QEMU semihosting ctest7.1 ctest 一键验证完成裸机构建后ctest会直接在 QEMU Arm System 模拟器上以 semihosting 模式运行可执行文件。三个方案各自的测试目录不同ctest --test-dir build-target --output-on-failure # cmake-twice ctest --test-dir build/app --output-on-failure # cmake-super_build ctest --test-dir build --output-on-failure # cmake-external_project测试如何被注册以cmake-twice/CMakeLists.txt为例仅在CMAKE_CROSSCOMPILING裸机交叉编译时为真时才注册if (CMAKE_CROSSCOMPILING) enable_testing() set(IMAGE ${SRC_DIR}/../images/gray_small.pgm) if (EXISTS ${IMAGE}) add_test( NAME add_filter COMMAND ${SRC_DIR}/run_baremetal.sh $TARGET_FILE:add_filter ${IMAGE} 16 out.pgm ) set_tests_properties(add_filter PROPERTIES PASS_REGULAR_EXPRESSION Success!) endif () endif ()测试名add_filter用run_baremetal.sh在 QEMU 中执行add_filter输入 apps/images/gray_small.pgm、偏移量16、输出out.pgm并要求输出匹配Success!对应 filter.cpp 成功后的printf(Success!\n)。宿主构建模式下不会注册该测试因为宿主端没有裸机工具链可供 QEMU 运行。7.2 run_baremetal.shQEMU 运行脚本README 指出run_baremetal.sh就是ctest在底层调用的脚本也可以直接对任何为此目标构建的可执行文件运行。脚本核心run_baremetal.sh#!/bin/bash set -euo pipefail EXECUTABLE$1 EXE_ARGS$* QEMU_MACHINE_ARGS(-M realview-pbx-a9 -cpu cortex-a9 -smp 1 -m 1024M) echo Running command: $EXE_ARGS qemu-system-arm \ ${QEMU_MACHINE_ARGS[]} \ -monitor null -serial null -nographic \ -kernel ${EXECUTABLE} \ -semihosting -semihosting-config enableon,targetnative,arg${EXE_ARGS}关键参数语义-M realview-pbx-a9 -cpu cortex-a9选择 Arm Realview PBX 开发板模型与 Cortex-A9 CPU与 README 的测试条件对应-smp 1单核与裸机无多线程约束一致-m 1024M1 GB 内存-kernel以裸机内核方式直接加载可执行文件无 OS无引导加载器-semihosting -semihosting-config enableon,targetnative,arg...开启 semihosting 并把命令行参数透传给目标程序——目标端的printf()输出、argv[1..3]解析全部由此支撑。八、移植到其他裸机平台的注意事项综合 README、工具链文件与源码注释若要将此示例迁移到自己的目标平台需要检查的点包括工具链换用目标架构对应的 GCC 前缀如arm-none-eabi-→ 其他工具链前缀确认版本与 ABI。CPU 特性编译选项-march/-mfpu/-mfloat-abi必须匹配目标 CPU例如不支持 NEON 的核需要去掉-mfpuneon并相应调整 Halide 调度。启动引导noosrt.s中的_enable_neon入口与_mainCRTStartup标签依赖你的 C 运行库与启动序列需要核对并修改若目标无 NEON 则整段可省略。Halide Target 字符串Halide_TARGET arm-32-noos-semihosting中的特性组合应与目标运行时能力一致noos与semihosting是成对使用的裸机组合见 src/runtime/HalideRuntime.h。运行库能力没有Threads/dl时必须保持Halide_RUNTIME_NO_THREADS、Halide_RUNTIME_NO_DL_LIBS为 ON调度中禁用.parallel()并把自动调度器并行度设为 1。图像格式仅 PPM/PGM 可用PNG/JPEG 需要自行集成 libpng/libjpeg参见 filter.cpp 的注释。模拟器参数-M、-cpu、-semihosting等 QEMU 参数需与目标板卡模型匹配。九、延伸阅读交叉编译的通用方法论与add_halide_generator、ExternalProject等策略的官方论述doc/HalideCMakePackage.md含Halide_RUNTIME_NO_THREADS、Halide_RUNTIME_NO_DL_LIBS等变量的语义。Halide 运行时 Target 特性声明包括halide_target_feature_semihostingsrc/runtime/HalideRuntime.h。三个方案的完整构建脚本apps/HelloBaremetal/cmake-twice/build.sh、apps/HelloBaremetal/cmake-super_build/build.sh、apps/HelloBaremetal/cmake-external_project/build.sh以及各自的CMakeLists.txt。赞分享编译器图像处理编程语言高性能计算【免费下载链接】Halidea language for fast, portable>项目地址https://gitcode.com/gh_mirrors/ha/Halide点击查看免费下载相关推荐SDL 3 在 RISC OS 平台上的交叉编译与移植现状指南SDL 3 在 RISC OS 平台上的交叉编译与移植现状指南 导读 本文基于 docs/README riscos.md https://link.gitco音视频游戏开发跨平台Hiredis交叉编译ARM平台移植指南Hiredis交叉编译ARM平台移植指南 1. 引言ARM嵌入式开发的Redis客户端困境 在嵌入式系统开发中你是否曾遇到过这些棘手问题交叉编译工具链配数据库客户端后端无OS环境编译难题攻克fmtlib/fmt 11.0.1移植实战指南无OS环境编译难题攻克fmtlib/fmt 11.0.1移植实战指南 你是否在嵌入式开发中因缺少标准库支持而无法使用fmtlib本文将手把手教你解决无操作系标准库上一篇RouterSploit 实战Movistar 路由器 SSH 默认口令爆破模块ssh_default_creds深度解析下一篇Stencil 类型测试Type Tests实践指南用 TypeScript 编译器验证 JSX 类型正确性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表