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

Sending more than one character with NUS leads to crash

Hi!

My setup:

* nRF52 DK

* nRF5_SDK_15.0.0_a53641a

* s132_nrf52_6.0.0

* SES V3.34b 64-bit

* android ver.8 smartphone with nRF Connect

I have implemented the UART service to multiperipheral application but it doesn't work well. I have added required files, made some changes in main.c:

#include "ble_nus.h"
#include "app_uart.h"
#if defined (UART_PRESENT)
#include "nrf_uart.h"
#endif
#if defined (UARTE_PRESENT)
#include "nrf_uarte.h"
#endif

#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
#define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */


static uint16_t   m_conn_handle          = BLE_CONN_HANDLE_INVALID;                 /**< Handle of the current connection. */
static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
static ble_uuid_t m_adv_uuids[]          =                                          /**< Universally unique service identifier. */
{
    {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}
};

BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);                               /**< BLE NUS service instance. */

just the function from the infocenter:

void uart_event_handle(app_uart_evt_t * p_event)
{
    static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    static uint8_t index = 0;
    uint32_t       err_code;
    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&data_array[index]));
            index++;
            if ((data_array[index - 1] == '\n') || (index >= (m_ble_nus_max_data_len)))
            {
                NRF_LOG_DEBUG("Ready to send data over BLE NUS");
                NRF_LOG_HEXDUMP_DEBUG(data_array, index);
                do
                {
                    uint16_t length = (uint16_t)index;
                    err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
                    if ( (err_code != NRF_ERROR_INVALID_STATE) && (err_code != NRF_ERROR_BUSY) &&
                         (err_code != NRF_ERROR_NOT_FOUND) )
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);
                index = 0;
            }
            break;
        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;
        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;
        default:
            break;
    }
}

static void nus_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);
}

static void nus_data_handler(ble_nus_evt_t * p_evt)
{
    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
        uint32_t err_code;
        NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
        for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
        {
            do
            {
                err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                    APP_ERROR_CHECK(err_code);
                }
            } while (err_code == NRF_ERROR_BUSY);
        }
        if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
    }
}

adding NUS to LBS:

/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    ret_code_t         err_code;
    ble_lbs_init_t     init;
    ble_nus_init_t     nus_init;
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module instances.
    qwr_init.error_handler = nrf_qwr_error_handler;

    for (uint32_t i = 0; i < LINK_TOTAL; i++)
    {
        err_code = nrf_ble_qwr_init(&m_qwr[i], &qwr_init);
        APP_ERROR_CHECK(err_code);
    }

    // Initialize LBS.
    init.led_write_handler = led_write_handler;

    err_code = ble_lbs_init(&m_lbs, &init);
    APP_ERROR_CHECK(err_code);

    // Initialize NUS.
    memset(&nus_init, 0, sizeof(nus_init));

    nus_init.data_handler = nus_data_handler;

    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);


    ble_conn_state_init();
}

main:

int main(void)
{
    bool erase_bonds = true;
    // Initialize.
    nus_uart_init();
    log_init();
    NRF_LOG_INFO("______________________");
    timers_init();
    //alarms_init(); //[pawel] timery dzialaja
    leds_init();
    buttons_init();
    power_management_init();
    ble_stack_init();
    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
    peer_manager_init(&erase_bonds);
    // Start execution.
    NRF_LOG_INFO("Multiperipheral example started.");
    advertising_start();


    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}

and in sdk_config.h (I don't really know which defines to set and which not, so I relied on app_ble_uart example config file):

sdk_config.h (too big file for embedded code so hastebin)

I am able to send only one character (for example "6") through the mobile app with the UART service. The chip is receiving it and printing it in the terminal.

When I try to send more (for example "62") I got crash and reset. Below is the call stack provided by the debugger:

I believe error 0x08 refers to NRF_ERROR_INVALID_STATE.

Any suggestion what may cause such behaviour?

Parents
  • Hi Pawel, 

     

    Could you check which line exactly throwing the error ? You can follow the debug guide here

  • Hi

    Here is the detailed call stack I provided before:

    Then regarding your link I have added DEBUG symbol to predefined settings. Here is call stack from this setting:

    Debug terminal in SES printed something like that when I tried to send 2 characters:

    <error> app: Failed receiving NUS message. Error 0x4.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\Users\pawel\Documents\nRF\sdk\nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral\experimental\ble_app_multiperipheral_2nd\main.c:420
    PC at: 0x0002ACC1
    <error> app: End of error report

    Line 420 belongs to nus_data_handler, so I put some breakpoint to analyze this:

    When I send two characters, for example "ab" the "a" prints in puTTY but "b" does not. I have found out that handling second character lead to an error in app_uart_put(...):

Reply
  • Hi

    Here is the detailed call stack I provided before:

    Then regarding your link I have added DEBUG symbol to predefined settings. Here is call stack from this setting:

    Debug terminal in SES printed something like that when I tried to send 2 characters:

    <error> app: Failed receiving NUS message. Error 0x4.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at C:\Users\pawel\Documents\nRF\sdk\nRF5_SDK_15.0.0_a53641a\examples\ble_peripheral\experimental\ble_app_multiperipheral_2nd\main.c:420
    PC at: 0x0002ACC1
    <error> app: End of error report

    Line 420 belongs to nus_data_handler, so I put some breakpoint to analyze this:

    When I send two characters, for example "ab" the "a" prints in puTTY but "b" does not. I have found out that handling second character lead to an error in app_uart_put(...):

Children
Related