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

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

RE: [avr-gcc-list] Function Address fixup missing?


From: Stu Bell
Subject: RE: [avr-gcc-list] Function Address fixup missing?
Date: Fri, 26 Jun 2009 15:47:43 -0600

> Stu Bell wrote:
> > Trampolines work only for statically linked functions, not function 
> > pointers.
> Sorry, but I don't understand this.
> I believe that there is no problem with statically linked functions.

And that's what I said. There is not a problem with statically linked
functions.

In your first email, you wrote:

> I have a function in upper 128K:
> int ButtamiViaSubito(void) {
>   return 3;
> }
> 
> In the main (in lower memory) i take the address and then I call the
> function:
> 
> extern int ButtamiViaSubito(void);
> typedef int (*PuntaAButtami)(void);
> PuntaAButtami puntatore;
> 
> int main(void)
> {
>   ...
>   puntatore = ButtamiViaSubito;    // (1)
>   ...
>   int butta = puntatore();         // (2)
>   ...
> }

At this point, "puntatore" is a function pointer.  Unless the GCC gods
disagree with me (in which case I have been doing a lot of work for
nothing for the last 2 years), GCC only understands puntatore as a
16-bit entity.  Further, it will *not* use the trampoline for this call.

What sayeth thee, oh GCC gods? :-)

In fact, given that the trampoline is not used for static calls to upper
flash, I am also confused as to why it is not used for function
pointers.  I suspect the problem is that if a function pointer is used
in a routine in upper flash, the 16-bit call would go to the wrong
place.  So, an EICALL must be generated to go to the trampoline, and
EIND must be set correctly for the call to work.  On the other hand, if
the compiler is generating a call to the trampoline which it *knows* is
in lower flash, EIND can always be forced to 0 before the call.  But
then the code needs to be smart enough to reset EIND to what it was
before the function pointer call.  That means that *every* function
pointer call would need to generate instructions to save EIND before the
call and more to restore it's state after the call.  This would need to
be done because the compiler (which generates the instructions) has no
idea where the eventual location of the code will be, so it must plan
for the worst.

Generation of instructions would need to be an architecture-dependent,
since the owners of ATTinys would be pissed if the compiler added
istructions for a different architecture that are completely worthless
to them.

Sounds like this is a job for a volunteer.  Would you like the job, Mau?

Again, as I said in my first post, you *must* place *all* targets of
function pointers (in this case, the function ButtamiViaSubito()) in
lower flash.  There is currently no other solution in GCC.  Trust me,
I've looked for one.

Again, as I said in my first post, if you look in
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70387
you will find that I describe exactly how to place all of these function
pointer targets in lower flash.  It isn't hard and if you choose you can
steal (err, leverage, yeah, that's it, leverage!) my work directly.

I will add one more gotcha here -- I've noticed that ISRs also work
"better" when in lower flash.  Theoretically this is not needed, but I
suspect that the compiler has some assumptions about upper versus lower
flash register states (specifically, EIND) that do not hold when an ISR
is in upper flash.

Sorry about the long reply, but I've spent time fighting this issue and
the results are, well, complicated.

Best regards, 

Stu Bell 
DataPlay (DPHI, Inc.) 





reply via email to

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