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

Multiperipheral NUS crashes

Module: ilumi H52 BLE module (nRF52832)
SDK: nRF5_SDK_15.2.0_9412b96
Softdevice: 132_nrf52_6.1.0_softdevice.hex
Compiler: gcc version 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907] (15:7-2018-q2-4)


I have integrated the code from example "ble_app_uart" into example "ble_app_multiperipheral". Unfortunately there is some strange behaviour:

(1) NUS in single- and multiperipheral mode:
If I send debug information to UART instantly after connection established, the module crashes.

(2) NUS in single peripheral mode:
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT = 1
NRF_SDH_BLE_GATT_MAX_MTU_SIZE = 247

If I send a big amount of data from UART to BLE the modules crashes sometimes. I can't figure out why.

(3) NUS in multiperipheral mode:
NRF_SDH_BLE_PERIPHERAL_LINK_COUNT = 3
NRF_SDH_BLE_GATT_MAX_MTU_SIZE = 247 / NRF_SDH_BLE_PERIPHERAL_LINK_COUNT

The module crashes frequently. It depends on how much data is sent from UART to BLE. It does not depend on of how many central devices are connected.

for (uint8_t i = 0; i < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT; i++)
{
  if (m_qwr[i].conn_handle != BLE_CONN_HANDLE_INVALID)
  {
    do
    {
      uint16_t length = (uint16_t)uart_rx_index;
      err_code = ble_nus_data_send(&m_nus, uart_rx_data_array, &length, m_qwr[i].conn_handle);
      if ((err_code != NRF_ERROR_INVALID_STATE) && \
          (err_code != NRF_ERROR_RESOURCES) && \
          (err_code != NRF_ERROR_NOT_FOUND))
      {
        APP_ERROR_CHECK(err_code);
      }
    } while (err_code == NRF_ERROR_RESOURCES);
  }
}


I have no idea how to figure out the reason. How can I check if BLE buffer is full? What ways of debugging can I use to figure out why the module crashes?

Parents
  • Hi,

    What ways of debugging can I use to figure out why the module crashes?

    If you are entering the APP_ERROR_CHECK()/app_error_fault_handler with an error-code, please make sure that you have DEBUG defined. (CFLAGS += -DDEBUG and ASMFLAGS += -DDEBUG in the makefile when you are using gcc). Please also remove compiler optimization (to get expected debug results, OPT = -O0 -g3).

    gcc version 7.3.1

    Note that we used GCC ARM Embedded 6.3 2017-q2-update for testing and verification for the SDK 15.2 release.

Reply
  • Hi,

    What ways of debugging can I use to figure out why the module crashes?

    If you are entering the APP_ERROR_CHECK()/app_error_fault_handler with an error-code, please make sure that you have DEBUG defined. (CFLAGS += -DDEBUG and ASMFLAGS += -DDEBUG in the makefile when you are using gcc). Please also remove compiler optimization (to get expected debug results, OPT = -O0 -g3).

    gcc version 7.3.1

    Note that we used GCC ARM Embedded 6.3 2017-q2-update for testing and verification for the SDK 15.2 release.

Children
  • I have just got working Segger RTT. The flag -DDEBUG doesn't make any difference.

    RTT sends different error messages.

    NRF_SDH_BLE_GAP_DATA_LENGTH = 251:

    <info> app: Multiperipheral example started.
    <error> nrf_ble_gatt: sd_ble_gap_data_length_update() (request) on connection 0x0 returned NRF_ERROR_RESOURCES.
    <error> nrf_ble_gatt: The requested TX/RX packet length is too long by 165/165 octets.
    <info> app: Connection with link 0x0 established.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at .//main.c:395
    PC at: 0x0002CAF7
    <error> app: End of error report

    If I set NRF_SDH_BLE_GAP_DATA_LENGTH = 80:

    <info> app: Multiperipheral example started.
    <info> app: Connection with link 0x0 established.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at .//main.c:395
    PC at: 0x0002CAF7
    <error> app: End of error report

  • Could you post the code-line you have at line 395 and 394 in main.c? Please also post the whole function that line 395 is a part of.

  • Sorry, I forgot the code.

    void uart_event_handle(app_uart_evt_t * p_event)
    {
      switch (p_event->evt_type)
      {
    
        ...
    
        case APP_UART_COMMUNICATION_ERROR:
        {
          APP_ERROR_HANDLER(p_event->data.error_communication);	// main.c:395
          break;
        }
    
        default:
        {
          break;
        }
      }
    }

  • That is Nordic's bad handling of UART hardware errors!

    1. it is totally inappropriate to treat these as fatal errors;

    2. The NRF_ERROR_NO_MEM MESSAGE is nonsense and very misleading!

    See: 

    https://devzone.nordicsemi.com/f/nordic-q-a/40697/how-to-resolve-the-error-nrf_error_no_mem-at-the-case-app_uart_communication_error-in-uart_event_handle/160847#160847

  • This means that you are getting framing error on the UART. Could you try to enable internal pull up on the RX pin after uart init, and see if that fixes the issue ?

    Snippet:

    /**@snippet [Handling the data received over UART] */
    
    
    /**@brief  Function for initializing the UART module.
     */
    /**@snippet [UART Initialization] */
    static void uart_init(void)
    {
        uint32_t                     err_code;
        app_uart_comm_params_t const comm_params =
        {
            .rx_pin_no    = RX_PIN_NUMBER,
            .tx_pin_no    = TX_PIN_NUMBER,
            .rts_pin_no   = RTS_PIN_NUMBER,
            .cts_pin_no   = CTS_PIN_NUMBER,
            .flow_control = APP_UART_FLOW_CONTROL_DISABLED,
            .use_parity   = false,
    #if defined (UART_PRESENT)
            .baud_rate    = NRF_UART_BAUDRATE_115200
    #else
            .baud_rate    = NRF_UARTE_BAUDRATE_115200
    #endif
        };
    
        APP_UART_FIFO_INIT(&comm_params,
                           UART_RX_BUF_SIZE,
                           UART_TX_BUF_SIZE,
                           uart_event_handle,
                           APP_IRQ_PRIORITY_LOWEST,
                           err_code);
        APP_ERROR_CHECK(err_code);
    
    
        NRF_P0->PIN_CNF[RX_PIN_NUMBER] |= GPIO_PIN_CNF_PULL_Msk;
    }
    /**@snippet [UART Initialization] */

    Note that since you are using UART for the application, you should not use it for nrf_log, so if you have NRF_LOG_BACKEND_UART_ENABLED  in sdk_config.h , make sure it's set to 0.

    #ifndef NRF_LOG_BACKEND_UART_ENABLED
    #define NRF_LOG_BACKEND_UART_ENABLED 0
    #endif

Related