stm32 cdc

František Burian BuFran na seznam.cz
Úterý Prosinec 10 17:29:31 CET 2019


Na ladění HardFault mám pomůcku, nejčastěji se hardfault volá kvůli bad ARM 
state (přístup na
 nezarovnanou pozici. U USB je spousta registrů s pouze 16bitovým přístupem,
kde 8/32bitový 
přístup generuje tento HardFault. Kdysi jsem ještě míval s pomocí externích 
knihoven stack 
overflowy ale ten už se to nestává, knihovny si píšu sám):

void HardFault_HandlerC(unsigned long *hardfault_args);

  void hard_fault_handler(void)
  {
         // ".syntax unified\n"
    __asm(
                    "MOVS   R0, #4  \n"
                    "MOV    R1, LR  \n"
                    "TST    R0, R1  \n"
                    "BEQ    _MSP    \n"
                    "MRS    R0, PSP \n"
                    "B      HardFault_HandlerC      \n"
            "_MSP:  \n"
                    "MRS    R0, MSP \n"
                    "B      HardFault_HandlerC      \n"
            );
    // ".syntax divided\n"

  }

  void HardFault_HandlerC(unsigned long *hardfault_args)
  {
    if (((uint32_t)hardfault_args & 0xF0000000) != 0x20000000)
    {
      printf("HardFault - Invalid xSP \r\n");
      __asm("BKPT #0\n");

      // * Check if you have allocated enough stack space.
      // * 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
      //   (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).

      // RTOS?
      //   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
      //        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
      //        priority ISR running.
      //   Yes - some of them (including Keil RTX) has optional stack 
checking feature.

    }

    volatile unsigned long stacked_r0 = ((unsigned long)hardfault_args[0]);
    volatile unsigned long stacked_r1 = ((unsigned long)hardfault_args[1]);
    volatile unsigned long stacked_r2 = ((unsigned long)hardfault_args[2]);
    volatile unsigned long stacked_r3 = ((unsigned long)hardfault_args[3]);
    volatile unsigned long stacked_r12 = ((unsigned long)hardfault_args[4]);
    volatile unsigned long stacked_lr = ((unsigned long)hardfault_args[5]);
    volatile unsigned long stacked_pc = ((unsigned long)hardfault_args[6]);
    volatile unsigned long stacked_psr = ((unsigned long)hardfault_args[7]);
    volatile unsigned long _CFSR = (*((volatile unsigned long *)(0xE000ED
28)));
    volatile unsigned long _HFSR = (*((volatile unsigned long *)(0xE000ED2
C)));
    volatile unsigned long _DFSR = (*((volatile unsigned long *)(0xE000ED
30)));
    volatile unsigned long _AFSR = (*((volatile unsigned long *)(0xE000ED3
C))) ;
    volatile unsigned long _BFAR = (*((volatile unsigned long *)(0xE000ED
34)));
    volatile unsigned long _MMAR = (*((volatile unsigned long *)(0xE000ED
38)));

    volatile unsigned long T = stacked_psr & (1 << 24) ? 1 : 0;
    volatile unsigned long IPSR = stacked_psr & 0x3F;

    printf("HardFault\r\n");
    printf("xSP: %.8x (valid)\r\n", (uint32_t)hardfault_args );
    printf("PSR: %.8x IPSR=%.2x T=%.1x\r\n", stacked_psr, IPSR, T);
    printf(" PC: %.8x\r\n", stacked_pc);
    printf(" LR: %.8x\r\n", stacked_lr);

    if (!T) {
      printf(" ARM state not allowed!\r\n", stacked_lr);

      // * T=0 something is trying to switch the processor into Arm state.

      // * 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).
    }

    if (IPSR) {
      printf(" ISR %d \r\n",IPSR);

      // * 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
    //   in that ISR. Look out for data array accesses with unbounded index.
    }

    // * 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):

    // * Invalid address - check the address value
    // * Data alignment issue (the processor has attempted to carried an 
unaligned data accesses)
    // * For Cortex-M0+ processor, please check for memory access permission
(e.g. unprivileged access to the NVIC register), or MPU permission 
violations.
    // * Bus components or peripheral returned an error response for other 
reason.


    __asm("BKPT #0\n") ; // Break into the debugger
}
---------- Původní e-mail ----------
Od: ToMaS <tomas.hum na worldonline.cz>
Komu: HW-news <hw-list na list.hw.cz>
Datum: 10. 12. 2019 16:59:52
Předmět: stm32 cdc 
"Resim problem s STM32 VCP, at delam co delam tak to nic nedela.

Postupuji podle tohoto:
http://shawnhymel.com/1795/getting-started-with-stm32-nucleo-usb-virtual-com
-port/

Ale behem MX_USB_DEVICE_Init(); mi to skoci do void 
HardFault_Handler(void) a koncim.

Jsem zacatecnik, je nejaka rada proc se tak deje? Respektive jak zjistit 
proc se tak deje.

Diky za nasmerovani

ToMaS

P.S. Mam STM32L412, ale to asi neni problem.
_______________________________________________
HW-list mailing list - sponsored by www.HW.cz
Hw-list na list.hw.cz
http://list.hw.cz/mailman/listinfo/hw-list
"
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20191210/000c94c6/attachment.html>


Další informace o konferenci Hw-list