1

My question is related to this one. My sketch seems to stop responding after some time if I run it with debug enabled and I don't open the serial port/monitor on the computer.

Does the UART buffer fill up and block or something? Or, does it discard the excess data and keep working?

I can't find information about it.

2
  • In the avr hardware serial implementation, a write/print command will block until there is room if the buffer is full. My guess is that USB serial would act the same. Commented Aug 3, 2015 at 4:44
  • In your other thread I suggest a way of testing the Serial port periodically to see if it is available.
    – Nick Gammon
    Commented Aug 3, 2015 at 5:30

1 Answer 1

1

As far as I can see from CDC.cpp it attempts to see if the USB is available and if not, do not write anything but set the "write error" flag.

size_t Serial_::write(const uint8_t *buffer, size_t size)
{
    /* only try to send bytes if the high-level CDC connection itself 
     is open (not just the pipe) - the OS should set lineState when the port
     is opened and clear lineState when the port is closed.
     bytes sent before the user opens the connection or after
     the connection is closed are lost - just like with a UART. */

    // TODO - ZE - check behavior on different OSes and test what happens if an
    // open connection isn't broken cleanly (cable is yanked out, host dies
    // or locks up, or host virtual serial port hangs)
    if (_usbLineInfo.lineState > 0) {
        int r = USB_Send(CDC_TX,buffer,size);
        if (r > 0) {
            return r;
        } else {
            setWriteError();
            return 0;
        }
    }
    setWriteError();
    return 0;
}

This is the same test as is done in operator bool() without the 10 ms delay.

// This operator is a convenient way for a sketch to check whether the
// port has actually been configured and opened by the host (as opposed
// to just being connected to the host).  It can be used, for example, in 
// setup() before printing to ensure that an application on the host is
// actually ready to receive and display the data.
// We add a short delay before returning to fix a bug observed by Federico
// where the port is configured (lineState != 0) but not quite opened.
Serial_::operator bool() {
    bool result = false;
    if (_usbLineInfo.lineState > 0) 
        result = true;
    delay(10);
    return result;
}

Judging by the comments above, this may not be the most reliable thing in the world.

5
  • The whole CDC/ACM system has a fundamental flaw in that there is no way of knowing if the port has been opened - you can only examine the line states (DTR and RTS) to see if something the other end has asserted those lines. On some operating systems those lines are asserted by default (though that behaviour can be disabled) and on other operating systems it's left to the whim of the software that opens the port. The whole arrangement is very hit-and-miss, and it's for precisely that reason that FTDI developed their own proprietary protocol instead of using CDC/ACM.
    – Majenko
    Commented Aug 3, 2015 at 9:27
  • At least on Windows 10 Serial starts to return 'true' when the COM port is open and keeps returning 'true' no matter you open or close it. So if you close it the output buffer may full up and block forever on write calls. I gave it other power source and now I can see disconnecting the USB cable makes Serial to return 'false' and connecting it back and opening the COM port again makes it 'true' again.
    – aalku
    Commented Aug 3, 2015 at 12:10
  • @Majenko How can I examine the DTR of Serial on Arduino Pro Micro?
    – aalku
    Commented Aug 3, 2015 at 12:20
  • 1
    @aalku if (Serial) - that's what it does. It examines the control line states. But of course it's down to the remote end as to what that actually means.
    – Majenko
    Commented Aug 3, 2015 at 12:22
  • 1
    @Majenko Well, you can't trust it. At least on Windows 10. If DTR is signaled write should not block as far as I know, and it does. That can't happen in a hardware serial port. You write and if the other end can't listen the data is lost.
    – aalku
    Commented Aug 3, 2015 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.