This is not a complete answer to your problem, but it's mostly there.
 
Following is the code I use to call my DownloadFirmware entry point in
the bootloader:
 
  /*  We don't care about a result because we'll be reloaded and never
   *  come back to this point.
   *
   *  We have to assemble this instruction because we're using an
ATmega2560,
   *  and have to address the high memory in flash.  That means the
address
   *  of AppDownloadFirmware MUST be 0x1F400 (0x3E800, byte addressed).
   */
//  AppDownloadFirmware();
    asm volatile ( "ldi  r24, 0x01   \n\t"
                   "out  0x3C, r24   \n\t"
                   "ldi  r30, 0x00   \n\t"
                   "ldi  r31, 0xf4   \n\t"
                   ".word 0x9519 ;eicall \n\t"
                 );

The reason I say this is "incomplete" is that I know the call to
AppDownloadFirmware() in the bootloader will not return.  Instead, the
firmware will be overwritten and the CPU reset.  That means I don't care
about clobbered registers.  Also, the jump location is hardwired.
 
You can take this to the next step by making this an inline function,
passing in the function address, and protecting the registers you
clobber so the processor can return (if you want).
 
Also, when I wrote this, the inline assembler did not grok the EICALL
instruction so I had to hand-assemble it.  You may be able to just use
the instruction now.
 
I hope this helps!
 
Best regards, 

Stu Bell 
DataPlay (DPHI, Inc.) 

 

________________________________

From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of
Dusan Ferbas
Sent: Monday, August 04, 2008 8:37 AM
To: avr-gcc-list@nongnu.org
Subject: [avr-gcc-list] eicall on ATmega2561


Hi,

we are trying to call a bootloader function from application. According
to data, different function is used there (eeprom, flash, SPI flash).
We have a problem, because it does not work. I consulted with Andy
Hutchinson a while ago, we investigated little more, but something more
is needed :-).
In other words it looks like EIND seeding does not work.

Are we missing to setup something ?

Is there a way, how to say to a GCC compiler, that asm part modifies
specific regs ?
For AVR, they are used to pass arguments.
Or is it a better way to create an inline function ?

...
it did not work leaving all work to compiler (WinAVR-20080610 used)
-----------------------------------------
  unsigned char eind_local = EIND;
  EIND = 0x3F800 >> (16 + 1); //highest LoadAddr bits  (for Atmega2561
== 1, because it is a word address)
  BootInfoHeader->fn[id](address, p_data, size);
  EIND = eind_local;

to be sure, what is happening (EIND seeding and restore left in C)
---------------------------------------
unsigned short call_address = (unsigned short)BootInfoHeader->fn[id];
asm volatile (
    "movw r30,%3" "\n\t"   //indirect call
    "push r20" "\n\t"      //preserve regs, used for args
    "push r21" "\n\t"
    "push r22" "\n\t"
    "push r23" "\n\t"
    "movw r20,%0" "\n\t"   //load args
    "movw r22,%1" "\n\t"
    "movw r24,%2" "\n\t" 
    "eicall" "\n\t"
    "pop r23" "\n\t"       //restore regs
    "pop r22" "\n\t"
    "pop r21" "\n\t"
    "pop r20"
    ::
    "r" (size),
    "r" (p_data),
    "r" (address),
    "r" (call_address)
    );

the only way, how it works (push return address, push call address and
make a "ret" to it, EIND is not needed)
-------------------------------------
unsigned char low_address = call_address & 0xFF;
unsigned char high_address = (call_address >> 8 ) & 0xFF;

unsigned char low_pc = 0x38;             //computed from .lst and .map
unsigned char high_pc = 0xFA;

asm volatile (
  "push r20" "\n\t"
  "push r21" "\n\t"
  "push r22" "\n\t"
  "push r23" "\n\t"
  "push %5" "\n\t"
  "push %6" "\n\t"
  "ldi r20,lo8(1)" "\n\t"
  "push r20" "\n\t"
  "push %3" "\n\t"
  "push %4" "\n\t"
  "push r20" "\n\t"
  "movw r20,%0" "\n\t"
  "movw r22,%1" "\n\t"
  "movw r24,%2" "\n\t" 
  "ret" "\n\t"
  "pop r23" "\n\t" 
  "pop r22" "\n\t"
  "pop r21" "\n\t"
  "pop r20"
  ::
  "r" (size),
  "r" (p_data),
  "r" (address),
  "r" (low_address),
  "r" (high_address),
  "r" (low_pc),
  "r" (high_pc)
  );





Dusan Ferbas
www.etech.cz <http://www.etech.cz/>  

_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Reply via email to