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 ==
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,
You should analyse the reason for the ABORT call.
See: http://www.keil.com/support/docs/3080.htm
View all questions in Keil forum