I’ve been meaning to dig a little more into the system serial port on the cortex. We often see lost data when using the ROBOTC debugStream or PrintToScreen in EasyC but I did not expect the same issues to be present with the firmware I’ve been writing over the last few weeks. So lets take a look at the path the data takes from cortex to PC when we are debugging.
This diagram shows the path debugStream (or PrintToScreen) information takes. The data is generated in the user cpu and transmitted using asynchronous serial protocol at 230400 baud (bits per second) to the master cpu. The master cpu turns this stream into packets (more on that below) and sends it over either the USB tether or VEXnet to the joystick. In the joystick the packets are assembled back into an asynchronous serial stream but this time running at 115200 baud. This is sent via the programming adapter into the prolific serial adapter (or now the new vex adapter) which again turns the data back into packets that are sent to the PC over USB.
So the first obvious issue that limits how fast data can be sent is the slower of the two serial communication channels. The connection between user and master processors is at 230400 baud whereas the output of the joystick is at half this speed. Constantly sending data from user to master processors would overload the output of the joystick even if the intermediate stages were not present.
The next issue is the way the master processor turns the stream of data into packets. If the user processor is sending data slowly, say one byte at a time, it’s not very efficient to take each of these and send them over to the joystick as they arrive. For this reason, the master processor buffers the incoming bytes and waits for a gap in communication of perhaps a couple of mS. When it sees the gap it takes any buffered information and sends that in one or more packets over the USB tether to the joystick. Here is an example oscilloscope trace showing serial data (the yellow trace) leaving the user processor and then arriving out of the joystick about 3mS later (blue trace).
So life is good, but what happens when we throw a much larger amount of data at the master processor. Here is a trace showing 512 bytes of data leaving the user processor (yellow) and it arriving out of the joystick (blue).
Notice how the joystick output (blue) has it’s data grouped with small gaps between, this is due to the way the master processor is sending the data over the USB link. Without going into the gory details of how USB works, what we find if we dig into the USB stream with an analyzer is that the serial debug data is turned into packets with a maximum payload of 63 bytes. In the trace above, the 512 bytes sent from the user processor becomes eight 63 byte packets with the remaining sent in a smaller ninth packet.
Sending more than 512 bytes from the user processor starts to cause problems, there seems to be a 512 byte buffer in the master processor firmware that can be overwritten before it has time to packetize it and send over the USB link. This is the problem in EasyC when multiple PrintToScreen command are used back to back.
The next issue we face with ROBOTC is the way its proprietary communications protocol works. As discussed before in other posts, there is a 2000 byte buffer that debugStream data occupies before being sent to be displayed. ROBOTC will request a new chunk (I’m avoiding calling this a packet so as not to confuse with the USB packets) of data for display in the debug window at periodic intervals. It does this between also requesting all sorts of other information such as motor status and global variables. ROBOTC will ask for up to 250 bytes to be sent for display in one message, sometimes it will ask for several 250 byte chunks in a row before asking for other status, but the overhead of the protocol does not allow for anywhere near the theoretical maximum serial throughput to be reached. Here is an example of communication from user processor to PC showing debugSteam packets. This is in a similar format to the previous traces, it only shows serial data going from user processor to PC, it does not show the ROBOTC data requests.
As before, the yellow trace is data from user cpu to master cpu, the blue trace is the data out of the joystick and half the baud rate of the yellow data. In this example, two small packets are followed by three 250 byte debugStream packets. Note that data is flowing from the joystick for approximately 50% of the time available dropping the effective baud rate to something like 57600.
So we determine the maximum data rate for ROBOTC to be perhaps 5760 characters per second minus the overhead used for other messages, a safe speed would probably be about 3000 characters per second.