从 Zephyr RTOS 项目在 CMake 中构建多个二进制文件,每个二进制文件都有不同的设备地址
Building multiple binaries in CMake from Zephyr RTOS project, each with different device address
我有一个由网格中的节点组成的项目,它们将在彼此之间进行无线通信,并将使用地址相互识别。
节点的职责是相同的,因此每个节点的源代码都是相同的,除了地址,我希望每个节点都具体且唯一。
这个项目将是一种演示或技术演示,因此为了简单起见,我不想介绍一些地址协商或任何类似的复杂内容。
我正在研究并发现了一些在 CMake 中使用 target_compile_definitions 的建议,但我不太确定如何将其应用于通用 Zephyr CMakeLists.txt:
set(BOARD qemu_x86)
find_package(Zephyr)
project(my_zephyr_app)
target_sources(app PRIVATE src/main.c)
所以我想知道最好的方法是什么?有没有办法在 CMake 中做到这一点(说到 CMake,我还是个菜鸟)?或者我应该修改一些 Python 脚本?
编辑:
我在想是否可以从 CMake 级别执行类似 #define 的操作,然后对其余设备重复该操作 X 次。所以最后我会有 X 个二进制文件,它们只在 #define .
方面有所不同
提前感谢您的回复。
在您的项目中使用该地址创建自定义 ELF 部分。使用编译器特定的语法。这是针对 GCC 编译器的:
// volatile, so that optimizer does not bite us
__attribute__((__section__("myaddress")))
__attribute__((__used__))
volatile const uint8_t _address[20] = {0};
# external API - fetch the address
# remove volatile for usage for optimizations
uint8_t *get_address(uint8_t buffer[20]) {
memcpy(buffer, _address, sizeof(_address));
return address;
}
最好创建一个链接器文件,以便将您的部分放置在 .rodata 只读内存中。
构建一个 ELF 文件。
创建一个简短的脚本。该脚本会将生成的 ELF 文件中的部分内容替换为您的自定义数据 - 实际地址。使用 objcopy --update-section myaddress=filename
更新该部分,其中 filename
具有该部分的二进制内容。对每个地址重复 objcopy
。最好是在 CMake 中编写该脚本 - 研究 CMakeFindBinUtils
和 add_custom_command
+ add_custom_target
以及带有 $<TARGET_FILE:app>
.
的生成器表达式
然后对生成的ELF文件使用objcopy
生成bin文件
总的来说,这听起来像是一种奇怪的方法,因为每个设备都有一些“标识号”、“制造商号”等存储在某些 read-only 设备特定的内存中。强烈考虑读取该数字并将其用作地址。
我有一个由网格中的节点组成的项目,它们将在彼此之间进行无线通信,并将使用地址相互识别。
节点的职责是相同的,因此每个节点的源代码都是相同的,除了地址,我希望每个节点都具体且唯一。
这个项目将是一种演示或技术演示,因此为了简单起见,我不想介绍一些地址协商或任何类似的复杂内容。
我正在研究并发现了一些在 CMake 中使用 target_compile_definitions 的建议,但我不太确定如何将其应用于通用 Zephyr CMakeLists.txt:
set(BOARD qemu_x86)
find_package(Zephyr)
project(my_zephyr_app)
target_sources(app PRIVATE src/main.c)
所以我想知道最好的方法是什么?有没有办法在 CMake 中做到这一点(说到 CMake,我还是个菜鸟)?或者我应该修改一些 Python 脚本?
编辑:
我在想是否可以从 CMake 级别执行类似 #define
提前感谢您的回复。
在您的项目中使用该地址创建自定义 ELF 部分。使用编译器特定的语法。这是针对 GCC 编译器的:
// volatile, so that optimizer does not bite us
__attribute__((__section__("myaddress")))
__attribute__((__used__))
volatile const uint8_t _address[20] = {0};
# external API - fetch the address
# remove volatile for usage for optimizations
uint8_t *get_address(uint8_t buffer[20]) {
memcpy(buffer, _address, sizeof(_address));
return address;
}
最好创建一个链接器文件,以便将您的部分放置在 .rodata 只读内存中。
构建一个 ELF 文件。
创建一个简短的脚本。该脚本会将生成的 ELF 文件中的部分内容替换为您的自定义数据 - 实际地址。使用 objcopy --update-section myaddress=filename
更新该部分,其中 filename
具有该部分的二进制内容。对每个地址重复 objcopy
。最好是在 CMake 中编写该脚本 - 研究 CMakeFindBinUtils
和 add_custom_command
+ add_custom_target
以及带有 $<TARGET_FILE:app>
.
然后对生成的ELF文件使用objcopy
生成bin文件
总的来说,这听起来像是一种奇怪的方法,因为每个设备都有一些“标识号”、“制造商号”等存储在某些 read-only 设备特定的内存中。强烈考虑读取该数字并将其用作地址。