Central node crashes just after sending data

Hi,

I have tried to use central_uart example on SDK v1.91 using nRF52832. I modified the central_uart file to send hardcoded value rather data from uart. It seems there is something that makes it crashes all the time  bt_nus_client_send passes.

central_uart.7z

Can you please verify?

  • Inside central_uart/main.c-->ble_data_sent(), comment out k_free(buf), so it looks like this:

    static void ble_data_sent(struct bt_nus_client *nus, uint8_t err,
    					const uint8_t *const data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	struct uart_data_t *buf;
    
    	/* Retrieve buffer context. */
    	//buf = CONTAINER_OF(data, struct uart_data_t, data);
    	//k_free(buf);
    
    	k_sem_give(&nus_write_sem);
    
    	if (err) {
    		LOG_WRN("ATT error code: 0x%02X", err);
    	}
    }

    I did that, and then your sample worked

    Best regards,

    Simon

  • Hi 

    I would like to ask, what if I don't remove the k_sem_give() and removed the k_sem_take()? Would that cause a problem in my code?

    Thanks,

    oli

  • Hi Oli

    Simon is currently unavailable, and I will handle your case in the mean time. 

    Removing the semaphore doesn't necessarily cause a problem, but it means there is a risk that you will call the bt_nus_client_send(..) function while the current transaction is still ongoing. 

    If this happens the bt_nus_client_send(..) function will return the EALREADY error, as shown here

    In other words, if you plan to remove this semaphore you should add some code in the application to check for this error. When this error occurs the data will not be sent, and you need to send it at a later time if you want to avoid data loss. 

    Best regards
    Torbjørn

  • Hi  ,

    Thanks for the reply. Can I just equate the bt_nus_client_send() to a variable and make sure that it returns 0? Please see below:

    int err;
    
    err = bt_nus_client_send();
    if(err){
        LOG_WRN("Failed to send data over BLE connection (err %d)", err);
    }
    LOG_INF("Data sent");

    Thanks,

    oli

  • Hi Oli

    That code should work fine, yes. Just note that the "Data sent" text would be printed regardless, to me the following version would be more appropriate:

    int err;
    
    err = bt_nus_client_send();
    if(err){
        LOG_WRN("Failed to send data over BLE connection (err %d)", err);
    }
    else {
        LOG_INF("Data sent");
    }

    All error codes will be returned as negative numbers, and it is common practice to check for errors by checking if err < 0, but for functions that never return positive numbers it is sufficient simply to check the variable directly like in your example. 

    Best regards
    Torbjørn

Related