0

I have a project that consists of nodes in a mesh, that will communicate between each other wirelessly and will identify each other with a use of addresses.

Nodes will be equivalent in their responsibilities so the source code for each them will be identical, except for address which I would like to be specific and unique for each.

This project will be a kind of demo, or technology demonstration so for simplicity I do not want to introduce some address negotiations or anything complex like that.

I was researching and found some suggestions to use target_compile_definitions in CMake but I am not really sure how to apply it to generic Zephyr CMakeLists.txt:

set(BOARD qemu_x86)

find_package(Zephyr)
project(my_zephyr_app)

target_sources(app PRIVATE src/main.c)

So I was wondering what is the best way to do that? Is there a way to do that in CMake (I am quite a noob yet when it comes to CMake)? Or should I tinker with some Python script?

EDIT: And I was thinking if maybe doing something like #define <device_addr> from level of CMake is possible, and then repeating that X times for the rest of the devices. So in the end I would have X binaries that will differ only in regard to that #define <device_addr>.

Thank You for responses in advance.

konin
  • 53
  • 4
  • What is this "address" as per your context? IP? IP+Port? Or something else? – kiner_shah Jan 22 '22 at 11:14
  • In my context it can be just generic hex value. This will be very small network with no internet connection so I believe that is enough. It is only for devices to recognize each other in this particular network. – konin Jan 22 '22 at 11:17
  • I think you need to elaborate more - what do you want CMake to do? What is the end goal? – kiner_shah Jan 22 '22 at 11:20
  • I need to have a set of binaries for each device in the network that will differ only in local address of a specific device. I would like addresses to be predefined, so that devices in the network, when booted, will be able to immediately communicate with each other (with use of adresses). So for example node A will immediately know that somewhere there in the network exists node B that it can communicate with. – konin Jan 22 '22 at 11:27
  • And I was thinking if maybe doing something like #define from level of CMake is possible, and then repeating that X times for the rest of the devices. So in the end I would have X binaries that will differ only in regard to that #define . – konin Jan 22 '22 at 11:29

1 Answers1

0

Create a custom ELF section in your project with the address. Use compiler specific syntax. This is for GCC compiler:

// 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;
}

At best create a linker file so that your section will be placed in .rodata read only memory.

Build one ELF file.

Create a short script. This script will replace the content of the section in the generated ELF file with your custom data - the actual address. Use objcopy --update-section myaddress=filename to update the section, where filename has the binary content of the section. Repeat objcopy for every address. The best would be to write that script in CMake - research CMakeFindBinUtils and add_custom_command + add_custom_target and generator expression with $<TARGET_FILE:app>.

Then use objcopy on generated ELF files to generate bin files.

Overall, this sounds like an odd approach, because every device has some "identification number", "manufacturer number" etc. stored in some read-only device specific memory. Strongly consider reading that number and just using it as an address.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111