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

Hardfault ble_nus_send_data

Hello!

Im getting a hardfault when trying to send 10 bytes data via NUS. I receive the data, but the app crashes:

0> <error> hardfault: HARD FAULT at 0x00000000
0> <error> hardfault: R0: 0x20008170 R1: 0x00000000 R2: 0x00000000 R3: 0x00000002
0> <error> hardfault: R12: 0x000001F4 LR: 0x0003F75F PSR: 0x00000000
0> <error> hardfault: Cause: The processor has attempted to execute an instruction that makes illegal use of the EPSR.

Im using FreeRTOs + SD132 v 6.1.1 and SDK 15.3

Any idea where to look at?

Parents Reply Children
  • Dear Einar,

    I implemented my UARTE receiving procedure writing directly the registers. When I heavily (meaning more than 10sending/receiving of 6 bytes on average) use UARTE and I call a function with the data received, I have the hardfault happening.

    This is the interrupt receiving code

    void UARTE0_UART0_IRQHandler(void)
    {
    
      if (m_uart_instance.p_reg->EVENTS_RXSTARTED)
      {
        m_uart_instance.p_reg->EVENTS_RXSTARTED = 0; // clear register
      }
      if(m_uart_instance.p_reg->EVENTS_RXDRDY)
      {
        m_uart_instance.p_reg->EVENTS_RXDRDY=0; //clear register
        if(!timer_started)
        {
          timer_started=true;
          common_start_uart_recv_timer();
        }
        uint32_t amount = m_uart_instance.p_reg->RXD.AMOUNT;
      }
      if(m_uart_instance.p_reg->EVENTS_ENDRX)
      {
        m_uart_instance.p_reg->EVENTS_ENDRX=0; //clear register
        nrfx_uarte_event_t evt;
        evt.type = NRFX_UARTE_EVT_RX_DONE;
        evt.data.rxtx.bytes  = m_uart_instance.p_reg->RXD.AMOUNT;
        evt.data.rxtx.p_data = m_tmp_buffer;
        
        //This gives the EPSR StateError Hardfault
        handle_uart_event(&evt);
        
        //This does NOT, but it's not feasible, as I'm losing bytes
        if(m_uart_evt_queue_size<UART_EVT_QUEUE_MAX_SIZE)
        {
          memcpy(&(m_uart_evt_queue[m_uart_evt_queue_size]), &evt,sizeof(nrfx_uarte_event_t));
          m_uart_evt_queue_size++;
        }
    
      }
      if(m_uart_instance.p_reg->EVENTS_ENDTX)
      {
        m_uart_instance.p_reg->EVENTS_ENDTX=0; //clear register
        nrfx_uarte_event_t evt = {0};
        evt.type             = NRFX_UARTE_EVT_TX_DONE; 
        evt.data.rxtx.bytes  = m_uart_tx_buffer_len; //m_uart_instance.p_reg->TXD.AMOUNT
        evt.data.rxtx.p_data = m_uart_tx_buffer;
        
        //This gives the EPSR StateError Hardfault
        handle_uart_event(&evt);
        
        //This does NOT
        if(m_uart_evt_queue_size<UART_EVT_QUEUE_MAX_SIZE)
        {
          memcpy(&(m_uart_evt_queue[m_uart_evt_queue_size]), &evt,sizeof(nrfx_uarte_event_t));
          m_uart_evt_queue_size++;
        }
    
      }
      if(m_uart_instance.p_reg->EVENTS_ERROR)
      {
        err_code = m_uart_instance.p_reg->ERRORSRC;
        m_uart_instance.p_reg->ERRORSRC = err_code;
        m_uart_instance.p_reg->EVENTS_ERROR=0; //clear register
        uint32_t amount = m_uart_instance.p_reg->RXD.AMOUNT;
        nrfx_uarte_event_t evt;
        evt.type = NRFX_UARTE_EVT_ERROR;
        evt.data.error.error_mask = err_code;
        evt.data.error.rxtx.bytes=amount;
        evt.data.error.rxtx.p_data = m_tmp_buffer;
        if(m_uart_evt_queue_size<UART_EVT_QUEUE_MAX_SIZE)
        {
          memcpy(&(m_uart_evt_queue[m_uart_evt_queue_size]), &evt,sizeof(nrfx_uarte_event_t));
          m_uart_evt_queue_size++;
        }
      }
    }

    The function void handle_uart_event(nrfx_uarte_evt_t *evt) has a series of IF/ELSEs and memcpy that handle the bytes I receive.

    m_uart_evt_queue is an array of nrfx_uarte_evt_t where I store the uart events. It will be processed later by a function called with the SysTick interrupt.

    I solved the event of completed transmission, by delaying the call to the handle_uart_event with a delay of 20ms.

    The problem with the EVENTS_ENDRX register is that a delay makes me miss bytes.

    Is there any possible solution?

Related