This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bug in nrf_serial_read

We have found what appears an easily reproducible bug in nrf_serial_read.

Reproduce as follows:

* PCA10040

* SDK 15.3

* SES

* Example project peripheral serial

* Change to Flow control disabled

* Change the timeout parameter on nrf_serial_read to 0 (is 1000)

Now when you do the echo loop occasionally you will see random characters.

I cant see any reason that a zero timeout shouldnt work..?

  • Hi,

    occasionally you will see random characters

    Can you give an example?

    Do you send anything to the board from another device, or do you connect TX to RX?

    Best regards,
    Jørgen 

  • No, it is complete reproducible just with the standard peripheral/serial project in the SDK.  As you know that simply does an echo back of the characters you type in a terminal connected to the usb port of the PCA10040.

    So if you try the example project, you will see that it works as it comes in the SDK, but by simply making the 2 changes I list above (remove flow control and set timeout to 0), random characters will occur as you type and echo at slow speed.

    It cant be overrun condition, since it is just slow typing at 115200 and under that condition flow control should not be needed.  

  • Anything further I can provide to help u reproduce this bug?

  • Hi,

    Sorry for the long delay before my reply on this issue.

    I did some testing today, and I think I found what is causing the issue you are seeing.

    When you pass 0 as an argument to the timeout_ms parameter, the transfer will operate in non-blocking mode. Since you have no delay, the same buffer will be passed to the library's RX queue multiple times, and it is potentially overwritten by a transfer. You should make sure that the previous transfer is completed, before starting a new transfer with the same buffer. This can be done by implementing the event handler, and use a flag to wait for the completion. I'm not able to reproduce the issue with the following code: 

    /**
     * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    #include <stdint.h>
    #include <stdbool.h>
    #include <stddef.h>
    
    #include "nrf.h"
    #include "nrf_drv_clock.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_drv_power.h"
    #include "nrf_serial.h"
    #include "app_timer.h"
    
    
    #include "app_error.h"
    #include "app_util.h"
    #include "boards.h"
    
    /** @file
     * @defgroup nrf_serial_example main.c
     * @{
     * @ingroup nrf_serial_example
     * @brief Example of @ref nrf_serial usage. Simple loopback.
     *
     */
    
    uint8_t rx_done = false;
    #define OP_QUEUES_SIZE          3
    #define APP_TIMER_PRESCALER     NRF_SERIAL_APP_TIMER_PRESCALER
    
    NRF_SERIAL_UART_DEF(serial_uart, 0);
    
    static void sleep_handler(void)
    {
        __WFE();
        __SEV();
        __WFE();
    }
    
    static void event_handler(struct nrf_serial_s const *p_serial, nrf_serial_event_t event)
    {
        switch(event)
        {
            case NRF_SERIAL_EVENT_RX_DATA:
            {
                rx_done = true;
            }
            break;
        }
    }
    
    NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
                          RX_PIN_NUMBER, TX_PIN_NUMBER,
                          RTS_PIN_NUMBER, CTS_PIN_NUMBER,
                          NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                          NRF_UART_BAUDRATE_115200,
                          UART_DEFAULT_CONFIG_IRQ_PRIORITY);
    
    #define SERIAL_FIFO_TX_SIZE 32
    #define SERIAL_FIFO_RX_SIZE 32
    
    NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
    
    
    #define SERIAL_BUFF_TX_SIZE 1
    #define SERIAL_BUFF_RX_SIZE 1
    
    NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
    
    NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ,
                          &serial_queues, &serial_buffs, event_handler, sleep_handler);
    
    
    int main(void)
    {
        ret_code_t ret;
    
        ret = nrf_drv_clock_init();
        APP_ERROR_CHECK(ret);
        ret = nrf_drv_power_init(NULL);
        APP_ERROR_CHECK(ret);
    
        nrf_drv_clock_lfclk_request(NULL);
        ret = app_timer_init();
        APP_ERROR_CHECK(ret);
    
        // Initialize LEDs and buttons.
        bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);
    
        ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
        APP_ERROR_CHECK(ret);
    
        static char tx_message[] = "Hello nrf_serial!\n\r";
    
        ret = nrf_serial_write(&serial_uart,
                               tx_message,
                               strlen(tx_message),
                               NULL,
                               NRF_SERIAL_MAX_TIMEOUT);
        APP_ERROR_CHECK(ret);
    
        while (true)
        {
            static char c;
            while(rx_done == false);
            rx_done = false;
            ret = nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 0);
            if (ret != NRF_SUCCESS)
            {
                continue;
            }
            (void)nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);
            (void)nrf_serial_flush(&serial_uart, 0);
    
        }
    }
    
    /** @} */
    

    Best regards,
    Jørgen

Related