This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

BusFault on Power Reset

Hello,

if i power up my system i get an BusFault. On a lucky punch it works. If i Debug the system the fault doesnt happen.

I have found out where the fault happens and the reason why is absolutely clear. But i cant find out how the system comes in this state for the fault.

This is a short code snipped where the fault happend

nrfx_err_t uarte_get_async_data(uarte_select_e const sel, uarte_rx_buffer_t ** const pp_data)
{
  ...
  ...
  (*pp_data)->lengh = 0; //there the fault happens

  //save buffer location
  uarte_rx_buffer_t * tmp = *pp_data;

  //disable irq while operate on global rxDatas
  //only change the two buffers, do not copy content
  __disable_irq();
  *pp_data = p_cont->rxDatas.buffer;
  p_cont->rxDatas.buffer = tmp;
  __enable_irq();

  return...
}

in the line where i set the lengh to 0 the fault happen because of some reason *pp_data points to a wrong address eg 0x0601235d!

I have an Cortex-M4 and as debug interface i only can use SWDIO/SWDCLK. I dont have the SWO pin!

I also can use further GPIO pins to morse some status codes to my logic analyser ;).

first step i have done is to check why the busfault occure:

-> check BFSR Register -> IMPRECISSER Bit was set -> disable caching:


volatile uint32_t* ACTLR = (uint32_t*)0xe000e008;
*ACTLR |= 0x2;

-> now BFSR Register -> PRECISERR is set and BFAR Register is: 0x0601235d -> match with the content of the *pp_data if i attach the debugger when the system is already crashed!!

 

Okey thats it, i also know definitly that anywhere write to the content of my *pp_data variable! But where because when i debug the fault doesnt happen!

 

The next step i tried:

-> Use Data Watchpoint and Trace Unit (DWT)!

DWT work if i use the Debugger and the CPU HALT, but the problem only occure during power up without debugger! DWT without debugger CANT HALT the CPU it is only possible to send an Debug event and call the DebugMon_Handler!

I thought if the memory access to the variable occure the DWT send an Debug event and call the DebugMon_Handler, in the handler i run while(true). If this happend i have enought time to attach the debugger and check the stackframe!

i configured the moinitor exception like this:

CoreDebug->DEMCR |= 0x10000; //MON_EN
CoreDebug->DEMCR |= 0x1000000; //TRCENA
CoreDebug->DEMCR |= 0x7F0; //Debug Traps

I have tested the DebugMon_Handler if i insert an __asm("bkpt") the DebugMon_Handler will be called! but when i do an write access to the pp_data variable the DebugMon_Handler wont be called! As i already said if i debug and write to the pp_data variable the CPU HALT -> DWT seems to work, but only with connected Debugger, on disconnected Debugger the DebugMon_Handler wont be called.

I configured the DWT like this, if i write 0x0601235d to the variable "check" the CPU halt:

DWT->COMP3 = (uint32_t)✓
DWT->COMP1 = 0x0601235d;
DWT->FUNCTION1 = 0x3b06;

Any further proposals what i can do/check to find out who writes to the pp_data variable?

Parents
  • Not sure if it helps, but I use this to setup DWT:

    //
            // get debug register base address
            //
            movs    r2,#0x1000
            movt    r2,#0xe000
    
            //
            // enable write access
            //
            ldr     r1,=0xC5ACCE55
            str     r1,[r2,#0xfb0]
    
            //
            // clear WP
            //
            movs    r1,#0
            str     r1,[r2,#0x20+WP*16]
            str     r1,[r2,#0x28+WP*16]
            movs    r1,#2                   // 32bit access
            str     r1,[r2,#0x24+WP*16]
    
    
            //
            // enable monitor mode
            //
            movw    r0,#0xedf0-0x1000
            adds    r2,r2,r0
            ldr     r1,[r2,#0xc]
            orrs    r1,r1,#1<<16            // enable Monitor mode
            orrs    r1,r1,#1<<24            // TRCENA
            str     r1,[r2,#0xc]
    
            //
            // set prio of monitor exception
            //
            movw    r0,#0xed00
            movt    r0,#0xe000
            ldr     r1,[r0,#0x20]
            bic     r1,r1,#0x000000ff       // highest prio
            str     r1,[r0,#0x20]

    With WP == 0,

    And setting the WP

      TFUNC   wp_stkchk_set
            mov     r2,#0x1000
            movt    r2,#0xe000
    
            str     r0,[r2,#0x20+WP*16]
            movw    r0,#DWT_FUNCTION_WO_DBG_EVT
            str     r0,[r2,#0x28+WP*16]
    
            bx      lr

Reply
  • Not sure if it helps, but I use this to setup DWT:

    //
            // get debug register base address
            //
            movs    r2,#0x1000
            movt    r2,#0xe000
    
            //
            // enable write access
            //
            ldr     r1,=0xC5ACCE55
            str     r1,[r2,#0xfb0]
    
            //
            // clear WP
            //
            movs    r1,#0
            str     r1,[r2,#0x20+WP*16]
            str     r1,[r2,#0x28+WP*16]
            movs    r1,#2                   // 32bit access
            str     r1,[r2,#0x24+WP*16]
    
    
            //
            // enable monitor mode
            //
            movw    r0,#0xedf0-0x1000
            adds    r2,r2,r0
            ldr     r1,[r2,#0xc]
            orrs    r1,r1,#1<<16            // enable Monitor mode
            orrs    r1,r1,#1<<24            // TRCENA
            str     r1,[r2,#0xc]
    
            //
            // set prio of monitor exception
            //
            movw    r0,#0xed00
            movt    r0,#0xe000
            ldr     r1,[r0,#0x20]
            bic     r1,r1,#0x000000ff       // highest prio
            str     r1,[r0,#0x20]

    With WP == 0,

    And setting the WP

      TFUNC   wp_stkchk_set
            mov     r2,#0x1000
            movt    r2,#0xe000
    
            str     r0,[r2,#0x20+WP*16]
            movw    r0,#DWT_FUNCTION_WO_DBG_EVT
            str     r0,[r2,#0x28+WP*16]
    
            bx      lr

Children
No data