Anyone have any ideas why I'm getting this issue ?
Short issue statement: When writing to SD3 from 2 threads (main+worker) ( with binarySemaphore protecting access to SD3) the last byte of the previous string gets delayed until after the complete string of the second write.
PS - Please note I mention BinarySemaphore here, but actually use normal Semaphores(chSemInit(&logSem,1);
Longer Details:
I've a worker thread thats busy reading serial input from one SerialDriver (SD2), scanning for CRLF and when found, claims a binarySemaphore, chprintfs the output to another SerialDriver (SD3) and then continues on as normal.
I have a loop running in main that every 100MS it also creates some content to stream out to SD3 after claiming the same binarySemaphore.
Now the logic works fine (I know its not the right way to do this in terms of blocking the reading while writing - but ignore that for now).
The issue I get is that the last byte of the worker thread output seems to be buffered until the main loop output has completed, then it gets sent. But given the worker thread issues chprintf while holding the semaphore surely this shouldn't happen as it should block or fill the outputqueue of the serialdriver before main is able to claim the Semaphore. Operating without the Semaphore gives random blended output as you would expect.
Thread Priority seems to have some impact on this happening as well, but i'm not sure why it should have any impact given the Semaphore is controlling the ability to queue data for the serial output.
The attached png shows the serial byte sequence received including the CR/LF being split by the $RC2 string output. You can clearly see the symptom if you look at the $RC2 line in the middle of the image - the CR from the pervious semaphore protected write is there, then the $RC2 string, then the delayed LF from the previous write ).
The code in the worker thread looks like this:
Code: Select all
chSemWait(&logSem);
chprintf((BaseSequentialStream *)&SD3,"%s",nmea_buf);
chSemSignal(&logSem);The code in main looks like this:
Code: Select all
chSemWait(&logSem);
sendRC2Data((BaseSequentialStream*) &SD3, &sensorData, RC2_DT | RC2_ALL_DX | RC2_ALL_AX );
chSemSignal(&logSem);
The code in the function sendRC2Data is quite long, but the usart output command used at the end is
Code: Select all
// Add checksummarker
p+=chsnprintf((char *)&rc2Buffer[p], 7, "%02x\r\n", checksum);
// Stream rc2Buffer to stream (usually serial port)
chprintf(stream,"%s",(char *)&rc2Buffer[0]);
So - anybody any ideas why my serial data output isn't in sequence.
Thanks in advance. Probably some newby mistake but seems strange unless the IO queues are operating with priority, but then I would expect it to appear in the middle of strings as well, but it never does.