All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai] rt_dev_write returns immediately on xeno_16550A
@ 2013-01-24  3:31 Doug Brunner
  2013-01-24  8:43 ` Wolfgang Grandegger
  2013-01-24  8:55 ` Jan Kiszka
  0 siblings, 2 replies; 5+ messages in thread
From: Doug Brunner @ 2013-01-24  3:31 UTC (permalink / raw)
  To: xenomai

I have a 16550A UART (actually 1/4 of a TI TL16C554) on the ISA bus on 
my WinSystems PPM-LX800-G SBC, and I'm finding that rt_dev_write returns 
control to the userspace process much earlier than I would expect, given 
how the kernel module is set up. (I'm using Xenomai 2.6.1 btw.) 
Fortunately it has a dedicated IRQ line, so I was able to put a logic 
analyzer on the IRQ, the TX line, and the RTS line (which my software 
manually controls to operate an RS485 transceiver).

I initially found that, with the TX FIFO size allowed to default to 16 
bytes, rt_dev_write with a block of size 13 returns immediately. (I 
could tell this because my userspace routine sets RTS just before 
calling rt_dev_write and clears RTS immediately after, so it was visible 
on the logic analyzer.) This makes sense, because I could see that the 
16C554 fires an IRQ immediately on the start of transmission (that 
violates the description of the TX IRQ in its datasheet, but that's a 
matter for TI). This would lead into rt_16550_interrupt, which would see 
that ctx->out_npend == 0 because the data was written to the FIFO in one 
go, and consequently fire out_event. The TX timeout was configured for 
100 ms, so rt_16550_write would be waiting on out_event, and 
rt_dev_write would return at that time.

However...I tried setting the TX FIFO to 1 byte via xeno_16550A module 
parameter, and found that rt_dev_write still returned almost 
immediately. This is what I don't understand, since I could see data 
being transmitted, and the IRQ line going high once for every byte. This 
means that rt_16550_interrupt MUST be getting called, and in turn 
calling rt_16550_tx_interrupt to move data out to the UART. For 
rt_16550_tx_interrupt to be doing so, out_npend must != 0, so out_event 
should not be getting fired until the very last character.

I did notice something odd: at the beginning of rt_16550_write, we 
initialize timeout_seq with ctx->config.rx_timeout. Later that timeout 
sequence is reused while waiting on out_event, which is naturally 
subject to ctx->config.tx_timeout. This seems like a possible source of 
error if tx and rx timeout are not equal--I didn't study the internal 
implementation of the timeout sequence so I'm not sure. However, I tried 
changing the references from rx_timeout to tx_timeout and it produced no 
change in behavior.

Do you know why rt_dev_write would be returning prematurely? I've 
attached the relevant userspace code snippets for reference. Note that 
RawInterface is a subclass of Interface, and higher level code will call 
RawInterface::Write.

-- 
     Doug Brunner

-------------- next part --------------
A non-text attachment was scrubbed...
Name: rt-16550a-snippet.cpp
Type: text/x-c++src
Size: 2784 bytes
Desc: not available
URL: <http://www.xenomai.org/pipermail/xenomai/attachments/20130123/d5da87ef/attachment.cpp>

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-24  9:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-24  3:31 [Xenomai] rt_dev_write returns immediately on xeno_16550A Doug Brunner
2013-01-24  8:43 ` Wolfgang Grandegger
2013-01-24  9:21   ` Wolfgang Grandegger
2013-01-24  9:32     ` Wolfgang Grandegger
2013-01-24  8:55 ` Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.