Sending data without a delimiter using the nordic uart service (NUS) sample - Dropping bytes

I'm developing my application using the NRF Connect SDK in VS code.  SDK Version 2.4.2.  The NRF52832f we're using is integrated into a module made by fanstel and it has been assembled on our own internal ECU that interfaces with another microcontroller.  We're wanting to use the nordic uart service (NUS) to transfer data from one device to another,  in this case using two circuit boards but in the future one of the boards will be replaced by a smart phone.

In our project we're sending binary data using the nordic uart service profile with the peripheral uart service sample application connected to the central uart service sample application on a different evaluation board.  I added a periodic uart flush which disables the uart (code example below) because I don't have a delimiter character to indicate data is done being sent but I think this potentially makes me drop bytes when the central may receive bytes over it's physical UART between the time I disable the UART and before it's enabled again.  I see bytes drop frequently, using a BLE sniffer and also confirmed via inspection in the RTT console, which is causing serious throughput issues.

Does anyone have any experience with this?  I'm also concerned that even if I do designate a delimiter like \r\n the process of disabling/renabling the uart in the uart interrupt as is done in the sample project will still make bytes drop if more messages are sent in short succession after this.  Does anyone have the UART peripheral running without enable/disable anywhere and without delimiters?  Thanks in advance!

void uart_timeout_flush(void)
{
	for (;;) {
		if(uart_bytes_read > 0u)
		{
			uart_bytes_read = 0;
			LOG_INF("UART Flush: ");
			disable_req = true;
			uart_rx_disable(uart);
		}
		k_sleep(K_MSEC(50));
	}
}

K_THREAD_DEFINE(uart_timeout_flush_thread_id, UART_FLUSH_STACKSIZE, uart_timeout_flush, NULL, NULL,
		NULL, UART_FLUSH_PRIO, 0, 0);

Parents
  • Hey Tobjørn,
    Thanks for sharing this library with me it looks like it could help alleviate a lot of my concerns.

    What version of NRF connect sdk has this been tested on? It appears the configuration suggested in the readme isn't relevant to 2.4.2: ZEPHYR_EXTRA_MODULES doesn't seem to exist and when I add it to ZEPHYR_MODULES it causes other issues.

    Thanks,
    Nick

  • Hi Nick

    I think it was tested on v2.3.0, but I just tested the simple and the peripheral_uart samples for the nRF52840DK and I can build the samples without any issues. 

    Did you try to build one of the included samples to see if they work? 

    If you try to include the module in your own sample it is important to get the relative location of the module correct, unless you keep it identical to the existing samples. 

    If you are still unable to get it to work, could you share the build output? 

    Best regards
    Torbjørn

  • Tobjørn,

    I was able to get this configured and working in my project and it seems to have resolved my issue!  Many thanks!

    It still seems to have some odd behavior, framing errors and overruns, if you send frames to it while it's in the middle of handling it's buffers; I'm testing limiting the UART sender so it allows for processing time between packets which seems to work.  I've never had so many issues with UART on other platforms before,  I guess my past experience is that the data is immediately (isr) taken out of peripheral register buffers and placed into RAM or that the peripheral has a byte level ring buffer inside of it that causes this not to be an issue.

    Anyways I'm not complaining I swear.  This library has made the best of a bad situation.  Thanks again my friend.

    All the best,
    Nick

  • Hi Nick

    You mean you are running into issues when using the ncs-uart-handler library I shared earlier?

    What UART baudrate are you running, and have you made any changes to the buffer configuration? 

    I have done testing to verify that the library should work even with constant coms at 1Mbaud, but I haven't really tested in a scenario with a lot of other things happening in the application. Are you running a lot of other peripherals, RF protocols etc on the side? 

    If the UART async callbacks are delayed too much by other interrupts in the system it will fail at some point, but ideally it should be possible to scale the buffers according to the worst case delay in order to avoid issues. 

    Best regards
    Torbjørn

Reply
  • Hi Nick

    You mean you are running into issues when using the ncs-uart-handler library I shared earlier?

    What UART baudrate are you running, and have you made any changes to the buffer configuration? 

    I have done testing to verify that the library should work even with constant coms at 1Mbaud, but I haven't really tested in a scenario with a lot of other things happening in the application. Are you running a lot of other peripherals, RF protocols etc on the side? 

    If the UART async callbacks are delayed too much by other interrupts in the system it will fail at some point, but ideally it should be possible to scale the buffers according to the worst case delay in order to avoid issues. 

    Best regards
    Torbjørn

Children
  • Torbjørn,

    Correct.

    Running very slow, 115200, even parity, no changes to the buffer configuration though I am reconfiguring the project as a central instead of a peripheral making a sort of "phone emulator" application.

    There's essentially nothing going on outside tx/rx servicing in the application.  The main loop just reads a fifo (K_FOREVER) populated by the uart callback, sends the data to the nordic service and the bt callback frees the buffer after it's done being sent.

    Maybe I'll try to change buffers but I even have problems sending fixed length 14 character strings once every 10ms.

    Thanks,

    Nick

  • Hi Nick

    This could be related to an issue in the UART async driver when using the default interrupt based byte counting method. You can optionally enable a hardware counting feature which uses more peripherals, but ensures byte counting is handled without CPU interaction required. 

    In order to enable this you can have a look at these configuration parameters.

    Could you add these configs and see if it solves the issue? 

    Please note you need to change the name of the parameters if you want to use a different UART or TIMER module. 

    Best regards
    Torbjørn 

  • Hey Torbjørn,

    I meant to respond a while ago but:

    I think I discovered the issue.  I was calling bt_nus_send directly in the callback,  I think it blocks too long from time to time and that causes the issue.

    I'm now using a fifo and doing the sends from the main loop and everything looks great, with and without the configuration parameters you suggested.  (I was using UART0 btw so it made sense as is).

    Hardware counting also was required to get it to work correctly or we would lose data.

    Many thanks for all your help and your library,
    Nick

Related