Compiler error when clicking on function pointer
I am writing a bootloader for PIC32MX using HiTech PICC32 compiler (similar to C90). At some point I need to go to the real main procedure, so somewhere in the bootloader I have
void (*user_main) (void);
user_main = (void (*) (void)) 0x9D003000;
user_main();
(Note that in the actual code, the function signature is typedef'd and the address is a macro.)
I would rather calculate this (virtual) address from a physical address and have something like:
void (*user_main) (void);
user_main = (void (*) (void)) (0x1D003000 | 0x80000000);
user_main();
... but when I try I get a compiler error:
Error #474: ; 0: no psect specified for function variable/argument allocation
Have I worked some kind of vaginality C syntax?
This error is not referencing any specific line, but if I comment out the call user_main()
it goes away. (It might be a compiler removing the redundant branch of code, but the HiTech PICC32 isn't particularly smart in Lite mode, so it might not.)
Update . I also notice that if I use
void (*user_main) (void);
unsigned int x = 0x9D003000;
user_main = (void (*) (void)) x;
user_main();
I am getting the same error.
a source to share
This is not a common C problem - this is the HI-TECH specification.
I have never used HI-TECH products, but the problem is that the linker does not know where in memory it should place arguments or local variables in the procedure user_main
. From the PICC Guide :
(474) no psect set for function variable / argument allocation (Linker)
The FNCONF assembler directive, which points to linker information regarding the auto / parameter block, has never been seen. It is supplied in standard run-time files if needed. This error could mean that the correct launcher was not associated at runtime. Make sure you use the FNCONF directive if the runtime launcher is written by hand.
a source to share
I realize this is not an answer to the original question, but the syntax of calling a function using a function pointer can be made clearer (correct) with the following construct:
(*user_main)();
If you do this, you will immediately see that user_main is a pointer, which is dereferenced and the function call is made. This avoids confusion with the user_main function pointer with the user_main () function.
a source to share
An ugly way to do this might be to put your pointer type and unsigned long into a union. You know what you have to do. The C standard makes this behavior undefined, but you're already in undefined territory, and by the grace of your compiler, as soon as you need to convert an integer to a pointer.
a source to share