This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

static initialization of extern pointer to function

Hi All,

Could anybody help me out with the following problem? I have a module with the following declarations.

int (*on_CAN_msg)(void);
	...
void CAN_int_handler(void) interrupt 7 using 1 {
	...

	if (on_CAN_msg)
		on_CAN_msg();
	...
}

Now I have another module:
int CAN_msg_handler(void){
	...
}

extern int (*on_CAN_msg)(void) = CAN_msg_handler;

I also have the following linker's OVERLAY directive to make sure the compiler knows the correct call sequence:
CAN_int_handler ! (CAN_msg_handler),
main ! (on_CAN_msg)

CAN_msg_handler() doesn't get called. However, when I replace extern int (*on_CAN_msg)(void) = CAN_msg_handler;
with
int main(){
	...
	on_CAN_msg = CAN_msg_handler;
	...
}
everything seems fine. How can I make this code work without having to assign the handler on the fly?

Thanks in advance,
Sandy

Parents
  • Does the rest of your initialized file scope data work correctly? That is, you
    have included INIT.A51 in your program to copy the initialized data section from
    ROM (code space) to RAM?
    Is there a way to determine which library/startup files are linked to your project by default? I am using IDE version 2.31, which I guess is a bit outdated, and I can only see my source files in the project window. The Options for Target window isn't very helpful either.

    Thanks

Reply
  • Does the rest of your initialized file scope data work correctly? That is, you
    have included INIT.A51 in your program to copy the initialized data section from
    ROM (code space) to RAM?
    Is there a way to determine which library/startup files are linked to your project by default? I am using IDE version 2.31, which I guess is a bit outdated, and I can only see my source files in the project window. The Options for Target window isn't very helpful either.

    Thanks

Children
  • I have just discovered an interesting feature. If the modules look like this

    //can.c
    
    int (*on_CAN_msg)(void) = 0;
    	...
    void CAN_int_handler(void) interrupt 7 using 1 {
    	...
    
    	if (on_CAN_msg)
    		on_CAN_msg();
    	...
    }
    
    
    //main.c
    
    int CAN_msg_handler(void){
    	...
    }
    
    extern int (*on_CAN_msg)(void) = CAN_msg_handler;
    the compiler/linker does not generate an error, or even a warning! Why not?

    By the way, the program seems to work OK if I declare the pointer to function in the other module, i.e. like this:
    //can.c
    
    extern int (*on_CAN_msg)(void);
    	...
    void CAN_int_handler(void) interrupt 7 using 1 {
    	...
    
    	if (on_CAN_msg)
    		on_CAN_msg();
    	...
    }
    
    
    //main.c
    
    int CAN_msg_handler(void){
    	...
    }
    
    int (*on_CAN_msg)(void) = CAN_msg_handler;
    Why does the linker work this way?

  • Don't worry too much about why your essentially incorrect method miraculously works --- just use the correct one, i.e. the one in which the variable is defined and initialization in the module that has the initializer available to it, rather than the one that wants to call through hat pointer.

    And while you're at it, you should consider getting rid of all 'extern' declarations in .c files. #include header files instead --- that's what they're there for. I.e. there should be a "main.h" contain that extern declaration, and both can.c and main.c should #include that.

  • If you're going to use function pointers, you should read the following application note:

    http://www.keil.com/appnotes/docs/apnt_129.asp

    Jon