I've read two stories on the serial print transmit buffer:
(1) the print command moves one character at a time into the processor's hardware UART peripheral transmit buffer (which can only hold one character). The movement from application space to UART hardware is nearly instantaneous, but the UART transmits the character at baud rate. If the print command contains several characters, the application must wait for each consecutive character to empty from the UART hardware until the final character is moved into the tranmit buffer. Then the program execution continues. (i.e. the program progresses to the next line of code only after the last character is transferred to the UART peripheral.)
(2) the print command moves the entire string (many characters) into an interrupt-driven transmit buffer, and it handles the movement of each individual character through the UART hardware while the application code continues to runs in the "foreground". (i.e. the program immediately progresses to the next line of code, although one or more characters are queued in a software transmit buffer.)
I'm trying to optimize the loop time of a controller. Right now, I have the controller outputting a couple variables to a serial terminal (at 115200 baud). This is obviously slowing down my loop rates. I was thinking of perhaps filling a string up in a loop, then transmitting one character of the string on each subsequent loop until all characters have been sent. Once emptied, the next loop would refill the string with updated variables. My variables would be updated every n loops, but since my loops times would presumably be faster, I wouldn't mind. Understanding how the Arduino handles serial print xmits would help.
There is a 64 byte (IMHO) transmit buffer which is filled from the application and emptied from
the UART handler. If the buffer fills up, Serial.print blocks.
So you better put less in the buffer than can be transported, or you will be slowed down.
smoore:
I've read two stories on the serial print transmit buffer:
(2) the print command moves the entire string (many characters) into an interrupt-driven transmit buffer, and it handles the movement of each individual character through the UART hardware while the application code continues to runs in the "foreground". (i.e. the program immediately progresses to the next line of code, although one or more characters are queued in a software transmit buffer.)
Almost correct, there is a 63 byte TX buffer. Serial.print() will add to this buffer, if there is available space the Serial.print() function will return immediately, the data will be shifted out thru UART by a background interrupt process.
Now if the data passed is bigger than will fit in the buffer Serial.print() will wait for the Hardware UART to empty enough space to hold the buffer. This will cause Serial.print() to 'hang'.
You can call Serial.availableForWrite() to get the space available in the TX buffer before you Call Serial.print(); You can use this info to decide if you want to call Serial.print(), or adjust how much data you send.
I still think there is a 64 byte buffer (to use masking for the index wraps),
but for programming convenience it will be regarded as full if it contains 63 characters.
(full = (adv(wPtr) == rPtr)) it makes it easy to differenciate between empty and full.