Page 1 of 6
[DONE] Serial port losing data when several threads are acti
Posted: Sat Jun 15, 2013 4:38 am
by hebnern
I have a custom board that uses an STM32F205. I am using USART1 in half duplex mode to implement a 1-wire bus master. If you are not familiar with the protocol, here is a quick description: The bus is composed of an open drain line on the master connected to open drain lines on the slaves with a single pull-up for the entire bus. _Every_ bit transmission on the bus is initiated by the master pulsing the line low for precise periods of time.
In my case, these precise timings are implemented by sending specific byte values from a 115200 baud serial port. Now, when the serial port is set to half duplex mode, the STM32 internally connects the transmitter and receiver and takes care of disabling the transmitter after transmission is complete. Since the RX and TX are internally connected, _every_ byte that is transmitted will also be received by the UART.
My driver is implemented using the Serial driver and it seems to work perfectly when it is the application is run in a single thread. However, when I start adding all the other threads that my app requires, I start losing bytes. As described above, RX and TX are internally connected, yet somehow I am occasionally not reading bytes that I just sent. I don't see how task switching would affect this since the interrupts should still be occurring and buffering the incoming bytes.
Since only one byte at a time is ever transmitted, and received, it should be impossible for the queue to be overflowing. I added some checks for this anyway, and it is definitely not occurring. I also turned on all debugging features to check for stack overflow or other weirdness, but everything seems to be operating normally.
I am not sure what could be causing this or what else to try. Any ideas?
Re: Serial port losing data when several threads are active
Posted: Sat Jun 15, 2013 8:31 am
by DrunkenDonkey
I recall I was losing data on the serial port too on 115200, worked fine with 57600 and was not an overflow issue too. Gave up on it and continued to use 57600 for the time being, not that it helps tho, but mentioning, it was way back.
Re: Serial port losing data when several threads are active
Posted: Sat Jun 15, 2013 9:25 am
by Giovanni
What about thread priorities, if the thread operating on the serial port has the highest priority then it should be unaffected by other threads.
Also verify the error events from the serial driver, you could be getting overflow flags without noticing it. In order to do so you need to register an Event Listener on the serial driver and examine the flags.
Giovanni
Re: Serial port losing data when several threads are active
Posted: Sun Jun 16, 2013 2:58 am
by hebnern
I tried making the thread the highest priority and it maybe helped a tiny bit, but there is still lots of data loss. I will try hooking up event handlers to the UART events and see what I get.
Re: Serial port losing data when several threads are active
Posted: Sun Jun 16, 2013 3:37 am
by hebnern
I am checking the flags after the 1-wire transmission phase is complete. It looks like I am getting SD_NOISE_ERRORs very rarely, but even when those happen, I am able to receive all data. When the data loss occurs, the flags read exactly the same as when it succeeds: IO_INPUT_AVAILABLE | IO_OUTPUT_EMPTY | IO_TRANSMISSION_END.
Re: Serial port losing data when several threads are active
Posted: Sun Jun 16, 2013 6:54 am
by Giovanni
Are you running with the debug options in chconf.h enabled? if not please try that.
Giovanni
Re: Serial port losing data when several threads are active
Posted: Sun Jun 16, 2013 8:49 am
by hebnern
Yes, I have enabled all debugging options without issue.
I have gotten it working fairly well by increasing the priority, ensuring that other threads yield quickly, and minimizing my serial reads/writes by sleeping while waiting for commands to be processed by the slave instead of polling for completion. I am still getting the occasional read timeout which I don't understand, but it is at least much better.
I was thinking that maybe the slave was stomping on the start bit being sent by the master causing it to not see its own transmissions, but since the bus is open drain and idle-high, it is impossible for any device on the bus to prevent any other device from pulling the line low. Thus the master should always receive some value when it transmits.
I have also been reading about interrupt priorities thinking that maybe the preempting scheduler interrupt was causing us to lose UART interrupts, but from what I read this should not occur, the UART interrupts may be delayed, but they should be executed when any higher priority interrupts complete.
I would like to understand what is going on, but I am not sure I will be able to find an answer. Maybe I should just leave well enough alone

Re: Serial port losing data when several threads are active
Posted: Sun Jun 16, 2013 9:53 am
by Giovanni
The driver should not lose data at those speed, there is something wring somewhere.
Could you try to increase the Serial driver circular buffer sizes? it is done in halconf.h. It it is matter of thread priorities then larger buffer will help, if it is matter of ISR saturation then it will not help but at that point we can work on IRQ priorities.
Another option is to use UART driver, it is DMA driver and more efficient but a bit harder to use because it is callback based.
Giovanni
Re: Serial port losing data when several threads are active
Posted: Tue Jun 18, 2013 7:47 pm
by hebnern
I currently have the serial queue sizes set to 64 bytes, and it should be impossible for any more than 1 byte to be queued up at any time since all of my reads/writes look like:
read_bit_from_slave()
// write the start bit, the slave will fill in the data
sdPut(SD1, 0xFF);
// read the start bit that we just wrote plus data from the slave
return sdGet(SD1);
write_bit_to_slave(c)
// write the data to the slave
sdPut(SD1, c);
// throw away the data that we just wrote to ourselves
sdGet(SD1);
Since we _always_ do a blocking read after each write in order to clear the byte that we just wrote to ourselves, we should never have any more than 1 byte queued up.
You mentioned interrupt saturation. How would this cause data loss in this scenario? Are UART interrupts discarded if there are too many interrupts occurring or something?
Re: Serial port losing data when several threads are active
Posted: Tue Jun 18, 2013 8:54 pm
by Giovanni
An interrupt saturation scenario happens when the system generates interrupts with a rate so high that the CPU is unable to serve an interrupt before that interrupt is triggered again. This should never happen for slow peripherals like UARTs so I find this unlikely.
Does your application require an external pull-up? it is an open drain I/O I think, do you have a sufficiently low pull-up?
Giovanni