avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Allocating code to separate sections


From: Alistair Gadd
Subject: Re: [avr-gcc-list] Allocating code to separate sections
Date: Thu, 09 Oct 2014 16:39:14 +0200
User-agent: Mozilla/5.0 (Windows NT 5.2; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0


On 2014/10/09 01:14 PM, Erik Christiansen wrote:
On 09.10.14 08:49, Alistair Gadd wrote:
I think I prefer your first option though because it would put everything in
that module into the .sdlib section, but my problem is I don't know how to
create and use the linker script.
To take a copy of the linker script used for the ATmega328p:

$ avr-gcc -mmcu=atmega328p -Wl,--verbose > ld.lnk

Then, in your favourite editor, delete the two long lines of
"============", and anything outside them, keeping only the linker
script in between. And add the

   .sdlib : 0x2000
   {
        file & input section specs here
   }

where it needs to go in relation to the existing output sections.

To use your custom linker script, add "-T ld.lnk" to CFLAGS in a
makefile, or add it directly to the avr-gcc command line if that is more
convenient.

N.B. The following question and suggestion may arise because the IDE
does something weird which I have not seen:

But can those addresses possibly work? Looking at
"26.8.16 ATmega328P Boot Loader Parameters" in the datasheet, the
available bootloader addresses are: 0x3F00, 0x3E00, 0x3C00, and 0x3800.
It shows the application code _ending_ at 0x37FF, in the latter case.

In any event, the bootloader area of flash is an entirely separate
memory segment, which is best made explicit in the MEMORY description in
the linker script. To set the scene, here is how I last did it for an
ATmega16, also with the bootloader at the top of memory:

MEMORY 
{
  text   (rx)   : ORIGIN = 0, LENGTH = 62K
  boot   (rx)   : ORIGIN = 62K, LENGTH = 2K
  data   (rw!x) : ORIGIN = 0x800100, LENGTH = 4K
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 2K
}

Doing it that way for the ATmega328p would need adding of one line, and
modification of another, along the lines of:

MEMORY
{
  text      (rx)   : ORIGIN = 0, LENGTH = 30K
  boot      (rx)   : ORIGIN = 30K, LENGTH = 2K
  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
}

That corresponds with "Table 26-13. Boot Size Configuration, ATmega328P"
in the datasheet, AIUI. Now all you have to do is add:

  .boot :
  {
    *(.boot_init)       /* You may have different input
                              section names */
    *(.boot)
  } > boot

between

   .text
   {
     ...
   }              <- After this closing brace.

and

   .data
   {
     ...

Alternatively, you could skip the then necessary e.g.

void boot(void) __attribute__ ((section (".boot")));

by using my_boot_filename(*.text), as Senthil describes.

But using also e.g. __attribute__ ((section (".boot_init"))) allows you
to specify link order within the output section explicitly in the
linker script as I have shown.

I'm not sure how digestible such a short description is, given that this
is your first encounter with linker scripts, but the basics are simpler
than they look. It is only adventurousness which finds the boggy
patches.

If it is essential to use the name ".sdl", because the IDE otherwise
can't cope, then by all means change it. But with your own linker
script, you should be fully in control.

Erik


Hi Senthil and Erik,

Many thanks to you both for the help on this one - I believe I am getting there slowly.

Erik, I am going to have to take some time to absorb your response while I play with the linker scripts. On your comment on the addresses used, I used 0x7000 for the bootloader start (CFLAGS -Ttext 0x7000) because it seems that the compiler wants a byte address and not a word address and the IDE wants a word address for defining the .sdlib section (.sdlib==0x2000) - here's an extract from the generated command line:

avr8-gnu-toolchain\bin\avr-g++.exe" -o  ....................... -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -Wl,-section-start=.sdlib=0x4000  -mmcu=atmega328p -Ttext 0x7000 -T ../avr5_sdlib.xn

The generated intel hex file placed the code at 0x4000 (.sdlib) and 0x7000 (.text) as byte addresses which would relate to word address of 0x2000 and 0x3800 when loaded into the processor and the vectors placed at 0x7000 and upwards in the hex file were all jumps to 0x38XX addresses. My plan is to move .sdlib right up once I've got things working. Please correct me if I've got this all wrong.

Best regards, and thanks again for all the help,
Alistair.

--


reply via email to

[Prev in Thread] Current Thread [Next in Thread]