0

I'm working on a embedded application where I need to declare an array of function pointers on a fixed memory address and then use it in different .c files. What I came up with is this:

typedef void(__irq __arm  * p_intr_handler_t)(void);

p_intr_handler_t * IntTable =  (p_intr_handler_t *)&VIM_RAM_BASE;
p_intr_handler_t IntTable[95];

VIM_RAM_BASE is the address. I delcare this in main.f file and I need to use it in various .c files, so I declared it like this:

extern p_intr_handler_t IntTable[95];

But whilst trying to compile I get an error message: "declaration is incompatible with "p_intr_handler_t *IntTable" (declared at line 3)" that message goes for both the normal and the extern declaration.

Any ideas what's wrong?

Thanks

0

3 Answers 3

1

Depending on what you're trying to do, it may make more sense to do this with the linker rather than the compiler. In that case you just declare the symbol as extern in the C file (with no definition at all), and tell the linker where it is. So your header would contain:

extern p_intr_handler_t IntTable[95];

and then you'd add a link-time option (GNU gcc/ld syntax here -- other linkers are different)

-Wl,--defsym=_IntTable=0x8000000

where you set the address to whatever you like. Check out the documentation for your linker to see what the equivalent option is.

Sign up to request clarification or add additional context in comments.

Comments

0

Why are you redeclaring IntTable with a different type?

Just jeep the first definition in a single .c, and create an extern for it in a .h to be included in the other .c, like this:

extern p_intr_handler_t * IntTable;

Obviously this works only if VIM_RAM_BASE is already somehow reserved for your data (i.e. the compiler won't try to put there other data), otherwise you should check out your compiler's documentation to see if there's a way to tell it to put a variable at a specific place in memory.

6 Comments

You are right, I actually declared it twice. Somehow I felt like I needed to imply that the size is 96...Anyway, I did what you said and now I get this message: p_intr_hadler_t * IntTable = (p_intr_hadler_t *)&VIM_RAM_BASE; that this expression must have a constant value and the extern p_intr_hadler_t * IntTable; is undefined...even though I linked the .h right.
How is VIM_RAM_BASE defined? Probably you don't need that &. Also, you must not "link" the .h, but include it in the relevant .c.
It it defined like this : __IO_REG32( VIM_RAM_BASE, 0xFFF82000,__READ_WRITE ); and the IO_REG32 like this #define __IO_REG32(NAME, ADDRESS, ATTRIBUTE) \ volatile __no_init ATTRIBUTE unsigned long NAME @ ADDRESS. By linking I meant including. The extern expression is in a .h file which is included in a relevant .c file, but the error is already in the .h, where the extern is.
The "name @ address" syntax is a nonstandard (but somewhat common) trick to do, in the compiler, what @Chris Dodd suggests doing in the linker. The linker method is of course also not in the C standards, but at least leaves your C code looking nice. :-)
Since I wasn't able to find @Chris Dodd's suggestion in my linker's (XLINK) documentation. I would like to stick to my way, but I'm still getting errors that p_intr_hadler_t * IntTable = (p_intr_hadler_t *)&VIM_RAM_BASE; must have a const value and extern p_intr_hadler_t * IntTable; is undefined. Any idea why?
|
0

You've defined IntTable twice, shouldn't you rename that to something else?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.