Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

libuarte sometimes print garbled

Hello, 

I'm implementing libuarte with ble_app_multilink. But receiver side receive gibberish like below.

Fò EGGER RTT            ˆÞ œb     ¨   ¯               25BA0301A70001540020FFA9FD3D003203    # This one is mixed with something

4824C20303F3000100CBEE00000403140000E2FF77FF41F8FD044CFEAEFDA7FD3F003903    # This one is correct

4824D90303F3000100CBEE00001803140000EBFF6AFF4BF80900FDFF0900A2FD3A003A03

4„ EGGER RTT            ˆÞ œb     þ                  25BA0301E00001006800000100000100DFEE0000DD030006010159000101010302030000

It looks like RTT message is printed to serial port. But I have already disabled NRF_LOG_BACKEND_UART_ENABLED.

Here is my sdk_config file

6862.sdk_config.h

Thank you so much 

 

Parents Reply Children
  • Thank you for your response. I have solved the problem that there is a bug in my code.

    I'm sorry to bother you.

    On the other hand, I have few questions about libuarte and ble_app_multilink.

    1. Is libuarte thread-safe? What happens if two peripheral's events calling nrf_libuarte_async_tx.

    2. Is nrf_queue thread-safe? I know nrf_queue is interrupt secure. Is that equals to thread-safe?

    3. Is the following code looks good for two peripherals?

    buffer_t buf;
    buf.p_data = p_lbs_c_evt->params.button.p_data;
    buf.length = (uint8_t)p_lbs_c_evt->params.button.data_len;
    
    ret_code_t err_code = nrf_libuarte_async_tx(&libuarte, buf.p_data, buf.length);
    if (err_code == NRF_ERROR_BUSY){
        if (!nrf_queue_is_full(&m_buf_queue)){
            ret_code_t err_code = nrf_queue_push(&m_buf_queue, &buf);
            APP_ERROR_CHECK(err_code);
        }
    }

    4. If libuarte/nrf_queue not thread-safe, should I need to implement something like

    CRITICAL_REGION_ENTER();

    CRITICAL_REGION_EXIT();

    Best Regards

    Leo

  • Hi,

    unfortunately, libuarte is currently not thread safe. It is returning NRF_ERROR_BUSY when transfer is in progress but setting busy state is done without protection so there is a chance for race. It can be easily fixed in `nrf_libuarte_drv.c`

    In the beginning of nrf_libuarte_drv_tx() function there is


        if (p_libuarte->ctrl_blk->p_tx)
        {
            return NRF_ERROR_BUSY;
        }
        p_libuarte->ctrl_blk->p_tx = p_data;

    That can be replaced with:

    if (!nrf_atomic_u32_cmp_exch(&p_libuarte->ctrl_blk->p_tx, NULL, p_data)) {
      return NRF_ERROR_BUSY;
    }

    Code above is using exclusive access to safely set p_tx which is used for determining if driver is busy. That will make it thread safe.

    Regarding nrf_queue, it is thread safe.

    If you don't want to modify libuarte code you would need to wrap tx call with critical region.

    Krzysztof

Related