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

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

Re: [avr-gcc-list] Relocating Code


From: Theodore A. Roth
Subject: Re: [avr-gcc-list] Relocating Code
Date: Thu, 12 Aug 2004 08:26:43 -0700 (PDT)

On Thu, 12 Aug 2004, Ramkumar Rengaswamy wrote:

> Hi,
>    I have an application where I am interested in relocating a particular
> function to a fixed location in the program memory.
> I do this by defining the __attribute__((section(".myfunction"))) in my C
> code and passing the option -Wl,--section-start=.myfunction=0x5000
> My .text section starts at address 0 and occupies only 4000 bytes.
> The code compiles fine but when I call the relocated function with a
> pointer parameter, the AVR resets.
> Is there any reason for such a behavior ?
> In general, are there any constraints for relocating a function in the
> program memory ?

How are you calling your relocated function? Are you assigning it's
address manually or letting the compiler/linker handle it?

Are you accounting for the fact that gcc does everything in terms of
byte addresses and calling a function in your code requires a word
address? For example, you are forcing the function to be at byte address
0x5000, but it's word address is really 0x2800, which is what call/rcall
need.

Here's an example program that demostrates what I'm talking about
(tested this with a mega128):

/*****************************/
#include <avr/io.h>

void foo (unsigned char arg) __attribute__((section(".myfunction")));

void
foo (unsigned char arg)
{
    PORTB |= arg;               /* Turn of the LEDS. */
}

typedef void (*func_ptr) (unsigned char arg);

void
call_fp (func_ptr fp, unsigned char arg)
{
    fp (arg);
}

int main (void)
{
    PORTB = 0x00;               /* Turn on the LEDS. */
    DDRB = 0xff;

    call_fp (foo, 0x0f);        /* Turn off the lower 4 LEDS. */
    call_fp ((func_ptr) 0x5000, 0xf0); /* Turn off the upper 4 LEDS. */

    return 0;
}
/*****************************/

Here's the relevant disassembled code:

000000d2 <main>:
  d2:   cf ef           ldi     r28, 0xFF       ; 255
  d4:   d0 e1           ldi     r29, 0x10       ; 16
  d6:   de bf           out     0x3e, r29       ; 62
  d8:   cd bf           out     0x3d, r28       ; 61
  da:   18 ba           out     0x18, r1        ; 24
  dc:   8f ef           ldi     r24, 0xFF       ; 255
  de:   87 bb           out     0x17, r24       ; 23
  e0:   6f e0           ldi     r22, 0x0F       ; 15
  e2:   80 e0           ldi     r24, 0x00       ; 0
  e4:   98 e2           ldi     r25, 0x28       ; 40
  e6:   0e 94 65 00     call    0xca
  ea:   60 ef           ldi     r22, 0xF0       ; 240
  ec:   80 e0           ldi     r24, 0x00       ; 0
  ee:   90 e5           ldi     r25, 0x50       ; 80
  f0:   0e 94 65 00     call    0xca
  f4:   80 e0           ldi     r24, 0x00       ; 0
  f6:   90 e0           ldi     r25, 0x00       ; 0
  f8:   0c 94 7e 00     jmp     0xfc

000000fc <_exit>:
  fc:   ff cf           rjmp    .-2             ; 0xfc
Disassembly of section .myfunction:

00005000 <foo>:
    5000:       98 b3           in      r25, 0x18       ; 24
    5002:       98 2b           or      r25, r24
    5004:       98 bb           out     0x18, r25       ; 24
    5006:       08 95           ret

Notice the addresses being passed via r24/r25 to the function calls:

  e0:   6f e0           ldi     r22, 0x0F       ; 15
  e2:   80 e0           ldi     r24, 0x00       ; 0
  e4:   98 e2           ldi     r25, 0x28       ; 40
  e6:   0e 94 65 00     call    0xca

The above is the one that works.

  ea:   60 ef           ldi     r22, 0xF0       ; 240
  ec:   80 e0           ldi     r24, 0x00       ; 0
  ee:   90 e5           ldi     r25, 0x50       ; 80
  f0:   0e 94 65 00     call    0xca

This second one jumps you deep into no-mans-land and the program counter
will eventually wrap around back to the reset vector (address 0x0000).

It's usually a bad idea to try to outsmart the compiler and linker. I
try to avoid it myself, but obviously, that's not always possible
(jumping into a bootloader comes to mind).

---
Ted Roth
PGP Key ID: 0x18F846E9
Jabber ID: address@hidden


reply via email to

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