Show proper allowed memory size when bootloader is installed

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

Greetings -

 

Is there any way of telling AS6.x / avr-gcc that a bootloader will be installed and to reduce the allowable size of memory accordingly? So far, I have not been able to find any place where presence of bootloader or the BOOTSZ bits are ever considered. 

 

Thanks

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Tue. Apr 28, 2015 - 04:11 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can hack the system .x file or copy it and use -T to then use your local copy.

 

The avr5.x for example (the one for things like mega16) says this:

OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 128K
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
  signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
  user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = 1K
}
etc.

The LENGTH=128K there on .text is because in the AVR5 family there are devices up to 128K. But say you had a 16K mega16 with a 2K bootloader then you could set that to 14K. Now if you build/link and the size goes over 14K for .text you will get a linker error

 

The .x files are in <installation>/avr/lib/ldscripts/avr*.x

 

As I say, if you check a current map file you can see whether its avr5 or some other architecture you are building for. Say it was "avr3" then copy avr3.x from that directory. Modify the LENGTH= and save it in your project directory as myavr3.x. Now when you build pass -Wl,-T myavr3.x and it will be your modified .x file that is used.

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

Jim,

 

You can either inspect the Build size with your own eyes,   or wait for the Bootloader to whinge.

 

(any respectable bootloader will detect if you try to write to an illegal area.    the lockbits will physically stop the write anyway)

 

If you are using AS6 for debugWIRE debugging,   you would disable BOOTRST.   (the bootloader would get erased)

 

Of course you could create a 'special' as suggested by Cliff.

Or grep the existing 'avr-size' output.

Or you could run your own 'avr-size' as a post-build.

 

I get the feeling that you are a GUI sort of user.    In which case,   visual inspection is required.

If you are a command-line sort of user,   you would simply add custom commands to your Makefile.

 

Incidentally,   the Arduino IDE 'knows' the available Flash memory for each board/bootloader combination.    (from "boards.txt")

 

David.

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

david.prentice wrote:
Or you could run your own 'avr-size' as a post-build.
You could also automate the detection of exceeding the boundary.  I build bootloaders for a raft of AVR targets and I use an awk script to check that the resulting size doesn't exceed the alloted space.  In the script below, the FLASH_SIZE and BOOT_ADDR values are passed in on the command line and the textSize is extracted from the avr-size output.  The line from the makefile is:

 

$(SIZE) --format=sysv $(OBJDIR)$(TARGET).elf | fromdos | $(AWK) --assign BOOT_ADDR=$(BOOT_ADDR) --assign FLASH_SIZE=$(FLASH_SIZE) -f checkBoot.awk

 

checkBoot.awk:

BEGIN {
    textSize = 0;
}

END {
    flashSize = getVal(FLASH_SIZE);
    bootAddr = getVal(BOOT_ADDR);
    printf("Bootloader size is %s bytes\n", textSize);
    if ((bootAddr + textSize) > flashSize)
    {
        msg = sprintf("error: bootloader exceeds boot section size");
        print msg > "/dev/stderr";
        exit 1;
    }
}

/^\.text/ {
    if (match($0, "[0-9]+"))
    {
        textSize = 0 + substr($0, RSTART, RLENGTH);
    }
}

{
}

 

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

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

I suppose the requested facility is of marginal value.

 

How often does one build your app?  How hard is it to look at the resulting flash usage, and compare to a value on a PostIt note on your computer monitor? (After all, only you know the bootloader section size.)

 

Some of us might want to create a composite app+bootloader for initial programming of virgins.  Won't that upset your facility?

 

To guard against "accidents", the PC side of the bootloader could do the needed check.  After all, it needs to process the .HEX into a .BIN equivalent anyway.

 

Can't you set the fuse "SPM is not allowed to write to the Boot Loader section"?
 

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

As David said  bootloader given too much code will hopefully cry "Oi!". As such I'd probably just leave it until run time and the first attempt to deliver the "too big thing". You'll soon know after building it.

 

Having said that the .x thing should be easier than I said in reality ;-)

 

(off to try it now and see if it works...)

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

EDIT: OK that turned out to be fairly easy...

$ cat size.c
#include <avr/pgmspace.h>

char data[2048] PROGMEM = { 1,2,3,4 };

int main(void) {
}

$ head myavr5.x 
/* Default linker script, for normal executables */
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 1K
  data   (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
$ avr-gcc -mmcu=atmega16 -Wl,-Map,size.map -Wl,-T,myavr5.x size.c -o size.elf
/usr/lib/gcc/avr/4.5.3/../../../avr/bin/ld: size.elf section `.text' will not fit in region `text'
collect2: ld returned 1 exit status

The most complex thing for me was finding out where the existing avr5.x was located on my machine. I used -Wl,-Map,size.map but its location is not mentioned in there. A quick Google told me to use -Wl,-verbose which forces the linker to show more info and it told me:

$ avr-gcc -mmcu=atmega16 -Wl,-Map,size.map -Wl,-verbose size.c -o size.elf
GNU ld (GNU Binutils) 2.20.1.20100303
  Supported emulations:
   avr2
   avr1
   avr25
   avr3
   avr31
   avr35
   avr4
   avr5
   avr51
   avr6
   avrxmega1
   avrxmega2
   avrxmega3
   avrxmega4
   avrxmega5
   avrxmega6
   avrxmega7
   avrtiny10
opened script file /usr/lib/ldscripts/avr5.x
using external linker script:

which told me what file it used by default. I later replaced the -Wl,-verbose with the -Wl,-T,myavr5.x after I had changed the LENGTH=128K to be LENGTH=1K

Last Edited: Tue. Apr 28, 2015 - 02:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, folks -

 

For now, this takes more energy than I want to put into it. I do, however, have a lot greater appreciation for what is involved.

 

What I had envisioned was a button to click in a project window. The button would say "This project has to coexist with a bootloader".  Then, if there are predefined bootloader sections, there would be some radio buttons to select the size. If there is no predefined bootloader section, one would enter the  size manually, maybe with a slider. The IDE would then modify the size number used by the  compiler or one of its minions to report on the percentage of available program memory that has been occupied by the build in question. Alas, sounds like too much to ask for.

 

Cheers and many thanks

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Tue. Apr 28, 2015 - 03:51 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I know this is an old thread, but for people coming here in the future there is an easy solution you can use in AVR Studio version 7.0 (it's not in 6.2).  No custom linker file is required.

 

Add this to your custom linker flags (Properties > Toolchain > AVR/GNU Linker > Miscellaneous), adjusting for your size limit:

 

-Wl,--defsym=__TEXT_REGION_LENGTH__=30720

 

You'll now get an error from the linker when you go over the specified size:

 

Error region `text' overflowed by 1052 bytes

 

Other symbols you can define can be seen by looking in your linker script file, e.g.: C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\lib\ldscripts\avr5.xn

Last Edited: Mon. Feb 5, 2018 - 07:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow that is interesting!! Thanks for sharing.