[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Re: [avr-gcc-list] Allocating variables to a fixed address]
From: |
Robert von Knobloch |
Subject: |
[Re: [avr-gcc-list] Allocating variables to a fixed address] |
Date: |
Wed, 13 May 2009 11:35:45 +0200 |
User-agent: |
Thunderbird 1.5.0.14 (X11/20060911) |
Stu Bell wrote:
> > If I had your problem, this is how I would solve it: Define a real table
> > of function pointers instead of trying to get the linker to create one
> > for you.
> >
> > typedef void (*TestProc) (void*);
> >
> > NOINLINE void test_lcd_2(void* pStr) {PGM_P string = (PGM_P) pStr;
> > prog_lcd_string2(string); }
> >
> > NOINLINE void test_lcd_string(void* pStr) { PGM_P string = (PGM_P)
> > pStr; prog_lcd_string(string); }
> >
> > NOINLINE void test_clearlcd2(void* ign) { clearlcd2(); }
> >
> > NOINLINE void test_lcd_hex4out(void* pByte) { uint8_t byte = *
> > (uint8_t*) pByte; return lcd_hex4out(byte); }
> >
> > ...
> >
> > const TestProc* TestTable[TEST_VECTORS] FUNCTION_SECTION = {
> > test_lcd_2,
> > test_lcd_string,
> > ...
> > };
> >
> > You will need to modify your calls to either send the pointer to the
> > argument (this forces all calls to have a single parameter of,
> > essentially, a word) or to always send a word. In either case, the
> > receiving routine will then cast the argument to the proper value before
> > passing it on.
> >
> > Do not place the routines or other constants in the same linker section
> > as the function table. If you leave the table in a section of its own,
> > it will always be placed at the head of the section without interference
> > from anything else.
> >
> > Calling the function requires you to pull the function out of the table
> > before calling it:
> >
> > #define TESTPROC_LCD_2 0
> > #define TESTPROC_LCD_STRING 1
> > . . .
> >
> > uint16_t test_proc;
> >
> > test_proc = pgm_read_word( (uint16_t) &TestTable[ TESTPROC_LCD_2 ] );
> > *(TestProc*)test_proc( myarg );
> >
> > . . .
> >
> > You could probably enclose the above stuff in a macro to make your code
> > far more readable:
> >
> > #define CallTestProc(proc,arg) \
> > do { \
> > uint16_t test_proc; \
> > test_proc = pgm_read_word( (uint16_t) &TestTable[ (proc) ] );
> > \
> > *(TestProc*)test_proc( (arg) ); \
> > } while (0);
> >
> > . . .
> >
> > CallTestProc( TESTPROC_LCD_2, myarg );
> >
> > That's my inspiration for the day. It's probably wrong somewhere, but
> > it's how I would approach the problem.
Hi Stu,
This solution, while a purer 'C' solution would require me to have all
my 'internal' functions with similar call/return requirements.
This is not, and cannot be, the case. I fear that the magig 'array of
function pointers' has only limited use and is unsuitable here.
But many thanks for your thoughts, every comment here makes me re-think
the problem, which is good.
Cheers,
Robert
- [Re: [avr-gcc-list] Allocating variables to a fixed address],
Robert von Knobloch <=