I am not expert on Cortex-M3. I recently test the memory handle using mbed LPC1768. It is strange that the debugger cannot jump into the hardfault_handler function. But the exceptional code execuated when it run in non-debug mode.
The code was exported from mbed online compiler and then opened by Keil uvision 5. I rewrite the HardFault_Handler function to capture an exception. The debugger is set as CMSIS-DAP. When I compile the code and load to the chip. It will flash LEDs after few seconds which means it jumps to the Hardfault_handler as expected. However, when I run in debug mode, the code paused at following line. The LED is not flashing as expected.
0x0000263E BEAB BKPT 0xAB
and I check the peripherals->core peripherals->fault report, the HARD_FAULT_STAT is 0x0 which means it didn't catch the interrupt. The BKPT bit as DBG_FAULT_STAT is 1. However, I didn't set any break point.
In the registers view, the ISR is 0 as well which means there is no interrupt caught!
Anyone can help on this problem? If a debugger cannot catch Hard_Fault_stat. It will be very difficult.
Here is the code.
#include "mbed.h" Serial pc(USBTX, USBRX); BusOut leds(LED1, LED2, LED3, LED4); extern "C" void HardFault_Handler() { pc.printf("Hard fault!\r\n"); while(1) { leds = 0x09; wait(0.1); leds = 0x06; wait(0.1); } } void fail() { pc.printf("Caught the failure\r\n"); while(1) { leds = 0x09; wait(0.4); leds = 0x06; wait(0.4); } } class Test { public: int something; char woot[28]; }; int main() { Test *dummy; int index = 0; while(1) { dummy = new Test; if (dummy == NULL) fail(); pc.printf("%u\r\n", index); ++index; } }
Are you sure the BKPT isn't a result of it attempting to host the printf()?
I have double checked and there is no breakpoint. I rerun the code using the simulator only. It doesn't jump to hardfault_handler either.
Here is the disassembly code around the final stop point (0x000026A4)
__rt_SIGRTMEM_inner: 0x00002684 B118 CBZ r0,0x0000268E 0x00002686 F1000208 ADD r2,r0,#0x08 0x0000268C D001 BEQ 0x00002692 0x0000268E 2000 MOVS r0,#0x00 0x00002690 4770 BX lr 0x00002692 2100 MOVS r1,#0x00 0x00002694 7001 STRB r1,[r0,#0x00] 0x00002696 4770 BX lr _ttywrch: 0x00002698 B508 PUSH {r3,lr} 0x0000269A 4669 MOV r1,sp 0x0000269C F88D0000 STRB r0,[sp,#0x00] 0x000026A0 2003 MOVS r0,#0x03 0x000026A2 BEAB BKPT 0xAB 0x000026A4 BD08 POP {r3,pc} __I$use$semihosting: 0x000026A6 4770 BX lr
Another strange thing is the that simulator looks like has larger memory for alloc(). Should I set the memory size for the chip somewhere?
I have double checked and there is no breakpoint.
Aha. That makes me wonder why this:
0x000026A2 BEAB BKPT 0xAB
looks so deceptively much like a breakpoint.
Ok, so it is trying to provide console IO, where do you think this goes?
The heap size is often specified in the startup_arch.s file.
The retargeting of the console IO is often does with a combination of serial.c and retarget.c
www.keil.com/.../armccref_Bgbjhiea.htm www.keil.com/.../armccref_bgbjjgij.htm
see also this article:
http://www.keil.com/support/docs/3614.htm
it will show you how to remove semihosting.