<html><body>Na ladění HardFault mám pomůcku, nejčastěji se hardfault volá kvůli bad ARM state (přístup na<br> nezarovnanou pozici. U USB je spousta registrů s pouze 16bitovým přístupem, kde 8/32bitový <br>přístup generuje tento HardFault. Kdysi jsem ještě míval s pomocí externích knihoven stack <br>overflowy ale ten už se to nestává, knihovny si píšu sám):<br><br>void HardFault_HandlerC(unsigned long *hardfault_args);<br><br> void hard_fault_handler(void)<br> {<br> // ".syntax unified\n"<br> __asm(<br> "MOVS R0, #4 \n"<br> "MOV R1, LR \n"<br> "TST R0, R1 \n"<br> "BEQ _MSP \n"<br> "MRS R0, PSP \n"<br> "B HardFault_HandlerC \n"<br> "_MSP: \n"<br> "MRS R0, MSP \n"<br> "B HardFault_HandlerC \n"<br> );<br> // ".syntax divided\n"<br><br> }<br><br> void HardFault_HandlerC(unsigned long *hardfault_args)<br> {<br> if (((uint32_t)hardfault_args & 0xF0000000) != 0x20000000)<br> {<br> printf("HardFault - Invalid xSP \r\n");<br> __asm("BKPT #0\n");<br><br> // * Check if you have allocated enough stack space.<br> // * Add a few function calls in various places in your program to check for stack leaks. CMSIS-Core provides some functions to help accessing SP value<br> // (e.g. __get_MSP()), and you can use those functions to add stack checking code (e.g. the value of MSP should be the same everything when a function is called).<br><br> // RTOS?<br> // No - You can use the banked stack pointer feature to separate the stack used by threads and handlers. In this way you can also add stack checking in<br> // the ISR with lowest priority level. Higher priority level ISRs cannot use this trick because the SP value can be different if there was a lower<br> // priority ISR running.<br> // Yes - some of them (including Keil RTX) has optional stack checking feature.<br><br> }<br><br> volatile unsigned long stacked_r0 = ((unsigned long)hardfault_args[0]);<br> volatile unsigned long stacked_r1 = ((unsigned long)hardfault_args[1]);<br> volatile unsigned long stacked_r2 = ((unsigned long)hardfault_args[2]);<br> volatile unsigned long stacked_r3 = ((unsigned long)hardfault_args[3]);<br> volatile unsigned long stacked_r12 = ((unsigned long)hardfault_args[4]);<br> volatile unsigned long stacked_lr = ((unsigned long)hardfault_args[5]);<br> volatile unsigned long stacked_pc = ((unsigned long)hardfault_args[6]);<br> volatile unsigned long stacked_psr = ((unsigned long)hardfault_args[7]);<br> volatile unsigned long _CFSR = (*((volatile unsigned long *)(0xE000ED28)));<br> volatile unsigned long _HFSR = (*((volatile unsigned long *)(0xE000ED2C)));<br> volatile unsigned long _DFSR = (*((volatile unsigned long *)(0xE000ED30)));<br> volatile unsigned long _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;<br> volatile unsigned long _BFAR = (*((volatile unsigned long *)(0xE000ED34)));<br> volatile unsigned long _MMAR = (*((volatile unsigned long *)(0xE000ED38)));<br><br> volatile unsigned long T = stacked_psr & (1 << 24) ? 1 : 0;<br> volatile unsigned long IPSR = stacked_psr & 0x3F;<br><br> printf("HardFault\r\n");<br> printf("xSP: %.8x (valid)\r\n", (uint32_t)hardfault_args );<br> printf("PSR: %.8x IPSR=%.2x T=%.1x\r\n", stacked_psr, IPSR, T);<br> printf(" PC: %.8x\r\n", stacked_pc);<br> printf(" LR: %.8x\r\n", stacked_lr);<br><br> if (!T) {<br> printf(" ARM state not allowed!\r\n", stacked_lr);<br><br> // * T=0 something is trying to switch the processor into Arm state.<br><br> // * T=0 and the stacked PC is pointing to the beginning of an ISR, check the vector table (all LSB of exception vectors should be set to 1).<br> }<br><br> if (IPSR) {<br> printf(" ISR %d \r\n",IPSR);<br><br> // * IPSR is indicating an ISR is running, and the stacked PC is not inside the address range of the ISR code, then you likely to have a stack corruption<br> // in that ISR. Look out for data array accesses with unbounded index.<br> }<br><br> // * If the stacked PC is pointing to a memory access instruction, usually you can debug the load/store issue based on the register contents (see below):<br><br> // * Invalid address - check the address value<br> // * Data alignment issue (the processor has attempted to carried an unaligned data accesses)<br> // * For Cortex-M0+ processor, please check for memory access permission (e.g. unprivileged access to the NVIC register), or MPU permission violations.<br> // * Bus components or peripheral returned an error response for other reason.<br><br><br> __asm("BKPT #0\n") ; // Break into the debugger<br>}<br><aside>
---------- Původní e-mail ----------<br>
Od: ToMaS <tomas.hum@worldonline.cz><br>
Komu: HW-news <hw-list@list.hw.cz><br>
Datum: 10. 12. 2019 16:59:52<br>
Předmět: stm32 cdc
</aside><br><blockquote data-email="tomas.hum@worldonline.cz">Resim problem s STM32 VCP, at delam co delam tak to nic nedela.<br><br>Postupuji podle tohoto:<br>http://shawnhymel.com/1795/getting-started-with-stm32-nucleo-usb-virtual-com-port/<br><br>Ale behem MX_USB_DEVICE_Init(); mi to skoci do void <br>HardFault_Handler(void) a koncim.<br><br>Jsem zacatecnik, je nejaka rada proc se tak deje? Respektive jak zjistit <br>proc se tak deje.<br><br>Diky za nasmerovani<br><br>ToMaS<br><br>P.S. Mam STM32L412, ale to asi neni problem.<br>_______________________________________________<br>HW-list mailing list - sponsored by www.HW.cz<br>Hw-list@list.hw.cz<br>http://list.hw.cz/mailman/listinfo/hw-list<br></blockquote></body></html>