This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Debugging Hardfault

Hi,

I'm working on an application with an accelerometer without SoftDevice (for the moment). The accelerometer communicate in I2C. It send an interruption when a new sample is available (50Hz).

Some simple calculation are done on these values.

During debugging, I have some random hardfault. What can I do to understand the root cause of this hardfault?

I'm using Segger embedded studio. You can see below a screen shot of the call stack when that happened.

image description

  • Are you checking error codes from all function calls? How often do you see the hardfault? Could you post code snippets from the accel_read() and register_get() functions?

  • In fact, I'm not checking the error code on "register get" function. I will add this check.

    You can see below these 2 functions.

    Accel read and register get (i2C) functions :

        void accel_read(void){
        ret_code_t err_code;
    
        uint8_t read;
        uint8_t valueL = 0,valueH = 0;
        int16_t x_raw, y_raw, z_raw;
        int32_t x, y,z;
        int32_t accel;
         
        // Read acceleration on all axis 
        register_get(H3LIS331DL_REG_OUT_X_L, &valueL);
        register_get(H3LIS331DL_REG_OUT_X_H, &valueH);
        x_raw =  (valueH<<8)|valueL;
        register_get(H3LIS331DL_REG_OUT_Y_L, &valueL);
        register_get(H3LIS331DL_REG_OUT_Y_H, &valueH);
        y_raw =  (valueH<<8)|valueL;
        register_get(H3LIS331DL_REG_OUT_Z_L, &valueL);
        register_get(H3LIS331DL_REG_OUT_Z_H, &valueH);
        z_raw =  (valueH<<8)|valueL;
        
        // Converting raw data to mg
    
        x = x_raw *3;
        y = y_raw *3;
        z = z_raw *3;
    
        //NRF_LOG_INFO("Accel x %i, %i, %i \r\n", x,y,z);
    
        accel = sqrt(x*x + y*y + z*z);
    
       //add accel value to a buffer. When the buffer is full, detect the peak.
        peak_detection(accel); 
    }
    
    
    
    
    static ret_code_t register_get(uint8_t reg, uint8_t * pval)
    {
      uint32_t start;
    
      // Write register address
      m_xfer_done = false;
      nrf_drv_twi_tx(&m_twi, SLAVE_ADDRESS, &reg, 1, true);
      start = NRF_RTC1->COUNTER;
      while ((m_xfer_done == false) && ((NRF_RTC1->COUNTER - start) < TWI_TIMEOUT) ) ;
    
      if (m_xfer_done == false)
        return NRF_ERROR_TIMEOUT;
    
      // Read register value
      m_read_done = false;
      nrf_drv_twi_rx(&m_twi, SLAVE_ADDRESS, pval, 1);
      start = NRF_RTC1->COUNTER;
      while ((m_read_done == false) && ((NRF_RTC1->COUNTER - start) < TWI_TIMEOUT) ) ;
    
      if (m_read_done == false)
        return NRF_ERROR_TIMEOUT;
      
      return NRF_SUCCESS;
    }
    
  • Are you basing your application on any of the examples in the SDK? Which SDK version are you using? Are you using the Hardfault handling library? What TWI device are you interfacing? Could you upload your entire SES project for debugging?

Related