[Tinyos-devel] Proposed change to the serial stack in TinyOS 2
Ben Greenstein
bengreenstein at gmail.com
Thu Dec 14 15:12:29 PST 2006
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();
}
More information about the Tinyos-devel
mailing list