[Tinyos-devel] Proposed change to the serial stack in TinyOS 2

Adler, Robert P robert.p.adler at intel.com
Fri Dec 15 09:05:53 PST 2006


Before this discussion goes too far, it might be wise to consider the
necessity of the conversation in the first place.  The original question
assumed the existance of UARTs that don't follow the 16*50 UART
convention that an interrupt event is signalled when the device requires
more data so that it can continue sending.  Do such devices exist?  If
they do, I would think that you would need a different interface in
order to properly interface with them in the first place (since, chances
are that they change more than just this one semantic).  At the same
time, the 16*50 UART is soooo old that the chances of it ever changing
are pretty low so it's not unreasonable to make a UART specific
interface and driver subsystem and to forget about trying to accommodate
chips that will most likely never exist.

As originally pointed out, signalling an interrupt when the port is
ready for more data and not when it is done sending its data is
definitely the behavior, and if you are too aggressive with your power
management you can turn off the port before it is done sending out all
of its data.  However, how to answer this question somewhat depends on
how TOS2 expects to be doing power management.  If it's up to each
component to always do its best to minimize power consumption, then what
Michael talks about below is most of the answer, but it will still need
to be augmented by some sort of "isflushed" command so that upper layer
components can determine if the UART is actually done sending (since
this seemed to be part of the reason for the discussion in the first
place).  However, if the system is architected so that it controls power
state to all components, then the other "waitForFlush" command ideas are
more appropriate anyway.  Finally, for whoever implements this, please
don't make waitForFlush Async...it absolutely can not be done in IRQ
context or you will destroy your interrupt handling time.  While the
MSP430 might have a 1 entry deep FIFO, the PXA27x has a 64 entry deep
fifo and how much time you will have to wait depends on how many bytes
you last wrote to the fifo, system bus latency/throughput, etc, and I'm
sure that there are other processors out there that will have other size
fifos.  If this "waitForFlush" ever happens in IRQ context, you can
potentially wait 100's of us just to have this one interrupt
complete...which is obviously really, really bad.

As for the original question:  I agree with most of the other posters
that 4.) is probably the best.  However, I'm not sure how much concern
the power consumption statement really is.  While it depends on the
specific processor architecture, I would imagine that having the
processor go into a low power state when its UART is still actively
sending data out might be bad anyway...but, as I said, the right thing
to do for absolute lower power really depends on the processor.

-Robbie



-----Original Message-----
From: tinyos-devel-bounces at Millennium.Berkeley.EDU
[mailto:tinyos-devel-bounces at Millennium.Berkeley.EDU] On Behalf Of
Michael Newman
Sent: Thursday, December 14, 2006 8:13 PM
To: 'Ben Greenstein'; tinyos-devel at Millennium.Berkeley.EDU
Subject: RE: [Tinyos-devel] Proposed change to the serial stack in
TinyOS 2

I wonder about the necessity of the interface knowing when the usart is
truly idle. 

It seems to me that the higher layers should not be allowed to know and
should not care. Exposing this knowledge is exposing lower level
hardware
details that should be kept hidden.

The example of powering down the usart is a good one. The knowledge
about
when the power down can be done is necessary but should be kept in the
lower
level code that is part of the UART abstraction. The lower level code
can
poll or inspect the state and decide when the hardware truly goes idle
and
power it off as needed. It can schedule a timer or poll in some
non-blocking
way (post a task).

Expecting the higher level code to handle problems of this kind is
making
the abstraction impure and will only lead to problems later when some
new
piece of hardware requires a more complex shutdown procedure.

Note also that the semantics of idle and the associated test are
important.
The exposed test should not tell if the hardware is idle but should
carry
the same semantics as the putDone event: the interface is ready to
accept
another byte.

-----Original Message-----
From: tinyos-devel-bounces at Millennium.Berkeley.EDU
[mailto:tinyos-devel-bounces at Millennium.Berkeley.EDU] On Behalf Of Ben
Greenstein
Sent: Thursday, December 14, 2006 6:12 PM
To: tinyos-devel at Millennium.Berkeley.EDU
Subject: [Tinyos-devel] Proposed change to the serial stack in TinyOS 2

I'm sending this email to gather feedback about a proposed addition to
the serial stack.

There are situations (such as when powering down the usart, when
switching from TX to RX on a radio with a UART data line, etc.) when
we need explicit information that the data sent over the UART has
actually been transmitted in full. The problem is that on MCUs that
double-buffer UART communication (such as the msp430) a putDone event
signifies that the UART is ready to accept another byte, but NOT that
the UART is idle. Moreover, idleness (when TX is empty) is exposed as
a flag that can be polled, but not as a HW interrupt.

The TinyOS 2 Core Working Group members have considered various
proposals for how to notify higher layers (above HPL) of when a
transmission is really complete and have reached some consensus on a
fix. I'll briefly describe the options we came up with and then go
into our proposed solution.

1) One can push a dummy byte at the end of the transmission, to flush
the real data out, and use the putDone after the dummy byte as
indication that the real data has been sent. This is probably the
lowest-latency solution. Unfortunately, however, some of the dummy
info will leak on the line, so the other side has to be able to safely
ignore this garbage. (All possible higher layers must have logic to
ignore this dummy byte when received.)

2) In the HAL, one could spin until the idle flag is asserted before
signalling putDone. This is the simplest interface and it places the
logic in the HAL so the HIL doesn't need to worry about it. The
downside is its obvious inefficiency as it effectively annihilates the
benefits of double buffering.

3) One could add a parameter to the HAL-level put() that signifies
that putDone shouldn't come until the UART is idle. This has the
benefit of only incurring the cost of spinning when needed, but is
confusing, as no one aside from the user of put() can check for
idleness.

Our proposed solution is the following:

4) Add a split-phase query interface to the HAL with the command
wait(). This interface would implement a task-level spin (so that it
is interruptable) and would signal waitDone() when the idle flag is
asserted. The downside of this interface is that it still relies on a
spin, which consumes extra energy as the processor will not enter a
sleep state while waiting.

interface Wait {
 async command void wait();
 async event void waitDone();
}
_______________________________________________
Tinyos-devel mailing list
Tinyos-devel at Millennium.Berkeley.EDU
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-dev
el

_______________________________________________
Tinyos-devel mailing list
Tinyos-devel at Millennium.Berkeley.EDU
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-dev
el



More information about the Tinyos-devel mailing list