[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Array of pointers to functions revisited...
From: |
Ned Konz |
Subject: |
Re: [avr-gcc-list] Array of pointers to functions revisited... |
Date: |
Mon, 19 Jul 2004 08:17:22 -0700 |
User-agent: |
KMail/1.6.2 |
On Monday 19 July 2004 6:43 am, E. Weddington wrote:
> > Which produces (on avr-gcc 3.4.0) the extremely straightforward:
>
> Which is wrong.
>
> The call_fun array above has been put into the Program Memory Space by
> using the keyword PROGMEM. Therefore, to access those values, one needs to
> pull them from Program Memory Space by using the <avr/progmem.h> API,
> pgm_read_word(), which reads a word (16 bits) from the Program Memory
> Space. This reads the specified array slot which contains the address of
> the function, which is then dereferenced and called.
Ah, right.
How about this?
/*
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++)
{
pFun p = (pFun)pgm_read_word(call_fun + i);
p();
}
return 0;
}
-------- which produces:
typedef void (PROGMEM * pFun)(void);
static pFun PROGMEM call_fun [3] = { &fun1, &fun2, &fun3 };
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: 12 e0 ldi r17, 0x02 ; 2
a4: c0 e0 ldi r28, 0x00 ; 0
a6: d0 e0 ldi r29, 0x00 ; 0
uint8_t i;
for (i = 0; i< 3; i++)
{
pFun p = (pFun)pgm_read_word(call_fun + i);
a8: ce 01 movw r24, r28
aa: 8c 5a subi r24, 0xAC ; 172
ac: 9f 4f sbci r25, 0xFF ; 255
ae: fc 01 movw r30, r24
b0: 25 91 lpm r18, Z+
b2: 34 91 lpm r19, Z
p();
b4: f9 01 movw r30, r18
b6: 09 95 icall
b8: 11 50 subi r17, 0x01 ; 1
ba: 22 96 adiw r28, 0x02 ; 2
bc: 17 ff sbrs r17, 7
be: f4 cf rjmp .-24 ; 0xa8
}
return 0;
}
c0: 80 e0 ldi r24, 0x00 ; 0
c2: 0c 94 63 00 jmp 0xc6
000000c6 <_exit>:
c6: ff cf rjmp .-2 ; 0xc6
--
Ned Konz
http://bike-nomad.com