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
  • Hi,

    RTT works over SWD, and should not interfere with the UART interface. Could it be some issue with the buffer scopes, causing the libUARTE buffers to be overwritten before being processed/transmitted?

    Have you tested with different UART pins, just to make sure there is nothing else in the application trying to write to these pins?

    Best regards,
    Jørgen

  • 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

Reply
  • 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

Children
Related