[DONE] Serial port losing data when several threads are acti

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

hebnern
Posts: 7
Joined: Sat Jun 15, 2013 4:06 am

[DONE] Serial port losing data when several threads are acti

Post 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?
DrunkenDonkey
Posts: 124
Joined: Sun Aug 28, 2011 5:16 pm

Re: Serial port losing data when several threads are active

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial port losing data when several threads are active

Post 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
hebnern
Posts: 7
Joined: Sat Jun 15, 2013 4:06 am

Re: Serial port losing data when several threads are active

Post 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.
hebnern
Posts: 7
Joined: Sat Jun 15, 2013 4:06 am

Re: Serial port losing data when several threads are active

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial port losing data when several threads are active

Post by Giovanni »

Are you running with the debug options in chconf.h enabled? if not please try that.

Giovanni
hebnern
Posts: 7
Joined: Sat Jun 15, 2013 4:06 am

Re: Serial port losing data when several threads are active

Post 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 :)
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial port losing data when several threads are active

Post 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
hebnern
Posts: 7
Joined: Sat Jun 15, 2013 4:06 am

Re: Serial port losing data when several threads are active

Post 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?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial port losing data when several threads are active

Post 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
Post Reply