[En-Nut-Discussion] Best way to implement a time-critical RS485 driver

Christian.Schilmoeller at camco.de Christian.Schilmoeller at camco.de
Fri Sep 2 12:09:12 CEST 2005


Hello!

I would be glad to hear an advice of some experienced (Ethernut-) 
programmers concerning the following problem: I have to implement a 
half-dupex, 250kBaud RS485 driver which has to obey special timing 
requirements. The timing resolution is much finer than the NutOS system 
timers, e. g. a timeout value of 150 microseconds when a byte is to be 
received. There has to be also a generation of a well-defined break signal 
and a short (~10µS) switching delay when the data direction changes.
I've already found a solution that works and fulfills the timing 
requirements. But I am looking for a better one, because I find the 
solution very ugly, hard to read and to maintain.
It consists of a state machine which is spread across four (!) interrupt 
handers (uart receive, uart data register empty, uart transmit complete, 
timer overflow). When the state machine reaches a "final" state - 
(transaction done or error condition), it wakes up a thread via 
"NutEventPostFromIrq()" which waits for this by "NutEventWaitNext()".
I have an idea about an alternative solution, but I don't know if it is 
more reasonable or handy. It might look like this:
The state machine is replaced by a piece of plain code which runs as a 
thread with high priority. When the thread waits for completion of uart 
actions (or time delays), it always calls "NutEventWaitNext()" on certain 
event queues.
Each irq handler then consists only of a short piece of code which copies 
data that has to be saved (e. g. UDR register) into a global variable and 
then calls "NutEventPostFromIrq()".
The advantage would be to get rid of the rather complex state machine and 
to replace it by "linear" code (the "state variable" would be the program 
counter then). But I'm afraid that the disadvantage would be a huge 
overhead of complete thread switches which are triggered by the irq 
handlers.
>From the experts' point of view, which solutions is preferable? Maybe 
there is a better, third solution? Any help or comments would be 
appreciated!

Christian

P.S.: I've heard that the C compiler (I'm using WinAVR) generally runs 
into trouble when functions are called inside irq handlers. Is there a way 
of saving unnecessary push/pop cyles if I replace the 
"NutEventPostFromIrq()" function by a macro which does the same?



More information about the En-Nut-Discussion mailing list