I've been playing with Game Boy Advance coding in C. For interrupts to work, the address of your interrupt handler routine must be manually copied to RAM location 0x03007FFC. I know how to do this in ARM Assembly but not in C. I was trying something like this:
#define REG_INTERRUPT *(vu32*)0x03007FFC
void irqhandler()
{
while(1){}
}
int main()
{
REG_INTERRUPT = &irqhandler();
while(1){}
return 0;
}
But it doesn't work. From what I understand about C functions, it seems like C is thinking I'm trying to get the address of the return value of irqhandler
(which there is none since it's a void) and that's where the error comes from. How do I tell C that I want the memory location of the function itself?
CodePudding user response:
irqhandler()
is wrong, you are calling the function instead of taking its address. You should writeirqhandler
or the 100% equivalent&irqhandler
.- Don't use strange home-brewed types like
vu32
, nobody knows what that means. Use standardized types from stdint.h. - You can't assign a function pointer to an integer, they are not compatible types. You need an explicit cast to integer.
Corrected code:
#include <stdint.h>
#define REG_INTERRUPT (*(volatile uint32_t*)0x03007FFCu)
...
REG_INTERRUPT = (uint32_t)irqhandler;
This of course assuming that the underlying hardware supports this and that something valid exists at address 0x3007FFC
that expects a 32 bit integer access.
For details check out How to access a hardware register from firmware?