2012-08-22 07:51 PM
Hello,
STM32L152, Rowley CrossStudio 2.3, STM32L152DEMO pcb, Using CrossConnect debugger within CrossStudio.I have seen this problem before, did not record/understand last time fixed.What will cause a hard fault on first SRAM access in program (after startup_.s). I have a bunch of static structure global declarations before main, once in main execution hard faults at first SRAM access (usually is a push (R7, lr) ) and those values look reasonable.Getting VCATCH, IMPRECISERR set, and drops to HardFault (CMSIS version). If I manually set CSB_SHCRS->BUSFAULTENA and rerun it will drop into bus fault handler.The modified handler returns this:[Hard fault handler - all numbers in hex]R0 = 20001940R1 = 0R2 = 0R3 = 0R12 = 1fffe944LR [R14] = 20001950 subroutine call return addressPC [R15] = 8000379 program counterPSR = 80006a0BFAR = e000ed38CFSR = 400HFSR = 40000000DFSR = 8AFSR = 0SCB_SHCSR = 0Tried making this the first thing inuint32t *ACTLR = (uint32_t *)0xE000E008;
// *ACTLR |= 2; never executed this
[Hard fault handler - all numbers in hex]R0 = 20001940R1 = 0R2 = 0R3 = 0R12 = e008LR [R14] = 20001950 subroutine call return addressPC [R15] = 8000177 program counterPSR = 8000378BFAR = e000ed38CFSR = 400HFSR = 40000000DFSR = 8AFSR = 0SCB_SHCSR = 0help or thoughtful guidance appreciated. #stm32-hardfault-impreciserr2012-08-23 05:01 AM
Presumably there is code in startup.s prior to main(), which gets executed and copys/clears out the statics?
Check the value of SP The value for LR seems invalid, coming from RAM and EVEN.2012-08-23 10:00 AM
Hi Clive,
Checked that static variablesa are intialized at debug entry to main. (what code initializes them is a mystery)Code in debugger looks like this:--- main.c -- 95 -------------------------------------------static uint8_t bc5RxByte = (uint8_t) 0x5A;static uint8_t lbtRxByte = (uint8_t) 0x5B;int main(void){ B580 push {r7, lr} B082 sub sp, sp, #8 AF00 add r7, sp, #0--- main.c -- 100 ------------------------------------------{ F5AD533E sub.w r3, sp, #0x2F80 F1A3037C sub.w r3, r3, #0x7C F04F0200 mov.w r2, #0 601A str r2, [r3]--- main.c -- 100 ------------------------------------------bc5RxByte = 0x01; F240030C movw r3, #12 F2C20300 movt r3, #0x2000 F04F0201 mov.w r2, #1 701A strb r2, [r3]--- main.c -- 101 ------------------------------------------lbtRxByte = 0x01; F240030D movw r3, #13 F2C20300 movt r3, #0x2000 F04F0201 mov.w r2, #1 701A strb r2, [r3]--values of trace are as follows.static uint8_t bc5RxByte = 0; //memloc = 0x20000149static uint8_t lbtRxByte = 0; //memloc = 0x2000014Aint main(void) {push {r7, lr}, push {0x00000000, 0x08000177} ... r7=0x00000000, lr=0x08000177sub sp, sp, #8, sub 0x20001368, 0x20001950, #8 ... sp=0x20001360add r7, sp, #0, 0x00000000, 0x20001360, #0 ... r7=0x20001360, sp=0x20001360{sub.w r3, sp, #0x2F80, 0x00000009, 0x20001360, #0x2F80 ... r3=0x1fffe3e0sub.w r3, r3, #0x7C, 0x1fffe3e0, 0x1fffe3e0, #0x7C ... r3=0x1fffe364mov.w r2, #0, 0x08000361, #0 ... r2=0x00000000str r2, [r3], 0x00000000, 0x1fffe364 ... r2=0x00000000 r3=0x1fffe364** at this point the SCB_HFSR->FORCED, SCB_BFSR->IMPRECISERR, SCB_ICSR->ISPREEMPT, VECTPENDING=0x003 are set and of course I am then in the hard fault loop.Looking in the project settings for preprocessor options of STM32_startup.s , I findSTM32L15x_HDSTARTUP_FROM_RESET__NO_SYSTEM_INITINITIALIZE_STACKI removed STARTUP_FROM_RESET & __NO_SYSTEM_INIT; but see not change in the behavior.What is generating the code (before the bc5RxByte = 0x01;) that tries to write to memory is a mystery to me.Enlightenment requested!2012-08-23 10:07 AM
Guess you need to figure out why it's allocation 12 KB of auto/local variables.
R3 points into ROM, below RAM, need to make the stack bigger.2012-08-23 10:48 AM
Changing the stack from 4k to 8k no change.
Memory Usage shows 6.6K free of 16K in idiot window.So you are saying that R3 is determined somewhere in the compiler as a result of the auto/allocation of static variables?I thought I could escape learning the startup.s and other particulars but it looks like I was wrong to think one could simply have the Crossworks figure out the bottom end stuff. Suggestions where to read? This is not covered that I see in Yiu's Definitive Guide to the M3 2nd edition.2012-08-23 11:37 AM
I don't know what your source looks like, the compiler is generating epilogue code in anticipation of using data/pointers which are 12K below the current stack pointer. From the code presented so far I don't know why.
Does this work?static uint8_t bc5RxByte = (uint8_t) 0x5A;
static uint8_t lbtRxByte = (uint8_t) 0x5B;
int main(void)
{
bc5RxByte = 0x01;
lbtRxByte = 0x01;
while(1);
}
You probably need to look at a microprocessor book that describes the concepts of stack frames, local variables and parameter passing. The concepts are the similar across x86, MIPS and ARM, with the RISC parts using registers to pass the first few parameters. I could probably cite a MIPS text that I though covered this well. Other than that, perhaps search on ABI (Application Binary Interface) methods. And compiler's use of epilogue/prologue code, interfacing between assembler and higher level languages.
2012-08-23 11:43 AM
Introduction to RISC Assembly Language Programming, John Waldron
http://www.amazon.com/Introduction-RISC-Assembly-Language-Programming/dp/0201398281/
2012-08-23 11:49 AM
Changing the stack from 4k to 8k no change.
No doubt, it needs to be at least 12KB to make any difference. F5AD533E sub.w r3, sp, #0x2F80 F1A3037C sub.w r3, r3, #0x7C 0x2F80 + 0x7C = 0x2FFC = 12284 = 11.996 KB2012-08-23 12:02 PM
If I comment out the remainder of the program, the offending code is not there. So then there is no hardfault.
''generating epilogue'' , so I suppose that I should see a pointer or address in the memory map file that is in code space then? Or is there some other method of tracking this anticipatory action of the compiler...or is it the linker?As to the book, I will likely get it <thank you for the pointer> but by God do I really need to understand that domain?From: clive1Posted: Thursday, August 23, 2012 8:44 PMSubject: Hard Fault on first SRAM accessIntroduction to RISC Assembly Language Programming, John Waldronhttp://www.amazon.com/Introduction-RISC-Assembly-Language-Programming/dp/0201398281/2012-08-23 12:08 PM
Ok, stack to 12384 <I would have never thought of going so large> and no hard fault. Now to figure where this enormous allocation is taking place.
But back to that little bit of code, where does it hark from?int main(void){ B580 push {r7, lr} B082 sub sp, sp, #8 AF00 add r7, sp, #0--- main.c -- 100 ------------------------------------------{ F5AD533E sub.w r3, sp, #0x2F80 F1A3037C sub.w r3, r3, #0x7C F04F0200 mov.w r2, #0 601A str r2, [r3]