[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Fw: [avr-gcc-list] Array of pointers to functions revisited...
From: |
Royce & Sharal Pereira |
Subject: |
Fw: [avr-gcc-list] Array of pointers to functions revisited... |
Date: |
Tue, 20 Jul 2004 00:49:11 +0530 |
----- Original Message -----
From: "Ned Konz" <address@hidden>
To: <address@hidden>; "Royce & Sharal Pereira" <address@hidden>
Sent: Monday, July 19, 2004 7:04 PM
Subject: Re: [avr-gcc-list] Array of pointers to functions revisited...
On Sunday 18 July 2004 2:52 pm, Royce & Sharal Pereira wrote:
> Now when I looked at the .lss file it wasn't any fun() :)
>
> The array call_fun had anything but the addresses of fun1, fun2 etc. !!
> In the .lst file I see a '.word pm(fun1)' instead of a '.word fun1'
> etc.(BTW What's this pm ?)
>
> The second problem is- The line-
>
> fun= pgm_read_word(call_fun[f_cnt]);
>
> does not get the desired address correctly. There is a un-necessary 'ld'
> before 'lpm' which destroys the Z reg, so that the fetched address is
> wrong(I assume you will compile my code & see the result).
Why are you all going through all of the pgm_read_word() stuff? Just good old
C...
--------
/*
avr-gcc -O3 -Wall -Wl,-Map,test.map -g -mtiny-stack -mint8 -mmcu=atmega16 -o
test.elf test.c;
avr-objdump -h -S test.elf > test.lst
R16/17 is call_fun
R26 is X reg
R28 is Y reg
R30 is Z register
*/
#include <inttypes.h>
#include <avr/pgmspace.h>
static void fun1(void) { }
static void fun2(void) { }
static void fun3(void) { }
typedef void (PROGMEM * pFun)(void);
static pFun PROGMEM call_fun [3] = { &fun1, &fun2, &fun3 };
int main(void)
{
uint8_t i;
for (i = 0; i< 3; i++)
(call_fun[i])();
return 0;
}
--------
Which produces (on avr-gcc 3.4.0) the extremely straightforward:
int main(void)
{
9a: cf e5 ldi r28, 0x5F ; 95
9c: d4 e0 ldi r29, 0x04 ; 4
9e: de bf out 0x3e, r29 ; 62
a0: cd bf out 0x3d, r28 ; 61
a2: c2 e0 ldi r28, 0x02 ; 2
a4: 04 e5 ldi r16, 0x54 ; 84
a6: 10 e0 ldi r17, 0x00 ; 0
uint8_t i;
for (i = 0; i< 3; i++)
(call_fun[i])();
a8: d8 01 movw r26, r16
aa: ed 91 ld r30, X+
ac: fd 91 ld r31, X+
^ ^^
---'LD'? wasnt the array initialised in ROM earlier? An LPM is required here!
---That was the reason for all the pgm_read_word() stuff.
---Normal C is ok if the array was in ram. But getting avr-gcc to fetch from
ROM requires some
arm-twisting.
ae: 8d 01 movw r16, r26
b0: 09 95 icall
b2: c1 50 subi r28, 0x01 ; 1
b4: c7 ff sbrs r28, 7
b6: f8 cf rjmp .-16 ; 0xa8
return 0;
}
--Thanks,
--Royce.