[En-Nut-Discussion] Best way to implement a time-critical RS485driver
Olof Tångrot
olof.tangrot at telia.com
Fri Sep 2 13:19:04 CEST 2005
What it the nature of the trouble with avr-gcc you have heard of?
----- Original Message -----
From: <Christian.Schilmoeller at camco.de>
To: <en-nut-discussion at egnite.de>
Sent: Friday, September 02, 2005 12:09 PM
Subject: [En-Nut-Discussion] Best way to implement a time-critical
RS485driver
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?
_______________________________________________
En-Nut-Discussion mailing list
En-Nut-Discussion at egnite.de
http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion
More information about the En-Nut-Discussion
mailing list