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

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

RE: [avr-gcc-list] Function pointers on > 128 KiB devices, how to?


From: Stu Bell
Subject: RE: [avr-gcc-list] Function pointers on > 128 KiB devices, how to?
Date: Wed, 20 Jan 2010 08:14:49 -0700

Known problem.  See my FreeRTOS for the ATmega2560 post in the AVR
Freaks Tutorials.

The only solution I have is to force all function pointer targets to be
in bottom flash (< 128KiB).  The fix I used is to create a section after
the .init* sections in the linker script and put all function pointer
target functions in that section.  Once you are in the targetted
function, all sunsequent functions can reside anywhere.

One other warning:  Large switch statements get upset if they lie on the
128K boundary.  The error you get here is a linker error.  You may need
to rearrange your object load order to make sure the switch statement is
on one side or other of the boundary.

Best regards, 

Stu Bell 
DataPlay (DPHI, Inc.) 

 

> -----Original Message-----
> From: address@hidden 
> [mailto:address@hidden 
> On Behalf Of Joerg Wunsch
> Sent: Wednesday, January 20, 2010 6:54 AM
> To: address@hidden
> Subject: [avr-gcc-list] Function pointers on > 128 KiB 
> devices, how to?
> 
> When porting a larger application to a 256 KiB device, we 
> stumbled across our function pointers and jump tables.  
> Consider the following code:
> 
> #include <stdint.h>
> #include <avr/pgmspace.h>
> 
> void foo(void);
> void bar(void);
> void mumble(void);
> 
> typedef void (*fptr) (void);
> 
> fptr jumptable[] __attribute__((progmem)) = {
>         foo,
>         bar,
>         mumble,
> };
> 
> volatile uint32_t i, j, k;
> 
> void
> foo(void)
> {
>         for (uint8_t x = 0; x < 200; x++) {
>                 i = j * 5 + k * 7;
>                 j = i + 32412341243;
>                 k = i & 0x12345678ull;
>         }
>         for (uint8_t x = 0; x < 200; x++) {
>                 i = j * 5 + k * 7;
>                 j = i + 32412341243;
>                 k = i & 0x12345678ull;
>         }
> }
> 
> void
> mumble(void)
> {
>         for (uint8_t x = 0; x < 200; x++) {
>                 i = j * 5 + k * 7;
>                 j = i + 32412341243;
>                 k = i & 0x12345678ull;
>         }
>         for (uint8_t x = 0; x < 200; x++) {
>                 i = j * 5 + k * 7;
>                 j = i + 32412341243;
>                 k = i & 0x12345678ull;
>         }
> }
> 
> void
> bar(void)
> {
>         for (uint8_t x = 0; x < 200; x++) {
>                 i = j * 5 + k * 7;
>                 j = i + 32412341243;
>                 k = i & 0x12345678ull;
>         }
> }
> 
> int
> main(int argc, char **argv)
> {
>         fptr f;
> 
>         if (argc < sizeof jumptable / sizeof jumptable[0]) {
>                 f = (fptr)pgm_read_word(jumptable[argc]);
>                 f();
>         }
> 
>         return 0;
> }
> 
> ...compiled with (thoroughly pessimized to generate large amounts of
> code):
> 
> avr-gcc -O3 -funroll-loops --param max-peeled-insns=1000000 \ 
--param max-completely-peel-times=1000000 \ --param max->
unrolled-insns=1000000 \ 
> --param=max-completely-peeled-insns=1000000 \ --param 
> max-average-unrolled-insns=1000000 \ -mmcu=atmega2560 
> -std=c99 -g -o foo.elf foo.c
> 
> This yields:
> 
> /tmp/cc1QZqci.o: In function `foo':
> /tmp/foo.c:20: warning: internal error: out of range error
> 
> Trying to replace the pgm_read_word() by a 
> pgm_read_dword_far() just adds more warnings about casting 
> pointers/integers of different size, but doesn't help for the 
> initial "out of range" error anyway.
> 
> Is there any option at all to use function pointers for a 
> device which supports code sizes > 128 KiB?  I (incorrectly) 
> assumed these were replaced by trampoline pointers, but 
> apparently, they aren't.
> 
> Any ideas welcome, possibly including quick&dirty inline asm 
> hacks to generate the indirect call.
> 
> -- 
> cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL
> 
> http://www.sax.de/~joerg/                        NIC: JW11-RIPE
> Never trust an operating system you don't have sources for. ;-)
> 
> 
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
> 




reply via email to

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