feat(build): support aligned embedded binary data

Allow callers to align embedded binary start symbols for DMA-capable
assets.
This commit is contained in:
morris
2026-07-24 11:48:17 +08:00
parent 4a2bad6367
commit 16c8013af4
6 changed files with 49 additions and 5 deletions
+4
View File
@@ -996,6 +996,10 @@ To embed a file into a project, rather than a component, you can call the functi
Place this line after the ``project()`` line in your project CMakeLists.txt file. Replace ``myproject.elf`` with your project name. The final argument can be ``TEXT`` to embed a null-terminated string, or ``BINARY`` to embed the content as-is. Place this line after the ``project()`` line in your project CMakeLists.txt file. Replace ``myproject.elf`` with your project name. The final argument can be ``TEXT`` to embed a null-terminated string, or ``BINARY`` to embed the content as-is.
Use the optional ``ALIGN`` argument to align the embedded data's start symbol to a positive power of two. For example, to align binary data to 16 bytes::
target_add_binary_data(myproject.elf "main/data.bin" BINARY ALIGN 16)
For an example of using this technique, see the "main" component of the file_serving example :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` - two files are loaded at build time and linked into the firmware. For an example of using this technique, see the "main" component of the file_serving example :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` - two files are loaded at build time and linked into the firmware.
.. highlight:: cmake .. highlight:: cmake
+4
View File
@@ -996,6 +996,10 @@ CMake 文件可以使用 ``IDF_TARGET`` 变量来获取当前的硬件目标。
并将这行代码放在项目 CMakeLists.txt 的 ``project()`` 命令之后,修改 ``myproject.elf`` 为你自己的项目名。如果最后一个参数是 ``TEXT``,那么构建系统会嵌入以 null 结尾的字符串,如果最后一个参数被设置为 ``BINARY``,则将文件内容按照原样嵌入。 并将这行代码放在项目 CMakeLists.txt 的 ``project()`` 命令之后,修改 ``myproject.elf`` 为你自己的项目名。如果最后一个参数是 ``TEXT``,那么构建系统会嵌入以 null 结尾的字符串,如果最后一个参数被设置为 ``BINARY``,则将文件内容按照原样嵌入。
可选的 ``ALIGN`` 参数用于将嵌入数据的起始符号对齐到指定的正整数 2 的幂。例如,将二进制数据按 16 字节对齐::
target_add_binary_data(myproject.elf "main/data.bin" BINARY ALIGN 16)
有关使用此技术的示例,请查看 file_serving 示例 :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` 中的 main 组件,两个文件会在编译时加载并链接到固件中。 有关使用此技术的示例,请查看 file_serving 示例 :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` 中的 main 组件,两个文件会在编译时加载并链接到固件中。
.. highlight:: cmake .. highlight:: cmake
@@ -34,7 +34,7 @@ Below is short explanation of remaining files in the project folder.
└── README.md This is the file you are currently reading └── README.md This is the file you are currently reading
``` ```
For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System v2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system-v2.html) of the ESP-IDF Programming Guide. For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System v2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system-v2/index.html) of the ESP-IDF Programming Guide.
## Troubleshooting ## Troubleshooting
@@ -74,6 +74,9 @@ append_line(".data")
append_line("#if !defined (__APPLE__) && !defined (__linux__)") append_line("#if !defined (__APPLE__) && !defined (__linux__)")
append_line(".section .rodata.embedded") append_line(".section .rodata.embedded")
append_line("#endif") append_line("#endif")
if(DEFINED DATA_ALIGNMENT)
append_line(".balign ${DATA_ALIGNMENT}")
endif()
make_and_append_identifier("${varname}") make_and_append_identifier("${varname}")
make_and_append_identifier("_binary_${varname}_start" "for objcopy compatibility") make_and_append_identifier("_binary_${varname}_start" "for objcopy compatibility")
append("${data}") append("${data}")
+16 -2
View File
@@ -77,9 +77,10 @@ endfunction()
# target_add_binary_data adds binary data into the built target, # target_add_binary_data adds binary data into the built target,
# by converting it to a generated source file which is then compiled # by converting it to a generated source file which is then compiled
# to a binary object as part of the build # to a binary object as part of the build. ALIGN optionally sets the
# alignment of the embedded data's start symbol.
function(target_add_binary_data target embed_file embed_type) function(target_add_binary_data target embed_file embed_type)
cmake_parse_arguments(_ "" "RENAME_TO" "DEPENDS" ${ARGN}) cmake_parse_arguments(_ "" "RENAME_TO;ALIGN" "DEPENDS" ${ARGN})
idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(build_dir BUILD_DIR)
idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(idf_path IDF_PATH)
@@ -93,11 +94,24 @@ function(target_add_binary_data target embed_file embed_type)
set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}") set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}")
endif() endif()
set(align_arg)
if(DEFINED __ALIGN)
if(NOT __ALIGN MATCHES "^[1-9][0-9]*$")
message(FATAL_ERROR "ALIGN must be a positive integer")
endif()
math(EXPR alignment_mask "${__ALIGN} & (${__ALIGN} - 1)")
if(NOT alignment_mask EQUAL 0)
message(FATAL_ERROR "ALIGN must be a power of two")
endif()
set(align_arg -D "DATA_ALIGNMENT=${__ALIGN}")
endif()
add_custom_command(OUTPUT "${embed_srcfile}" add_custom_command(OUTPUT "${embed_srcfile}"
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-D "DATA_FILE=${embed_file}" -D "DATA_FILE=${embed_file}"
-D "SOURCE_FILE=${embed_srcfile}" -D "SOURCE_FILE=${embed_srcfile}"
${rename_to_arg} ${rename_to_arg}
${align_arg}
-D "FILE_TYPE=${embed_type}" -D "FILE_TYPE=${embed_type}"
-P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake" -P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake"
MAIN_DEPENDENCY "${embed_file}" MAIN_DEPENDENCY "${embed_file}"
+21 -2
View File
@@ -803,7 +803,8 @@ endfunction()
#[[ #[[
target_add_binary_data(<target> <embed_file> <embed_type> target_add_binary_data(<target> <embed_file> <embed_type>
[RENAME_TO <symbol>]) [RENAME_TO <symbol>]
[ALIGN <alignment>]
[DEPENDS <dependency>...]) [DEPENDS <dependency>...])
*target[in]* *target[in]*
@@ -823,6 +824,11 @@ endfunction()
Use the given symbol name for the embedded data. If no symbol name is Use the given symbol name for the embedded data. If no symbol name is
provided, the embed_file file name will be used instead. provided, the embed_file file name will be used instead.
*ALIGN[in,opt]*
Align the embedded data's start symbol to the given positive power
of two.
*DEPENDS[in,opt]* *DEPENDS[in,opt]*
List of additional dependencies for the generated file containing List of additional dependencies for the generated file containing
@@ -833,7 +839,7 @@ endfunction()
build process. build process.
#]] #]]
function(target_add_binary_data target embed_file embed_type) function(target_add_binary_data target embed_file embed_type)
cmake_parse_arguments(_ "" "RENAME_TO" "DEPENDS" ${ARGN}) cmake_parse_arguments(_ "" "RENAME_TO;ALIGN" "DEPENDS" ${ARGN})
idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(build_dir BUILD_DIR)
idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(idf_path IDF_PATH)
@@ -847,11 +853,24 @@ function(target_add_binary_data target embed_file embed_type)
set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}") set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}")
endif() endif()
set(align_arg)
if(DEFINED __ALIGN)
if(NOT __ALIGN MATCHES "^[1-9][0-9]*$")
message(FATAL_ERROR "ALIGN must be a positive integer")
endif()
math(EXPR alignment_mask "${__ALIGN} & (${__ALIGN} - 1)")
if(NOT alignment_mask EQUAL 0)
message(FATAL_ERROR "ALIGN must be a power of two")
endif()
set(align_arg -D "DATA_ALIGNMENT=${__ALIGN}")
endif()
add_custom_command(OUTPUT "${embed_srcfile}" add_custom_command(OUTPUT "${embed_srcfile}"
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"
-D "DATA_FILE=${embed_file}" -D "DATA_FILE=${embed_file}"
-D "SOURCE_FILE=${embed_srcfile}" -D "SOURCE_FILE=${embed_srcfile}"
${rename_to_arg} ${rename_to_arg}
${align_arg}
-D "FILE_TYPE=${embed_type}" -D "FILE_TYPE=${embed_type}"
-P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake" -P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake"
MAIN_DEPENDENCY "${embed_file}" MAIN_DEPENDENCY "${embed_file}"