How to tell complier/linker to not generate code beyond this memory address?

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

Hi everyone,

 

I have read on the forum many times to build the application and bootloader in separate projects. Following that approach I realized if (application)app.hex and (bootloader)boot.hex are built independent of each other, when generating code for app.hex how would the complier know that don't write beyond this memory address (0x03FBFF) ? Because after this the bootloader is stored.

 

Is there a way or some setting that I can do, so I tell the compiler that only use memory upto 0x03FBFF and if my C code starts taking memory beyond this, warn me or throw an error.

 

Of course I can look at Program Memory Usage after building, but I need the complier to tell me in some way.

 

Thanks.

This topic has a solution.

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

Last Edited: Thu. Apr 29, 2021 - 11:47 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Can we assume you mean avr-gcc? Also by that large upper bound can we assume a 256KB micro with a 16KB bootloader section? (except 2560 does not have a 16K BOOTZSZ option does it?)

 

Anyway, if I build for a fairly popular 256 AVR (mega2560) and look at the .map file right near the top I see stuff like:

c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr6\libgcc.a(_exit.o)
                              C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.6.364/gcc/dev/atmega2560/avr6/crtatmega2560.o (exit)

This reveals that this particular micro is AVR architecture "avr6" in the eyes of the GCC tools.

 

What's more if I look in:

c:/program files (x86)/atmel/studio/7.0/toolchain/avr8/avr8-gnu-toolchain/avr/lib/ldscripts

(which takes the root of part of the path above then adds "avr/lib/ldscripts" to it) I find:

 

 

These are the original "X Files" ;-)

 

These are actually "linker scripts" and for the different types of AVR each gives a different kind of memory layout. We already know from the .map file inspection that the one of interest in this case is the one for "avr6" so is the file called avr6.x. At the top it contains:

 

 

The single "avr6.x" actually caters for a number of AVRs so the bounds in this are set to "worst" case. The stuff near the top:

__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 1024K;

says that in the absence of being told otherwise (by __TEXT_REGION_LENGTH__ being defined) it should assume a program area limit of 1MB (more than enough for any AVR in this group).

 

But this also reveals that if __TEXT_REGION_LENGTH__ is defined for the linker it will over-rule this generous limit.

 

Now in the exploration of the map file it also revealed that a "device pack" is being used for the build and it is in:

C:/Program Files (x86)/Atmel/Studio/7.0/Packs/atmel/ATmega_DFP/1.6.364/gcc/dev/atmega2560/avr6

within that one can find:

 

 

So this value of 256K (0x40000) is what is setting the limit for the text region size in ATmega2560. In fact you could see that in the .map file too:

Memory Configuration

Name             Origin             Length             Attributes
text             0x00000000         0x00040000         xr
data             0x00800200         0x00002000         rw !x
eeprom           0x00810000         0x00001000         rw !x
fuse             0x00820000         0x00000003         rw !x
lock             0x00830000         0x00000400         rw !x
signature        0x00840000         0x00000400         rw !x
user_signatures  0x00850000         0x00000400         rw !x

But note in the NM output that this symbol is shown as "W" which means it is only "weakly defined". So if you define it yourself this will over-ride the weak version being supplied form the CRT file.

 

So if I do this:

 

then after building, in the .map file I find:

 

 

So if I make that number very small and create a large chunk of flash data (a __flash array is a quick way to test this):

-Wl,--defsym=__TEXT_REGION_LENGTH__=0x100

also

#include <avr/io.h>

const __flash uint8_t data[1024];

int main(void)
{

leads to:

mcs7_test.elf section `.text' will not fit in region `text'collect2.exe(0,0): error: ld returned 1 exit status
		make: *** [mcs7_test.elf] Error 1

If I increase the definition of __TEXT_REGION_LENGTH__

Memory Configuration

Name             Origin             Length             Attributes
text             0x00000000         0x00001000         xr

then it builds OK because 1K+some change fits into 4K.

 

So ultimately I guess you want:

-Wl,--defsym=__TEXT_REGION_LENGTH__=0x3C000

which sets the text region length to 240K. If you build code larger than this you will get that error about "'.text' will not fit"

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

Thanks clawson for the thorough explanation. I am using avr-gcc and ATmega2560 for practice.

 

clawson wrote:
except 2560 does not have a 16K BOOTZSZ option does it?

Yes it does not have 16k boot space. But I wonder how I arrived at  0x03FBFF

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

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


Heisen wrote:
But I wonder how I arrived at  0x03FBFF
That's what I was wondering too. The options are:

 

 

So converting 1FE00, 1FC00, 1F800, 1F000 from word to byte boundaries it seems the options are 3FC00, 3F800, 3F000, 3E000. So I expect you would be using one of those.

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

Now I know why I arrived at 0x03FBFF because I am not getting the addresses properly.

 

Here is the confusion -

 

ATmega2560 has 256KB of flash memory. Which in bytes means total of 256000 bytes of storage. Goes from 0x00000-0x3E7FF in byte addressing.

 

But in Image above, the total memory is show as 0x00000-0x1FFFF in word addressing, so in bytes that must be 0x00000-0x3FFFF, which means total of 262144 bytes. So this goes beyond the 256KB of mentioned flash memory.

 

I know I am wrong somewhere, but where? 

 

 

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

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

1k = 1024, not 1000,  256k = 262144 not 256000!

 

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

Lets go Brandon!

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

Got it, so noob I am. How can I miss this, even though I know this very well. RIP confidence level.

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

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

No sweat!  I just noticed your in India, news here says COVID is running wild there, so stay safe!

Jim

 

 

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased! 

Income is proportional to how many you serve!

Lets go Brandon!

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

Also note that Atmel count flash in 16 bit words (2 bytes at a time) so when they say 1FC00 they mean byte address 3F800 (and if that sounds like it has been done  to deliberately confuse the world, it has.