从为您的平台创建列表文件 CMakeLists.txt模板 - FreeRTOS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

从为您的平台创建列表文件 CMakeLists.txt模板

CMakeLists.txt 模板文件是随 FreeRTOS 提供的,它位于 /vendors/vendor/boards/board/CMakeLists.txt 中。

CMakeLists.txt 模板文件由以下四个部分组成:

可以按照说明编辑列表文件的这四个部分,以与平台相匹配。您可以参考 /vendors 中其他符合条件的供应商主板的 CMakeLists.txt 文件以作为示例。

整个文件中会调用以下两个主要函数:

afr_set_board_metadata(name value)

此函数为 FreeRTOS 控制台定义元数据。该函数是在 /tools/cmake/afr_metadata.cmake 中定义的。

afr_mcu_port(module_name [<DEPENDS> [targets...]])

此函数定义与 FreeRTOS 模块(即库)关联的可移植层目标。它创造了 CMake GLOBAL INTERFACE IMPORTED 具有表单名称的目标 AFR:module_name::mcu_port。如果 DEPENDS 使用时,其他目标与链接 target_link_libraries。函数定义见 /tools/cmake/afr_module.cmake.

FreeRTOS 控制台元数据

模板文件的第一部分定义用于在 FreeRTOS 控制台中显示主板信息的元数据。使用函数 afr_set_board_metadata(name value) 定义模板中列出的每个字段。下表提供了每个字段的说明。

字段名称 值说明
ID 主板的唯一 ID。
DISPLAY_NAME 要显示在 FreeRTOS 控制台上的主板的名称。
DESCRIPTION 用于 FreeRTOS 控制台的主板的简短说明。
VENDOR_NAME 主板供应商的名称。
FAMILY_NAME 主板 MCU 系列的名称。
DATA_RAM_MEMORY 主板 RAM 的大小,后跟单位缩写。例如,使用 KB 表示千字节。
PROGRAM_MEMORY 主板程序内存的大小,后跟单位缩写。例如,使用 MB 表示兆字节。
CODE_SIGNER 用于 OTA 更新的代码签名平台。使用 AmazonFreeRTOS-SHA256散列算法和ECDSA加密算法的默认值。如果要使用不同的代码签名平台,请联系我们
SUPPORTED_IDE 分号分隔列表 IDs 用于 IDEs 板支持。
IDE_ID_NAME 支持的 IDE 的名称。Replace ID 其中IDE的ID列在 SUPPORTED_IDE 字段。
IDE_ID_COMPILER 对于所支持的 IDE,支持的编译器的名称列表,用分号分隔。Replace ID 其中IDE的ID列在 SUPPORTED_IDE 字段。
KEY_IMPORT_PROVISIONING

如果板演示项目从预置的 aws_clientcredential_keys.h 标头文件;在这种情况下, 快速连接 会在 FreeRTOS 控制台。

如果预期的板配置机制是JITR/JITP或多帐户注册,则设置为FALSE;在这种情况下, 快速连接 将会在 FreeRTOS 控制台。

编译器设置

模板文件的第二部分为主板定义编译器设置。要创建包含编译器设置的目标,请致电 afr_mcu_port 函数 compiler 取代 module_name 以创建一个 INTERFACE 目标名称 AFR::compiler::mcu_port。内核公开链接到此 INTERFACE 目标,以便编译器设置被跨动填充到所有模块。

使用标准、内置 CMake 功能定义列表文件的此部分中的编译器设置。在定义编译器设置时,请遵循以下最佳实践:

  • 使用 target_compile_definitions 提供编译定义和宏。

  • 使用 target_compile_options 提供编译器标记。

  • 使用 target_include_directories 提供包含目录。

  • 使用 target_link_options 提供链接器标记。

  • 使用 target_link_directories 提供链接器搜索目录。

  • 使用 target_link_libraries 提供链接的库。

注意

如果在其他位置定义编译器设置,则不需要重复文件此部分中的信息。相反,使用 DEPENDS 调用 afr_mcu_port,可从其他位置引入目标定义。

例如:

# your_target is defined somewhere else. It does not have to be in the same file. afr_mcu_port(compiler DEPENDS your_target)

使用 DEPENDS 调用 afr_mcu_port 时,它会调用 target_link_libraries(AFR::module_name::mcu_port INTERFACE your_targets),这会填充所需 AFR::compiler::mcu_port 目标的编译器设置。

使用多个编译器

如果主板支持多个编译器,则可使用 AFR_TOOLCHAIN 变量动态选择编译器设置。该变量设置为使用的编译器的名称,该名称应该与位于 /tools/cmake/toolchains 中的工具链文件的名称相同。

例如:

if("${AFR_TOOLCHAIN}" STREQUAL "arm-gcc") afr_mcu_port(compiler DEPENDS my_gcc_settings). elseif("${AFR_TOOLCHAIN}" STREQUAL "arm-iar") afr_mcu_port(compiler DEPENDS my_iar_settings). else() message(FATAL_ERROR "Compiler ${AFR_TOOLCHAIN} not supported.") endif()

高级编译器设置

如果要设置更高级的编译器设置,例如根据编程语言设置编译器标记,或更改不同版本和调试配置的设置,您可以使用 CMake 生成器表达式。

例如:

set(common_flags "-foo") set(c_flags "-foo-c") set(asm_flags "-foo-asm") target_compile_options( my_compiler_settings INTERFACE $<$<COMPILE_LANGUAGE:C>:${common_flags} ${c_flags}> # This only have effect on C files. $<$<COMPILE_LANGUAGE:ASM>:${common_flags} ${asm_flags}> # This only have effect on ASM files. )

C在配置阶段,当 CMake 读取列表文件。它们在发电阶段 CMake 完成读取列表文件并生成目标构建系统的构建文件。

FreeRTOS 可移植层

模板文件的第三部分为 FreeRTOS(即库)定义所有可移植层目标。

必须使用 afr_mcu_port(module_name) 函数,为计划实施的每个 FreeRTOS 模块定义可移植层目标。

您可以使用任何 CMake 功能,只要 afr_mcu_port 呼叫会创建一个名称用来提供创建相应 FreeRTOS 模块。

afr_mcu_port 函数创建 全球接口导入库目标 表单名称 AFR::module_name::mcu_port。作为 GLOBAL 目标,可以在中引用 CMake 列出文件。作为 INTERFACE 目标时,不能构建为独立的目标或库,但可以编译到相应的 FreeRTOS 模块。作为 IMPORTED 目标时,其名称在目标名称中包含命名空间 (::),例如,AFR::kernel::mcu_port

默认情况下,无相应可移植层目标的模块处于禁用状态。如果您运行 CMake 以配置 FreeRTOS,在未定义任何便携式层目标的情况下,您应该看到以下输出:

FreeRTOS modules: Modules to build: Disabled by user: Disabled by dependency: kernel, posix, pkcs11, secure_sockets, mqtt, ... Available demos: Available tests:

使用移植层目标更新 CMakeLists.txt 文件时,将启用相应的 FreeRTOS 模块。您还应该能构建其依赖性要求随后得以满足的任何 FreeRTOS 模块。例如,如果已启用 MQTT 库,则 Device Shadow 库也会启用,因为它唯一的依赖项是 MQTT 库。

注意

的 FreeRTOS 内核依赖是的最低要求。的 CMake 配置失败,如果 FreeRTOS 不满足内核依赖。

设置内核移植目标

要创建内核移植目标(AFR::kernel::mcu_port)、呼叫 afr_mcu_port 模块名称 kernel。当您致电 afr_mcu_port,请为 FreeRTOS 便携层和驱动程序代码。创建目标后,您可以提供依赖项信息和 FreeRTOS 供目标使用的便携式层和驱动程序代码信息。

按照以下说明设置内核移植目标。

设置内核移植目标

  1. 为驱动程序代码创建目标。

    例如,可以为驱动程序代码创建 STATIC 库目标:

    add_library(my_board_driver STATIC ${driver_sources}) # Use your compiler settings target_link_libraries( my_board_driver PRIVATE AFR::compiler::mcu_port # Or use your own target if you already have it. # PRIVATE ${compiler_settings_target} ) target_include_directories( my_board_driver PRIVATE "include_dirs_for_private_usage" PUBLIC "include_dirs_for_public_interface" )

    或者,可以为驱动程序代码创建 INTERFACE 库目标:

    # No need to specify compiler settings since kernel target has them. add_library(my_board_driver INTERFACE ${driver_sources})
    注意

    INTERFACE 库目标无构建输出。如果使用的是 INTERFACE 库目标,则驱动程序代码将编译到内核库。

  2. 配置 FreeRTOS 便携式层:

    add_library(freertos_port INTERFACE) target_sources( freertos_port INTERFACE "${AFR_MODULES_DIR}/freertos_kernel/portable/GCC/ARM_CM4F/port.c" "${AFR_MODULES_DIR}/freertos_kernel/portable/GCC/ARM_CM4F/portmacro.h" "${AFR_MODULES_DIR}/freertos_kernel/portable/MemMang/heap_4.c" ) target_include_directories( freertos_port INTERFACE "${AFR_MODULES_DIR}/freertos_kernel/portable/GCC/ARM_CM4F" "${include_path_to_FreeRTOSConfig_h} )
    注意

    您还可以配置 FreeRTOS 通过直接在中指定这些源文件及其包含的目录来添加便携式层 AFR::kernel::mcu_port 目标。

  3. 创建内核可移植层目标:

    # Bring in driver code and freertos portable layer dependency. afr_mcu_port(kernel DEPENDS my_board_driver freertos_port) # If you need to specify additional configurations, use standard CMake functions with # AFR::kernel::mcu_port as the target name. target_include_directories( AFR::kernel::mcu_port INTERFACE "${additional_includes}" # e.g. board configuration files ) target_link_libraries( AFR::kernel::mcu_port INTERFACE "${additional_dependencies}" )
  4. 要测试列表文件和配置,可以编写一个简单的应用程序以使用 FreeRTOS 内核移植。有关开发和构建的更多信息 FreeRTOS 应用程序 CMake,请参阅 建筑 FreeRTOS 配 CMake.

  5. 创建演示之后,将 add_executabletarget_link_libraries 调用添加到列表文件,并将内核编译为静态库,以检验内核可移植层的配置是否正确。

    add_executable( my_demo main.c ) target_link_libraries( my_demo PRIVATE AFR::kernel )

设置 FreeRTOS 模块的移植目标

为内核添加可移植层目标之后,可以为其他 FreeRTOS 模块添加可移植层目标。

例如,为 Wi-Fi 模块添加可移植层:

afr_mcu_port(wifi) target_sources( AFR::wifi::mcu_port INTERFACE "${AFR_MODULES_DIR}/vendors/vendor/boards/board/ports/wifi/iot_wifi.c" )

此 Wi-Fi 模块可移植层示例只有一个基于驱动程序代码的实施文件。

如果要为 FreeRTOS 安全套接字模块添加可移植层,则该模块依赖于 TLS。这使得其便携式图层目标比Wi-Fi模块略复杂。 FreeRTOS 提供基于以下项的默认TLS实施 mbedTLS 可链接至:

afr_mcu_port(secure_sockets) target_sources( AFR::secure_sockets::mcu_port INTERFACE ${portable_layer_sources} ) target_link_libraries( AFR::secure_sockets::mcu_port AFR::tls )

在此示例代码中,标准 CMake 功能 target_link_libraries 表明安全套接字便携层取决于 AFR::tls.

您可以参考所有 FreeRTOS 模块,使用其目标名称 AFR::module_name。例如,您可以使用相同的语法来说明对 FreeRTOS-Plus-TCP:

target_link_libraries( AFR::secure_sockets::mcu_port AFR::freertos_plus_tcp AFR::tls )
注意

如果平台自己处理 TLS,则可直接使用驱动程序代码。如果将驱动程序代码直接用于 TLS,则无需调用 target_link_libraries,因为所有 FreeRTOS 模块隐式依赖于包含驱动程序代码的内核。

由于所有非内核 FreeRTOS 模块隐式依赖于内核,因此其移植层不需要将内核指定为依赖项。不过,POSIX 模块定义为可选的内核模块。如果要使用 POSIX,则必须将其显式包括在内核可移植层中。例如:

# By default, AFR::posix target does not expose standard POSIX headers in its public # interface, i.e., You need to use "freertos_plus_posix/source/FreeRTOS_POSIX_pthread.c" instead of "pthread.h". # Link to AFR::use_posix instead if you need to use those headers directly. target_link_libraries( AFR::kernel::mcu_port INTERFACE AFR::use_posix )

FreeRTOS 演示和测试

模板文件的最后一部分定义了演示和测试目标 FreeRTOS. CMake 为每个满足依赖项要求的演示和测试自动创建目标。

在本节中,使用 add_executable 函数定义可执行目标。如果要编译测试,则使用 aws_tests 作为目标名称。如果要编译演示,则使用 aws_demos。可能还需要提供其他项目设置,如链接器脚本和构建后命令。例如:

if(AFR_IS_TESTING) set(exe_target aws_tests) else() set(exe_target aws_demos) endif() set(CMAKE_EXECUTABLE_SUFFIX ".elf") add_executable(${exe_target} "${board_dir}/application_code/main.c")

target_link_libraries 被叫到可用的链接 CMake 演示或测试您的可执行目标的目标。

注意

仍需要修改 aws_demos/config_files/aws_demo_config.haws_tests/config_files/aws_test_runner_config.h,以启用演示和测试。

运行构建后命令

有关运行构建后命令的信息,请参阅 add_custom_command。使用第二个签名。例如:

# This should run an external command "command --arg1 --arg2". add_custom_command( TARGET ${exe_target} POST_BUILD COMMAND "command" "--arg1" "--arg2" )
注意

CMake 支持许多常见的、独立于平台的操作,如创建目录、复制文件等。有关 CMake 命令行操作,请参阅 CMake命令行工具参考. 您可以参考 CMake 命令行工具 CMake 包含内置变量的列表文件 ${CMAKE_COMMAND}.