3 years, 2 months ago.

How to make printf() non-blocking?

I establish a serial connection over USB to an nRF52840-DK programmed with mbed with:

  Serial pc(USBTX, USBRX); // tx, rx

and subsequently use:

pc.printf(...)

to send out debugging information out from the nRF52840-DK over USB. I open putty to the usb serial port, and all is good. I see the debugging information.

HOWEVER, if I close putty, the program hangs, up until I open putty again and re-connect. This is 100% repeatable.

I don't want this. I want the program to continue whether or not I have a terminal connected to read the output.

How do I make printf() not hang like this?

Please advise.

It's even worse than I thought. If I comment out Serial declaration and replace it with:

    Serial pc(P0_6, P0_8); // tx, rx

it does, as expected, send the debug information out over P0_6, which is correct. However, it also continues to send out the debug information over USB, which is wrong. Furthermore, if there is no terminal connected over USB to read the debug information, it will hang! And that's completely not how it should be. Again, if I then open a terminal over USB to read the debug information, the system unhangs itself again. All this is 100% repeatable.

So far, the only way to evade the problem is to comment out all serial declarations as well as anything related to it, like printf()'s. Only then does the program run without hanging.

posted by David WhiteHare 19 Sep 2018

Odd. That must be platform specific because it certainly doesn't do it for other boards.

posted by Andy A 19 Sep 2018

1 Answer

3 years, 2 months ago.

The reason that switching to P0_6 and P0_8 causes the data to come out of the USB port is because the USB port is on P0_6 and P0_8. USB_TX and USB_RX are aliases for those pins.

It looks like the hardware flow control pins on that port are also connected up to the device that does the USB to serial conversion. My guess is that that is what's causing the issue.

So possible options to try:

In your software on startup disable flow control on the pc port.

On the PCB break solder bridges SB22 and SB24. That will physically disconnect the flow control lines. The USB device may still try to stop the port sending data but the signal will never get to the port.

On the PCB break solder bridges SB23 and SB25. That will physically disconnect the data lines from the USB device. Unfortunately this will also disable the USB serial port but it should stop it from having any influence on the port.

Accepted Answer

Thank you! That explains it. I disabled RTS and CTS using:

  NRF_UART0->PSEL.CTS=0XFFFFFFFF;  //disconnect any CTS pin.  CTS disabled.
  NRF_UART0->PSEL.RTS=0XFFFFFFFF;  //disconnect any RTS pin.  RTS disabled.

and now printf() still works but doesn't block. :)

posted by David WhiteHare 19 Sep 2018