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

Parents
  • 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;
    }
    
Reply
  • 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;
    }
    
Children
Related