Dear All,
I have the following function relocated to RAM and running from RAM:
u32 ReadOTPData(u8 FMI_OTPAddress) { u32 OTP_Data = 0x0; *(vu16 *)(FMI_BANK_1) = 0x98; // issue "read OTP" command OTP_Data = (*(vu32*)(FMI_BANK_1 + FMI_OTPAddress)); // read OTP data *(vu16 *)(FMI_BANK_1) = 0xFF; // issue "read FLASH" command return OTP_Data; }
This function is called from the following code, which runs from FLASH bank 1:
void GetMACfromOTP(void) { u32 x[2]; u8 *p = (u8 *)x; tsk_lock(); x[0] = ReadOTPData(OTP_MAC0_LOCATION); x[1] = ReadOTPData(OTP_MAC1_LOCATION); tsk_unlock(); memcpy(own_hw_adr, p, 6); return; }
When I run my program it fails somewhere close to the end of the ReadOTPData() function (the first time it is called) and lands at the PAbtHandler stub. If I change the declaration of OTP_Data to be static (or global), then the program runs as I expect.
One really weird effect, that worries me a lot, is that if I put a breakpoint on the closing brace of ReadOTPData(), then the program runs correctly in all cases, even when OTP_Data is on the stack.
So I am not sure whether this is a silicon issue, a compiler problem, or something else altogether. Anyone seen anything like this before? In case it is relevant, I am using the Realview C++ compiler, and I am runnning this code in an RTL task.
Regards,
Christopher Hicks ==
You should analyse the reason for the ABORT call.
See: http://www.keil.com/support/docs/3080.htm
Thanks Reinhard, that is useful information. I have done some other stuff with my code yesterday, and today when I put OTP_data back on the stack the programs gets to the "Undef" exception handler. I think, possibly, what is happening is this:
Something I do to the OTP prevents subsequent instruction fetch operations from FLASH bank 1 from executing properly. Thus, at the return from my RAM-located function I end up trying to execute nonsensical instructions, resulting in a range of curious exception behaviours.
However, the action of stopping at a breakpoint after the OTP access, but still with the PC pointing to RAM, causes the FLASH to return to a state where instructions can be read from it successfully.
So, I tried just inserting a small delay after issuing the "Read Array" command to FLASH bank 1, before returning from the function, and the program seems to work. This looks like a silicon problem - there seem to be lots of them in the FLASH subsystem on STR9 Rev D :-(
By the way, I noticed that if OPT_Data is a local variable it is not allocated on the stack, but instead is just allocated register R0. If it is static it is obviously allocated RAM. I think the extra instructions needed in the latter case are just enough for the FLASH to change state properly.
Thanks for your help,