<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>