Let me take a stab at clarification
or obtusification as the case may be....
The GenericComm send() method is non-blocking. It returns "right" away
after posting the buffer for lower-level interrupt driven sending. I'm
not sure if the buffer is copied (probably not). You are notified when
the send is done/failed by a callback to your sendDone() method. At that
point it is safe to reuse your buffer.
If you try to send another message before the first is finished I believe
the send() method will return a FAIL. So you should always trigger
subsequent message sends from the sendDone(), or invent some flurry
of semaphores to the same effect.
I also believe that there is a fixed set of receive buffers, but getting
to the actual ground truth would require the RTFC techniques you seem to
dislike. I do know that the msg buffer handed to you in a receive()
belongs to you until you return it as the receive() rval.
If the lower-level gets another message in the meantime it will use a
different buffer. If you wish to save the message (e.g., to post to
another task) you should copy it before the receive() returns. I guess
this means that you can overrun the buffer pool at some point if you
don't process fast enough...
The reason (perhaps) that your code fragment works only sometimes is that
you are sending the msg buffer and then returning it, which releases it
to the system for reuse. It would be 'better' to post a task to do the
processing and call the send() -- because you are running in the moral
equivalent of an interrupt routine in receive(). In either case you
need to copy the msg into a new buffer so it doesn't get walked on before
you are done with it.
Unfortunately most of the doc _is_ the code, with added help list opinions
and some guidance from the tutorial...It shore woulda bean nice if the UCB
header format required a module description in addition to the three pages
of copywrong information...
MS
Muthiah Annamalai wrote:
I have already posted this question before but havent got any
satisfactory
replies. Everyone seems to say to dig through the various layers of
code and figure it out. I need to know how the radio works on the MICA2 motes.
Please read the tutorial in the tinyos-1.x/doc/ directory.
I think TinyOS tutorial is one of the best written, contrary
to what you say or think.
1. From the tutorial, it seems that the send buffer is 1 packet wide.
Can someone explain how exactly the send() command of GenericComm works. IS
it a blocking or non blocking send?
Send command is non-blocking. Which is how most of TinyOS
is written like an event-drive system.
What happens if i try to send packet2
while packet1 is still being transmitted?
You get a SUCCESS or FAIL when from your 'call Radio.SendMsg()'
depending on the conditions. Generally it will result
in failure, and you may
need to wait for the SendDone() event
before you transmit the next packet. Which is why,
one should use Queues to do the transmission, as explained
in various tutorial examples like /apps/TOSBase/
Does the lower layer protocol take care of collisions etc
I dont think so.
2. The same doubt is with receive. How big is the receivers buffer?
If you use the default TinyOS AM stack, it is 29 bytes
for your payload. For more payload size hackyour way.
What happens if I am inside a receive() event, processing packet1 and
packet2's receive event is triggered. Will my one-packet size buffer be
overwriiten?
Again this question is well answered in the Tutorial.
You need to do processing withing 'tasks'. See the example
on OscilloscopeRF/.
Can I do something like this in my code
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr msg)
{
/* extract the payload
field, AnchorXY is my custom defined
packet, i
know for sure this event is triggered on receiving a packet of this
type */
> struct AnchorXY *q = (AnchorXY*)(msg -> data);
/* do some processing on this data.... call a local function
process()
*/
process(*q);
/* Multi-hop this message */
call SendMsg.send(TOS_BCAST_ADDR, sizeof(struct AnchorXY), msg);
return msg;
}
you should do this whole thing as a task. Read more about
how tasks dont interrupt each other, and how they are
queued etc, in the tutorial.
Basically you code must be more like:
task void processData()
{
/* do Yada Yada */
call Radio.SendMsg(... )
}
event TOS_MsgPtr ReceiveMsg.receive(TOS_MsgPtr msg)
{
struct AnchorXY *q = (AnchorXY*)(msg -> data);
SWAP_OLD_AND_NEW_BUFFERS(q,old);
COPY_OLD_TO_YOUR_Q(old);
post processData();
return msg;
}
The above code is sometimes working sometimes not. I suspect its
because the
send() command is non blocking therefore msg is returned to TinyOS
before it
is sent over the radio. Now maybe the buffer is getting overwritten
with
next received packet and that is why some packets are not getting sent.
Is
my reasoning right?
Dont know, but it can cause race conditions and lots of
runtime [unwanted]magic.
Hope you have some time to read the tutorial before asking
questions.
------------------------------------------------------------------------
Yahoo! Mail goes everywhere you do. Get it on your phone
<http://us.rd.yahoo.com/evt=31132/*http://mobile.yahoo.com/services?promote=mail>.
------------------------------------------------------------------------
_______________________________________________
Tinyos-help mailing list
[email protected]
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
_______________________________________________
Tinyos-help mailing list
[email protected]
https://mail.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help