2011-06-16 05:48 AM
hi.
i am using the STM32f103 chip and i am having all sord of problem that takes me to the Hard Fault inturpt . when i check the SCB->CFSR register i am getting all sord of errors like : ''the processor has attempted to access a coprocessor.'' or ''The processor has attempted to execute an undefined instruction.'' i read alot and i found that i can change the privilege mode for safty reason so that the software cannot accsess importent register in the cpu i am hoping that it will help me solve the problems. my question is how do i change that from what i can find i need to change the control register but how can i chnage that what is he called? i found all that data here by the way: http://www.st.com/stonline/products/literature/pm/15491.pdf thanks.2011-06-17 05:04 AM
Sounds like you'll just have to handle more faults if you lock it in user mode.
You really need to address the faults you're already seeing properly first. If it's complaining about undefined instructions, you need to see what it's executing and why. If you have access to TRACE, use that to figure out what's gone wrong. If you don't get some more telemetry/instrumentation into your code and fault handlers, look at stack dumps and call trees, to figure out why the process is getting into this mess. With stack issues, fill the stack with a visible pattern, view it in a memory window under the debugger, add a guard zone under the stack, and add code to monitor it periodically, or at key check points.2011-06-18 10:58 PM
2011-06-19 05:30 PM
I think you're just going to have to get more sophisticated about buffering the serial port, implementing diagnostics and fault handlers, and the ARM/Cortex-M3 architecture in general. Not sure I can teach you how to do that. I'd recommend Joseph Yiu's book on the Cortex-M3 as a good starting point.
For the Hard Fault Handler, you should look at this thread, about half way down. https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fHardFault%20Exception%20Why%20oh%20why!&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F...https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/HardFault Exception Why oh why!&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=3274
For stack related data, look at how your compiler (IAR), deal with stacks, and stack sizes. Look at the .MAP file, you have a 512 byte stack, located at 0x20000000,0x20000200, if you overflow this stack (ie below 0x20000000) it's going to HARD FAULT, and have a significantly hard time generating any data to do diagnostics with. I would suggest making it substantially larger (>2KB?). Fill 0x20000000..0x20000040 (64 bytes) with some clearly identifiable pattern (0xDEADBEEF,0xCAFECAFE), and check it periodically. If the pattern in this GUARD ZONE is corrupted/changed, then you will know that the stack has descended TOO FAR.2011-06-19 07:31 PM
Your debug output routines are quite a mess. Let's use some subroutines, and some less complex logic to clear them up a tad.
void debug_char(char x) { while(((USART3->SR)&USART_SR_TXE)==0);//if transmit buffer is empty USART3->DR = x; } void debug_string(char *s) { while(*s) debug_char(*s++); } void debug_int(int x) { char str[12]; char *s; if (x < 0) // Negative { debug_char('-'); x = -x; } s = str + sizeof(str); *(--s) = 0; do { *(--s) = '0' + (char)(x % 10); x = x / 10; }while(x); debug_string(s); debug_char('\n'); } void debug_mark_stack(void) { unsigned long *p = (unsigned long *)0x20000000; // assuming stack 0x20000000 to 0x20000xxx int i; for(i=0; i<16; i++) // bottom 64-bytes, give yourself more margin, as required. p[i] = 0xDEADBEEF; } int debug_check_stack(void) { unsigned long *p = (unsigned long *)0x20000000; if (p[15] != 0xDEADBEEF) { debug_string(''Stack bottoming out, failure imminent\n''); return(1); } return(0); }2011-06-20 09:20 AM
2011-06-20 09:49 AM
i defined 0x400 stack size but when i run the simulation on IAR i can see when the code puts the first 0xDEADBEEF in address 0x20000000 i get stack overflow.
when i look at the CSTACK windows i can see this attached image.
May be they are doing their own stack checking, I'm not using IAR, and I'm not seeing anything helpful in the screen shot. It's not showing the overflow error, or the bottom of the stack frame, or the failure point in the code. Suggest you look at the bottom of the stack, and how IAR are marking it. Try just marking the p[15] location, that might permit you to get an early warning without firing IAR's overflow check. By the time your stack overflows it will be too late to do anything. Normally if it were above the heap it would descend in to that, corrupting it as it goes. Where you have it placed, if it overflows it will exit the RAM and begin to HARD FAULT. Attempts to push processor state will also fail because the stack is unwritable. This is a good case for a system vs user stack, but that's probably a bit over complicated to explain/implement for you now.
2011-06-20 10:47 PM
thanks for your response.
from what i could figure out the IAR simulator does have stack monitor and becuse the stack filles up from the butttom up it says full stack if put avalue in the first address. any way i used the code and test it there was no stack overflow. could it be becuse of DMA error i use it in the ADC and if so how can i check it? and how can i check what was the last command the CPU tried to do and in what address? thanks. by the way is there any good book you know for embeded programing?2011-06-21 12:35 PM
It's hard to guess exactly where your problems lie, the key will be to identify the points in the code where the failures occur, and decide if they are caused by bad coding, random corruption, or whatever.
Try improving the hard fault handling to provide specific information, you will have to change the output code if you aren't able to use printf. After the example by Joseph Yiu, should work for IAR, might need tweaking, I don't use IAR In startup_stm32fxxx_xx.s Replace PUBWEAK HardFault_Handler SECTION .text:CODE:REORDER(1) HardFault_Handler B HardFault_Handler with EXTERN HardFault_Handler_C PUBWEAK HardFault_Handler SECTION .text:CODE:REORDER(1) HardFault_Handler TST LR, #4 ITE EQ MRSEQ R0, MSP MRSNE R0, PSP B HardFault_Handler_C In you main.c or stm32f10x_it.c, or whatever void HardFault_Handler_C(unsigned int * hardfault_args) { unsigned int stacked_r0; unsigned int stacked_r1; unsigned int stacked_r2; unsigned int stacked_r3; unsigned int stacked_r12; unsigned int stacked_lr; unsigned int stacked_pc; unsigned int stacked_psr; stacked_r0 = ((unsigned long) hardfault_args[0]); stacked_r1 = ((unsigned long) hardfault_args[1]); stacked_r2 = ((unsigned long) hardfault_args[2]); stacked_r3 = ((unsigned long) hardfault_args[3]); stacked_r12 = ((unsigned long) hardfault_args[4]); stacked_lr = ((unsigned long) hardfault_args[5]); stacked_pc = ((unsigned long) hardfault_args[6]); stacked_psr = ((unsigned long) hardfault_args[7]); printf (''[Hard fault handler]\n''); printf (''R0 = %x\n'', stacked_r0); printf (''R1 = %x\n'', stacked_r1); printf (''R2 = %x\n'', stacked_r2); printf (''R3 = %x\n'', stacked_r3); printf (''R12 = %x\n'', stacked_r12); printf (''LR = %x\n'', stacked_lr); printf (''PC = %x\n'', stacked_pc); printf (''PSR = %x\n'', stacked_psr); printf (''BFAR = %x\n'', (*((volatile unsigned long *)(0xE000ED38)))); printf (''CFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED28)))); printf (''HFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED2C)))); printf (''DFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED30)))); printf (''AFSR = %x\n'', (*((volatile unsigned long *)(0xE000ED3C)))); exit(0); // terminate or die return; } As for books, for the Cortex-M3, Joseph Yiu's book is a good start. I got to embedded through years of assembler coding and familiarity with micro processors/controllers. On firmware books by Jack Crenshaw, Jack Ganssle and Jean Labrosse, are generally pretty good http://www.alibris.com/booksearch?author=Jack%20Crenshaw&aid=1101896 http://www.alibris.com/booksearch?author=Jack%20G%20Ganssle&aid=1754621 http://www.alibris.com/booksearch?author=Jean%20J%20Labrosse&aid=2822925 I'd probably avoid William Hohl's book on ARM Assembly, nice book, but ARM7 and ARM9 coverage is a couple of decades too late. Try looking at Embedded systems and programming topics on Amazon, and read a few chapters, see what covers the material/areas you want.2011-06-22 01:17 AM