While building a CSMA communication protocol over rs485 I run into a strange timing issue which I suspect to be in the UART port driver. In order to detect collisions while writing data to the bus, I cycle out the data byte per byte and immediately read them back in (the receive enable of the rs485 driver chip is always on).
The strange thing is that where the send-readback cycle take about 20ms consistently for the first 4 bytes, it goes up to >200ms for the 5th byte and even higher for the 6th byte. The process break there as I’ve sent the read timeout to 250ms.
Code snippet and output is below. I assume the code is pretty self-explanatory (at least, that’s the intention).
Anyone has any idea what’s going on ? Coule the GC collection cycle have anything to do with this problem ?
private bool TransmitAndVerify(byte[] buffer, int offset, int count)
{
int bytesRead;
byte[] localReadBuffer = new byte[1];
byte[] localWriteBuffer = new byte[1];
bool failed = false;
driverEnablePin.Write(true);
Thread.Sleep(Configuration.ToggleTransmitPinSleepTime);
for (int i = offset; i < offset + count; i++)
{
localWriteBuffer[0] = buffer[i];
Log.Write("Rs485Socket", "TransmitAndVerify", "Writing " + localWriteBuffer[0] + ", i="+i);
port.Write(localWriteBuffer, 0, 1);
bytesRead = port.Read(localReadBuffer, 0, 1);
Log.Write("Rs485Socket", "TransmitAndVerify", "Read back " + localReadBuffer[0] + ", bytesRead=" + bytesRead);
if (bytesRead < 1) failed = true; // timeout occured during read operation - abort
if (localReadBuffer[0] != buffer[i]) failed = true; // sent byte was not received correctly - indicates a collision on the bus
if (failed)
{
Log.Write("Rs485Socket", "TransmitAndVerify", "Transmit failed at i="+i);
throw new Exception("Transmit failed");
}
}
driverEnablePin.Write(false);
Thread.Sleep(Configuration.ToggleTransmitPinSleepTime);
return true;
typical Debug Output :
26:0.361 @ Rs485Socket.TransmitAndVerify > Writing 165, i=0
26:0.375 @ Rs485Socket.TransmitAndVerify > Read back 165, bytesRead=1
26:0.383 @ Rs485Socket.TransmitAndVerify > Writing 0, i=1
26:0.397 @ Rs485Socket.TransmitAndVerify > Read back 0, bytesRead=1
26:0.405 @ Rs485Socket.TransmitAndVerify > Writing 2, i=2
26:0.419 @ Rs485Socket.TransmitAndVerify > Read back 2, bytesRead=1
26:0.428 @ Rs485Socket.TransmitAndVerify > Writing 1, i=3
GC: 2msec 26064 bytes used, 38316 bytes available
Type 0F (STRING ): 396 bytes
Type 11 (CLASS ): 2496 bytes
Type 12 (VALUETYPE ): 252 bytes
Type 13 (SZARRAY ): 1332 bytes
Type 15 (FREEBLOCK ): 38316 bytes
Type 16 (CACHEDBLOCK ): 72 bytes
Type 17 (ASSEMBLY ): 11556 bytes
Type 18 (WEAKCLASS ): 48 bytes
Type 19 (REFLECTION ): 24 bytes
Type 1B (DELEGATE_HEAD ): 252 bytes
Type 1D (OBJECT_TO_EVENT ): 192 bytes
Type 1E (BINARY_BLOB_HEAD ): 5748 bytes
Type 1F (THREAD ): 768 bytes
Type 20 (SUBTHREAD ): 96 bytes
Type 21 (STACK_FRAME ): 1428 bytes
Type 27 (FINALIZER_HEAD ): 168 bytes
Type 31 (IO_PORT ): 216 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
Type 36 (APPDOMAIN_ASSEMBLY ): 948 bytes
26:0.442 @ Rs485Socket.TransmitAndVerify > Read back 1, bytesRead=1
26:0.468 @ Rs485Socket.TransmitAndVerify > Writing 0, i=4
26:0.655 @ Rs485Socket.TransmitAndVerify > Read back 0, bytesRead=1
26:0.664 @ Rs485Socket.TransmitAndVerify > Writing 0, i=5
26:0.923 @ Rs485Socket.TransmitAndVerify > Read back 0, bytesRead=0
26:0.930 @ Rs485Socket.TransmitAndVerify > Transmit failed at i=5
#### Exception System.Exception - 0x00000000 (3) ####
#### Message: Transmit failed
#### WiredNetwork.Utilities.Rs485Socket::TransmitAndVerify [IP: 00fc] ####
#### WiredNetwork.Utilities.Rs485Socket::SocketLoop [IP: 0162] ####
A first chance exception of type ‘System.Exception’ occurred in WiredNetwork.dll
An unhandled exception of type ‘System.Exception’ occurred in WiredNetwork.dll
Additional information: Transmit failed