what is .trampolines section?

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

Could you explain me what is .trampoline section? When to use? How to use?
I tried to serch something about .trampolines without find nothing useful.

thanks

mastupristi?

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

That section is created when in a >128kB FLASH device (ATMega256x and some of the XMegas) an indirect function call (through function pointer or in a certain case of switch command) happens to a function located above the 128kB boundary.

You don't need to think about it nor to use it in any way; it is created automatically by the toolset.

However, be aware that this process appears to be broken currently, see https://www.avrfreaks.net/index.p...

JW

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

A little more on the issue: GCC pointers - of all types - are only 16-bits in length. That means you can address up to 128KB of FLASH memory directly with them, since FLASH is addressed as a number of 16-bit words and not bytes like SRAM.

However, that means that they cannot address data or functions located above 128KB of FLASH space. A few 8-bit AVRs have 256KB of FLASH, so this means we need a way to address the higher flash segment when we perform an indirect function call. The solution is this automatically generated "trampoline" section which contains code needed to call the higher addresses. When your code needs to get above the 128KB barrier via an indirect function call, it instead "bounces" up to the desired location via the code in the trampoline section.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Thanks for the explanation, though I'm still slightly confused.

Why does this only affect "indirect" function calls? And what does that mean exactly. Doesn't any call to a function in flash > 128K mean it has to use a jump instruction which would need to specify either an absolute address which is greater than 16-bits or perhaps a relative offset which depending on where you're making the call from could be greater than 16-bits.

Also, you say it bounces off the code in the .trampoline section... what does that mean exactly? Surely there are still jump instructions in there that must address the problem I describe in the paragraph above?

Thanks in advance for your help and time.

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

With a direct call in your code:

void function_in_upper_128KB(void)
{
 // Code
}

void some_other_func(void)
{
    function_in_upper_128KB();
}

The compiler can see that it needs to produce a 24-bit function call sequence, and so can perform a call anywhere in FLASH directly. However, pointers for 8-bit AVRs are all 16-bit regardless of their destination type, so there isn't enough space to encode the full 24-bit FLASH address. Take this example:

void function_in_upper_128KB(void)
{
 // Code
}

void some_other_func(void)
{
	(void) (*function_ptr)(void) = function_in_upper_128KB;

    function_ptr();
}

Here if the compiler did a normal transformation into assembly code, the resulting indirect call (function call through a function pointer) would cause the AVR to jump to the wrong address, as it can't know that the destination is in the upper segment of FLASH. To fix this, when you try to take the address of a upper-segment function, what you really get is the address of an entry in the trampoline table.

The trampoline table is in the lower segment of FLASH, which means it is reachable via normal function pointers. It contains full 24-bit jumps to the corresponding functions in the upper segment FLASH.

Via this mechanism you can continue to use function pointers normally, and the compiler uses the trampoline table as a proxy to fix up your code silently, by making your code jump first to the trampoline entry in the table, and then to the real destination via a 24-bit call.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Does it have something to do with de bouncing?

Four legs good, two legs bad, three legs stable.

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

Ah, so direct calls and the trampoline code would make use of the EIJMP/EICALL instructions which use the EIND register to specify the upper 6 bits of the entire 22-bit PC register?

Info from here: http://www.atmel.com/images/doc0...

I think we agree on everything except that document seems to say its a 22-bit call not 24-bits.

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

22 significant bits yes, but I'm yet to see an AVR that can take in a 6-bit integer without having to have two more bits along for the ride ;).

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

Dean, you said that GCC pointers of all types are only 16 bits.
I hope and pray you mean avr-gcc!

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

This forum is dedicated to 8bit avr-gcc, what else would he be referring to?

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

Yes, I should have specified (pointer width can be set per-architecture in GCC). Theoretically AVR-GCC for 8-bit AVRs could be compiled to use 32-bit pointers, but that would be grossly inefficient.

- Dean :twisted:

PS: Note to self, use exact terminology here in the future :P

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

So, flash > 64k doesn't bother anything unless you're using pointers to functions, and then GCC takes care of it for you. I just ordered some MEGA1284's, and I'm used to things like Tiny 2313 and Tiny45

How 'bout data stored in PROGMEM?

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Quote:

How 'bout data stored in PROGMEM?

You only really face issues when you amass more than 64KB of data - that's fairly unusual.

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

Note that the compiler does not decide which functions go into the upper reaches.
The linker does that.
Some references to some functions go to the linker-generated trampoline section and some directly the functions.
The linker needs to do some rather interesting things and it does them.

Moderation in all things. -- ancient proverb

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

skeeve wrote:
Note that the compiler does not decide which functions go into the upper reaches.
The linker does that.
Some references to some functions go to the linker-generated trampoline section and some directly the functions.
The linker needs to do some rather interesting things and it does them.

0. Addresses in indirect jumps/calls are in words rather than bytes. In the 128kB FLASH devices, all functions are within the 64kW address space, so Torby does not need to be bothered by the trampolines/stubs stuff at all.

1. As said by others in previous posts of this thread, direct jumps/calls are well within the reach of standard CALL/JMP in all currently existing AVRs. So we are talking about the indirect addressing now, as in IJMP/ICALL and EIJMP/EICALL. The compiler uses that in two cases - when function pointers are used, and when it decides that a case/switch construct is better to be solved by a table jump rather than a series of conditional jumps. The former is fully under control of the user (and in most cases avoidable through program design/methodology), the latter can be suppressed using some command-line switch (-fno-jump-tables IIRC). Thus, trampolines can be avoided altogether even in the >128kB/64kW programs.

2. Many programs in >128kB/64kW devices use extensive PROGMEM data. They can be deliberately moved above .text and accessed as far-progmem (I'd like to refer to the new named address spaces of the 4.7+ compiler, but AFAIK it's not ready to be seamlessly usable as far as the >64kB FLASH space is concerned, and there's little to no user-grade documentation for it either - Atmel, do you listen?) - I have written on this before; but beware of the following:

3. The linker in its default setting (no relaxation) is rather dumb and *all* indirect calls in the >128kB/64kW devices go through the trampolines. It is the relaxation process in the linker which, if switched on, recognizes that the indirect jumps into the 0th "page" don't need to go through trampolines and fixes that.
Note, that this did not use to be this way, and a bastardized version of relaxation removed the 0th-page-targeting trampolines even when relax was off. This worked as long as all such jumps were below the 64kW limit, but if not, "interesting" errors resulted - that's what the second post in this thread talks about. That's why now the non-relaxing process leaves all trampolines in place. If the user *knows* that all his jumps are below the 64kW limit (e.g. becasuse all the code is there and there's only data above), and does not wish to use relax, he could decide to use --no-stubs linker switch to avoid trampolines at all.

JW