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

Receiving for UART with FreeRTOS

Hello,

I have implemented a somewhat working RX algorithm for receiving data over UART but I'm looking for a good way to make it more robust. I haven't found any good answers to this in either the forum or the infocenter and I get a little bit confused regrading the driver setup.

My implementation:

  • Custom board using nRF52840
  • Using the nRF5 SDK v15.0.0.
  • Using FreeRTOS, built from the "ble_app_hrs_freertos"-example. (At the moment without BLE stack initialization.)
  • Implemented FreeRTOS task for handling UART communication.
  • Have a module connected over UART that use AT-commands.

Assumptions:

  • As it is AT-commands I always know the ending of the message, though I don't know the length as the reply to one command can be different.
    • An example is reading the ID which gives 24 bytes as answer. If there is a failure, the answer is simply "+ERR=x".
    • There is a response to every TX, thus I want to have RX after TX.

So far I have tried mostly with the "Serial port library" and I have tried using blocking-mode similar to:

uint32_t received_bytes = 0;
err = nrf_serial_write(&serial_uart, tx_tmp, tx_size, NULL, NRF_SERIAL_MAX_TIMEOUT);
err = nrf_serial_read(&serial_uart, rx_tmp, 50, &received_bytes, 100);

This does however only work for the first message. The second time I try with nrf_serial_read() I get an error as the handle for the timer is not null, somewhere around line 136 in app_timer_freertos.c (DUH, it is already created). For experimentation I changed to the following in app_timer_create() function in app_timer_freertos.c and now it works (even though I know it is a VERY ugly solution):

    if (pinfo->osHandle == NULL)
    {
        /* New timer is created */
        memset(pinfo, 0, sizeof(app_timer_info_t));

        if (mode == APP_TIMER_MODE_SINGLE_SHOT)
            timer_mode = pdFALSE;
        else
            timer_mode = pdTRUE;

        pinfo->func = timeout_handler;
        pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback);

        if (pinfo->osHandle == NULL)
            err_code = NRF_ERROR_NULL;
    }
    else
    {
        xTimerReset(pinfo->osHandle, 100);
        /* Timer cannot be reinitialized using FreeRTOS API */
        //return NRF_ERROR_INVALID_STATE;
    }

So is this a bug or am I using it totally wrong? Is the approach of using software timers good, or should I change to some other method?

Regards

Robert

Parents
  • Hi,

    I am sorry to see that this has been left unanswered for so long.

    I have tried to look into these issues, but I am afraid I need some help from a colleague who is out-of-office and will be so for the next two weeks. Hopefully I can come back to you before that, but that I cannot guarantee.

    From what I can tell thus far, yes, your proposed workaround in the opening post looks ugly, and I would find it very strange if something like that should be necessary. Are you sure that you have configured the serial port library correctly?

    We might need your full project, at least more code, in order to set up, reproduce and investigate further. You may open a private case in order to do so, if confidential. In that case please refer to this thread.

    Regards,
    Terje

  • Hello,

    Was this issue ever resolve? I am having the same issue with the SDK-15.2.0

  • No, this issue was never resolved. I did continue with my ugly fixes as it was only a technology demonstrator and something very temporary. I have since long stopped working on this project and I'm currently not working with any Nordic MCUs.

    I have received several messages about this so this seems to be an issue for more people. Maybe can help out?

Reply Children
No Data
Related