Question : Function pointer corrupted/offset when passed to function

So I am having more fun with my AT91SAM9261.  I am trying to initialize a system interrupt to set up a handler to a perioidic interrupt timer. I'm pretty much copying the example code to do this.   I am getting bizarre different results when I run my code, from the sample code.

On the good sequence in the sample project that came with IAR EWARM, it calls:

IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);
where AT91C_ID_SYS=1 (system interrupt), and ISR_Pit is a function with prototype

void ISR_Pit(void)

and at memory location 0x200011B8.  

And I trace the function call through the following:

void IRQ_ConfigureIT(unsigned int source,
                     unsigned int mode,
                     void( *handler )( void ))
{
    // Disable the interrupt first
    AT91C_BASE_AIC->AIC_IDCR = 1 << source;

    // Configure mode and handler
    AT91C_BASE_AIC->AIC_SMR[source] = mode;
    AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;

    // Clear interrupt
    AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}


and on the line

AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;

I see the register AIC_SVR_1 change to 0x200011B8, which is all well and good.

***

On to the bad sequence.  When I make the same call from my program (I have cut and paste the same initialization and ISR routines):

IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, ISR_Pit);

I verify that AT91C_ID_SYS is value 1, and ISR_Pit is a function of prototype

void ISR_Pit(void) at address 0x200000A4

And then I trace it into the call

void IRQ_ConfigureIT2(unsigned int source,
                     unsigned int mode,
                     void( *handler )( void ))
{
    // Disable the interrupt first
    AT91C_BASE_AIC->AIC_IDCR = 1 << source;

    // Configure mode and handler
    AT91C_BASE_AIC->AIC_SMR[source] = mode;
    AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;

    // Clear interrupt
    AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}

And I inspect the value of "handler" and it is address 0x200000A5 (!!!), one byte more than the passed pointer.  And I see the register change to the incorrect value 0x200000A5, when I want it to point at my ISR_Pit address of 0x20000A4.

***

So my function pointer got nudged by one when I called the function.  So my two questions are:

1) what would you experts do in terms of even troubleshooting this bizarre observation?  What could explain this?  Is my stack getting clobbered?  More memory alignment issues?
2) what can I do to appease the embedded gods, whom I have clearly infuriated?

Thanks very much for any thoughts.

Answer : Function pointer corrupted/offset when passed to function

Always check the map file to see the correct offsets.
Apart of that, does the code works?
Also, how is AT91C_BASE_AIC and AIC_SVR defined? are they defined as volatile?
Can you reproduce the problem by removing all non pertinent code, to exclude you have a bad pointer incrementing your register?
Random Solutions  
 
programming4us programming4us