NRF52832 FreeRTOS+UARTE not worked

Hi everyone:

I want to use UARTE on my FreeRTOS, but when I used the example(examples/peripheral/libuarte) in rtos, something went wrong.

First of all, I tested the example, and it looks like good. When I send slowly, the uart log is here.

and when I send quickly(every 4ms), the uart log is that.

But when I use the UARTE in FreeRTOS, It looks OK when sending slowly, but when I send it every 4ms(I need this frequency), the result is here.

I don't know what's wrong.

Best regards, 

Lurn

Parents
  • Hi Lurn,

    There is not much to go on here. Can you elaborate a bit more? How exactly do you doing things in your implementation, and what exactly happens in the failing case? And what is the difference between the failing case (with FreeRTOS) and without it?

    Generally FreeRTOS does not interfere directly with UART, but it is tempting to think that there could be some issue with priorities, perhaps the application now is doing more or for some reason is not able to service UART related interrupts fast enough, but I don't know enough of your application to be more specific.

  • Sorry for my unclear description.

    I use the example uarte code in FreeRTOS, just modify here

        nrf_libuarte_async_config_t nrf_libuarte_async_config = {
                .tx_pin     = TX_PIN_NUMBER,
                .rx_pin     = RX_PIN_NUMBER,
                .baudrate   = NRF_UARTE_BAUDRATE_921600,
                .parity     = NRF_UARTE_PARITY_EXCLUDED,
                .hwfc       = NRF_UARTE_HWFC_DISABLED,
                .timeout_us = 2,
                .int_prio   = APP_IRQ_PRIORITY_HIGH,
                .pullup_rx  = 1
        };

    I change the int_prio from APP_IRQ_PRIORITY_LOW to APP_IRQ_PRIORITY_HIGH.

    the question is when I use FreeRTOS,when I'm done sending the data, I should receive the data immediately, the log should like that,  (the ->◇ is send data, <- Diamonds is receive data).

    But now, I get a wrong state, I only receive some data after I send it several times

    BR,

    Lurn

  • Ok, the question is I set the memcpy(data_array, 0, sizeof(data_array)) too early, that the uart data wasn't send done, so the data was be set to 0.

    but, how to handle the error format?

    BR,

    Lurn

  • Hi Lurn,

    Lurn_Z said:
    Ok, the question is I set the memcpy(data_array, 0, sizeof(data_array)) too early, that the uart data wasn't send done, so the data was be set to 0.

    No, the data is available when you get the event, so copying them immediately afterwards, and freeing the buffer is OK.

    Lurn_Z said:
    but, how to handle the error format?

    Which error?

    From what I understand, the issue here is that you get the data in chunks. That is something you need to handle though, as fragmentation can happen for many different reasons. So I would suggest that you implement a form of filtering on a higher level. UART is typically just a stream of data, so most likely there is something in the data that tells you what logical units they represent? Perhaps a new-line character, or perhaps the data is in TLV format, or something else?

  • No, I mean when I send the data quickly, the data will be piled up and then sent out in a single line.

    you can see this, I use the uart to print data (A0-BF) for one time, when I set 50ms to delay, It look fine.

        for(int i = 0; i < test_size; i++)
        {
            test_data[i] = 0xA0 + i;
        }
    
        while(1)
        {
            err_code = nrf_libuarte_async_tx(&libuarte, test_data, test_size);
            APP_ERROR_CHECK(err_code);
            vTaskDelay(50);
        }

    but when I send it quickly,  once in milliseconds, the data in uart will be piled up, like that, the delay time is 20.

    But the delay time I need is 2~4ms.

    BR,

    Lurn

  • Hi Lurn,

    Yes, handling it in the receiver is better. There is no real packet concept in UART (even though libuarte attempts to mimick it with a timeout), so you need another way to handle it. I see form your latest thread that you went for that and that that works.

    Einar

Reply Children
  • Hi Einar,

    I think something is wrong.

    On the previous basis I used two nRF device to test my code.

    No.1 use UARTE to receive data from PC and send the data to No.2 nRF device over esb.

    No.2  use esb to receive data and send it to PC over UART.

    When I tested it, I found that I can get the correct data from No.1 over esb, but when I send the data to PC over UART, Some data is wrong.

    You can see the uart print, at 00283232 the data I send is

    hex_str = '5AC48602030405060708090A0B0C0D0E0F0102030405060708090A0B0C0D0E0F'

    but I loss the '02 03 04 05'

    I can make sure that the data I received is correct. Because before I send it over UART, I print it by RTT, and it was ok.

        printf("data_array = ");
        for(int i = 0; i < index; i ++)
        {
            printf("%X,"data_array[i]);
        }
        err_code = nrf_libuarte_async_tx(&libuarte, data_array, index);
        if(err_code != NRF_SUCCESS)
            UART_PRINTF("nrf_libuarte_async_tx err_code = %d.", err_code);
        APP_ERROR_CHECK(err_code);

     Do you know what the problem is?

    BR,

    Lurn

  • Hi Lurn,

    Can you check the UART Tx line with a logic analyzer or similar to see if the data is actually sent over UART by the nRF (as the data is there it seems likely). If it is and the data seems valid there, but it is not received by the PC for some reason, then the question is why it was not received by the PC. As you are not using flow control, you could experience and should expect data loss in some situations if the other end is not ready to receive data for some reason.

    Einar

Related