Arduino address attribute

Does the Arduino compiler support "attribute((address (0x100)))" or any other method of specifying an address in memory?

Using Arduino v1.6.4, it doesn't throw an error if I use that attribute, however it doesn't locate it where I specify either.

I have tried it with both PROGMEM and RAM memory locations, and neither seem to work.

Why do you need to do it? That's an overly complicated way to accomplish something that is probably dirt simple if you tell us the real intent.

http://xyproblem.info/

I want to put ID information at the end of memory, so that I can parse the hex file and identify the revision.

The ends of the memory have really important functions. That's the start of your program or the start of the bootloader, or something equally unmoveable.

Just put a marker sequence in your code that you can search for in the hex file. Like maybe "Version". Search for that and grab the bytes following.

Would EEPROM work?

Yeah, but you could put that in the last few bytes before the bootloader. I don't know the notation to make the compiler do it, but I'm almost certain it's supported.

I'm working with someone who puts serial numbers in the "gap" between the end of the bootloader and the end of the flash (he's got a program that automatically advances the numbers while it programs). That means they can't be changed by the bootloader, which makes sense for his application - but it may not for yours. Putting it in the space between the end of the app and the start of the bootloader would be fine if you want it to change alongside the app.

Thanks for the information about the address space used by the bootloader. Where is that information documented?

The bootloader itself is an example of code that needs addresses explicitly defined. However the compiler does this is fine with me: whether it's with an "attribute((address (0x100))", "@", or user defined memory sections.

From this documentation I believed that the attribute((address (0x100))" method was used. Am I looking at the wrong place for documentation of the compiler used by Arduino? -> https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes

BigBobby: From this documentation I believed that the attribute((address (0x100))" method was used. Am I looking at the wrong place for documentation of the compiler used by Arduino? -> https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes

You're looking at a too recent version. The current Arduino versions use GCC 4.8.x, which does not support the address attribute.

https://gcc.gnu.org/onlinedocs/gcc-4.8.5/gcc/Variable-Attributes.html#AVR-Variable-Attributes

I think you will find useful information about how to place something here

http://www.atmel.com/webdoc/AVRLibcReferenceManual/mem_sections.html

I’m not sure anything at that link actually lets you specify a location to store the data at in the C code, though. May not be a good way to get the compiler+linker to do this for you?

BigBobby:
Thanks for the information about the address space used by the bootloader. Where is that information documented?

The bootloader itself is an example of code that needs addresses explicitly defined. However the compiler does this is fine with me: whether it’s with an “attribute((address (0x100))”, “@”, or user defined memory sections.

From this documentation I believed that the attribute((address (0x100))" method was used. Am I looking at the wrong place for documentation of the compiler used by Arduino? → AVR Variable Attributes (Using the GNU Compiler Collection (GCC))

Boards.txt gives you the max size of a sketch. Since the bootloader is located after the sketch, the max size of the sketch is the address of the start of the bootloader. See the bootloader .hex files to see if there’s any space left at the end.

AFAIK this sort of stuff isn’t really documented officially, though it’s occasionally mentioned on forums/etc. If you’re doing stuff like this, you have to be prepared to work in low-documentation mode.

Wow, thanks for pointing out that the manual I was looking at was for the wrong version of the compiler. That explains why the address attribute was getting ignored.

The mem sections don't seem to give an option for specifying an address for a section in .text. They give an example of specifying an address for the .noinit section, but that is in .bss not .text.

I think the Arduino just doesn't provide a method of specifying addresses. That is frustrating as that ability is useful, but I understand the target audience for Arduino wouldn't typically do this.

Hard coding a version number into a specific address in memory might have been acceptable in the 1980s but not now.

You should never be aware of where the compiler has stored constants in your code. That is the surest way to write unmaintainable code.

Make the thing print the version number via one of the recognized output channels, like blinking a LED.

MorganS:
Hard coding a version number into a specific address in memory might have been acceptable in the 1980s but not now.

You should never be aware of where the compiler has stored constants in your code. That is the surest way to write unmaintainable code.

I think after you’ve done embedded work for a few years, you’ll feel different about your statements.

Embedded compilers include this ability for a reason. Arduino would include it too if it used a later version of avr-gcc. It’s not used often, but there are times when it’s needed.

  • Using a CRC in an application so that a bootloader can check it before running it.
  • The Serial Number example the other person gave above.
  • Data tables in flash that need to be page aligned (and probably kept out of the CRC calculation).
  • ID info so a binary image can be identified by bootloader firmware, bootloading software, or a person with a text editor.
  • Basically anytime you have to interact with code that you weren’t built with.

MorganS:
Just put a marker sequence in your code that you can search for in the hex file. Like maybe “Version”. Search for that and grab the bytes following.

Make the thing print the version number via one of the recognized output channels, like blinking a LED.

You have to appreciate how simple it is to open a hex file with Notepad++, go to the end of it, and know what revision it is. Even if I had to read the hex file out with avrdude because the code had locked up after doing its job for 2 years, I could still find out what version it was.

Using a string like “Version” to locate the information is less maintainable, uses more flash, and would be much more of a pain to read manually than putting the information at END_OF_MEMORY - 4.

I’m not sure how you think blinking an LED would help.

  1. If you have your own bootloader and you make it check the CRC then shouldn’t the compiling or boot loading process calculate that during upload and store it in its own data area? It shouldn’t appear as a constant in your C++ code.

  2. Yes, but how do you get that number out of the programmed chip? Downloading the raw binary is something only the original programmer can do and that programmer probably has other ways to see which version is on the chip. Like a sticker on the PCB?

  3. Data which changes should be in the data area, not the CRC protected program. Page alignment can be indicated to the compiler in other ways.

  4. What would the bootloader-with-CRC do with this information?

The idea about the LED is if this information is used by people other than the original programmer who has all the source and the binaries, there must be a way to get it out of the chip without owning an ICSP programmer.

MorganS: 1. If you have your own bootloader and you make it check the CRC then shouldn't the compiling or boot loading process calculate that during upload and store it in its own data area? It shouldn't appear as a constant in your C++ code.

The correct CRC must be calculated when the binary file is built. After that, there is opportunity for corruption. If the bootloading software wants to check the CRC it's fine, but it needs to know the correct CRC to compare to. An awful simple place to store the correct CRC, is at a fixed address near the end of memory.

The bootloader FW as well, has to know the correct CRC after the code is loaded. Every time the micro powers up, it will verify the application firmware is not corrupt before running it. If you write safety critical code in regulated industries (FDA, FAA, etc), you are required to do this.

MorganS: 2. Yes, but how do you get that number out of the programmed chip? Downloading the raw binary is something only the original programmer can do and that programmer probably has other ways to see which version is on the chip. Like a sticker on the PCB?

As long as the protection fuses aren't set, anyone can read the image out with avrdude. Even if it's some backward sketch that does nothing but enter an infinite loop, they can still read the image out with avrdude.

Stickers on PCBs started to go away in the 90s when flash memory became cheap. The firmware would usually be updated and nobody would open the product just to change the sticker. Even if a chip does have a sticker on it, in 2016 you pretty much always read it out of the device just to be sure.

MorganS: 3. Data which changes should be in the data area, not the CRC protected program. Page alignment can be indicated to the compiler in other ways.

As an example, a product uses a 4kB map of calibration data. The cal data must be nonvolatile so it's not in the data section, 4kB is too big for the eeprom, but since cal data is only written once or twice it's common to put it in the flash (similar to the previous poster's Serial Number example). The cal data would need to be preserved each time the executable is updated, which is most easily done by placing it at a fixed address.

MorganS: 4. What would the bootloader-with-CRC do with this information? The idea about the LED is if this information is used by people other than the original programmer who has all the source and the binaries, there must be a way to get it out of the chip without owning an ICSP programmer.

Well certainly there would be ways for the firmware to identify itself beyond reading out its binary image. Locating the ID info in a place that allows the developer or a software tool to identify an image without executing it, doesn't prevent the firmware from having a way to read the info out through a comm interface.

Optiboot (the UNO bootloader) uses a version number embedded at the end of the binary. The code is included with the IDE (hardware/arduino/avr/bootloaders/optiboot). They use inline assembly and a special section. You can look at the code and makefile to see how it is done.

Nice! I checked it out and it looks like Optiboot is doing exactly what I want to do.

It seems that in order to do it I can't build in the IDE, correct? Unless the IDE has some way I'm not seeing, for me to specify the additional "-Wl" link options?

Heh...sorry if it sounds like I want my cake and eat it too...

I don't think you can convince the IDE to do this. But have a look at hardware/arduino/avr/platform.txt, who knows it might be hackable. You are probably going to have to do it the hard way, with a makefile. Or you could "cheat" and edit the hex file by hand, that's probably doable. Look at the Optiboot hex file and then study up on how Intel hex files work. Good luck!

Thanks for pointing me to platform.txt. I was able to add the additional options there, modeled off optiboot.

I just needed to modify compiler.ldflags and "ompiler.elf2hex.extra_flags, and then add {compiler.ldflags} to recipe.c.combine.pattern. If I ever need to use a different mcu I'll probably switch to a makefile as it doesn't seem like platform.txt allows a way to modify the flags depending upon mcu.

For now it seems I'm good, which is cool since last week I had accepted this just wasn't possible with the Arduino environment!

Good . Well I couldn't resist trying to add a version number by editing the hex file. Simple to do and works just fine. So that's an option if the platform.txt hacking doesn't work out.