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

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

RE: [avr-gcc-list] eicall on ATmega2561


From: Stu Bell
Subject: RE: [avr-gcc-list] eicall on ATmega2561
Date: Mon, 4 Aug 2008 09:02:40 -0600

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: address@hidden [mailto:address@hidden On Behalf Of Dusan Ferbas
Sent: Monday, August 04, 2008 8:37 AM
To: address@hidden
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


reply via email to

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