Placing data (revision) at specific flash location

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am updating a bootloader and would like to place some revision info at a specific location (very top of flash) so that it can be accessed by an application using the known address.

(Using AS7, target is AT90USB1286)

 

From research, I thought the following would work by adding

-Wl,--section-start=.text=0x1FC00 -Wl,--section-start=.version=0x1FFFC

to the Linker Miscellaneous flags.

/****************************************************************************
 * Add the following in Project Properties / Linker / Miscellaneous
 *     -Wl,--section-start=.text=0x1FC00 -Wl,--section-start=.version=0x1FFFC
 ****************************************************************************/

#include <avr/io.h>

#define MYVERSION     'r', '2', 'h', 0x01       // Revision ID, Version, Revision, Features byte

int main (void) {
    DDRB = 0x01;
    
    while (1) {
        PINB = 0x01;     // Just to have some code generated
    }
}

__attribute__ ((used, section (".version")))
uint8_t myVersion[]  = { MYVERSION };          // Version Info to be placed in flash

but it does not. The version info is not placed in the hex file:

:020000021000EC     <- Extended Segment Address
:10FC00004BC0000051C000004FC000004DC00000BC
:10FC10004BC0000049C0000047C0000045C00000C4
:10FC200043C0000041C000003FC000003DC00000D4
:10FC30003BC0000039C0000037C0000035C00000E4
:10FC400033C0000031C000002FC000002DC00000F4
:10FC50002BC0000029C0000027C0000025C0000004
:10FC600023C0000021C000001FC000001DC0000014
:10FC70001BC0000019C0000017C0000015C0000024
:10FC800013C0000011C000000FC000000DC0000034
:10FC90000BC0000009C0000011241FBECFEFD0E24E
:10FCA000DEBFCDBF02D005C0ABCF81E084B983B940
:06FCB000FECFF894FFCF27
                       <-- Version Info should be here
:040000031000FC00ED    <- Start Segment Address
:00000001FF            <- End of File

 

However, if I undefine "myVersion" using

-Wl,--section-start=.text=0x1FC00 -Wl,--section-start=.version=0x1FFFC -Wl,--undefined=myVersion

  for the Linker Miscellaneous flags, it does work. Here is the produced hex file...

:020000021000EC     <- Extended Segment Address
:10FC00004BC0000051C000004FC000004DC00000BC
:10FC10004BC0000049C0000047C0000045C00000C4
:10FC200043C0000041C000003FC000003DC00000D4
:10FC30003BC0000039C0000037C0000035C00000E4
:10FC400033C0000031C000002FC000002DC00000F4
:10FC50002BC0000029C0000027C0000025C0000004
:10FC600023C0000021C000001FC000001DC0000014
:10FC70001BC0000019C0000017C0000015C0000024
:10FC800013C0000011C000000FC000000DC0000034
:10FC90000BC0000009C0000011241FBECFEFD0E24E
:10FCA000DEBFCDBF02D005C0ABCF81E084B983B940
:06FCB000FECFF894FFCF27
:04FFFC0072326801F4    <-- Version Info ('r', '2', 'h', 0x01)
:040000031000FC00ED    <- Start Segment Address
:00000001FF            <- End of File

Is this the "proper" way to force a value to a specific location?

Why do I have to undefine "myVersion"?

 

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From memory [pun intended], there are several comprehensive threads on just this topic.  One was quite recent IIRC.  I guess we can divine the toolchain being used.  I don't know if it is version dependent.  You might well want to be more specific, as there may be differences if using PROGMEM or __flash.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you building with -fdata-sections and -gc-sections by any chance? Seems the "used" attribute may be ignored?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Are you building with -fdata-sections and -gc-sections
Both get applied by default in AS7 (7.0.1416).

I thought the "used" attribute would work since the bootloader does not reference "myVersion" itself, but apparently not.

 

I was misunderstanding the use of "undefined", thinking it was undefining the symbol rather than forcing the symbol to be entered into the output file!

 

Thanks Lee and Cliff for pointing me in the right direction...

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, im really glad i found this thread! but can someone explain to me whats going on?

Im not big on linkers and make files etc etc, i just use atmel studio 7 'out of the box' and expect it to do what i need it to 99.9% of the time

 

But i wanted to add a sw revision to the code, so i could read the srec file on an sd card and see if its a later version or not and decide to update or not, but had the same issue of not being able to get it to show up.

I did the -Wl-undefined thing, and it now works, but i'd really like to know what is actually going on, rather than just accepting it works and move on (might as well learn something today right?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nedward wrote:
I did the -Wl-undefined thing, and it now works, but i'd really like to know what is actually going on
The -Wl-undefined "injects" a yet undefined symbol into the linking process, as if this symbol were referenced (or "used") somewhere in the code.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok,

 

so if i had just used the variable i made somewhere, all would have been ok as well? Makes sense. Thanks.

 

Is there another way to get the compiler to just believe i want something in the code even though i dont 'use' it? i can imagine using a pointer to access things meaning the compiler has no idea what code im actually using right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nedward wrote:
i can imagine using a pointer to access things meaning the compiler has no idea what code im actually using right?
But how do you set the pointer to it? Surely you reference the object when you do something like:

type obj;

type * pObj;

   pObj = &obj;
   PORTB = *pObj;

That reference would be enough to enough to make the linker think this item was "used" and therefore it would not discard "obj". Of course if you did something nasty like building the code and noting in the map file that "obj" was located at 0x1234 and then:

   pObj = (type *)0x1234;
   PORTB = *pObj;

then, yes, I guess you have managed to make a reference to the object without naming it - but it's not a great approach. Next time you build it might be 0x1236.