⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lesson4.html

📁 tinyos中文手册,是根据tinyos系统自带手册翻译过来的,虽然质量不好,但是对英文不强的人还是有用的
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<table border="0" cellspacing="2" cellpadding="3" width="80%" hspace="4">  <tbody>    <tr bgcolor="#e0e0e0">      <td width="100%"><b>IntToRfmM.nc</b>      <pre>&nbsp; bool pending;<br>&nbsp; struct TOS_Msg data;<br><br>&nbsp; /* ... */&nbsp;<br><br>&nbsp; command result_t IntOutput.output(uint16_t value) {<br>&nbsp;&nbsp;&nbsp; IntMsg *message = (IntMsg *)data.data;<br><br>&nbsp;&nbsp;&nbsp; if (!pending) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pending = TRUE;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message-&gt;val = value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; atomic {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; message-&gt;src = TOS_LOCAL_ADDRESS;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (call Send.send(TOS_BCAST_ADDR, sizeof(IntMsg), &amp;data))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return SUCCESS;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pending = FALSE;<br>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; return FAIL;<br>&nbsp; }</pre>      </td>    </tr>  </tbody></table></center><p>The command is using a message structure called <tt>IntMsg</tt>,declared in <tt>tos/lib/Counters/IntMsg.h</tt>. It is a simple structwith <tt>val</tt> and <tt>src</tt> fields; the first being the datavalue and the second being the message's source address. We assignthese two fields (using the global constant <tt>TOS_LOCAL_ADDRESS</tt>for the local source address) and call <tt>Send.send()</tt> with thedestination address (<tt>TOS_BCAST_ADDR</tt> is the radio broadcastaddress), the message size, and the message data. </p><p>The "raw" message data structure used by <tt>SendMsg.send()</tt> is <tt>structTOS_Msg</tt>, declared in <tt>tos/system/AM.h</tt>. It contains fieldsfor the destination address, message type (the AM handler ID), length,payload, etc. The maximum payload size is <tt>TOSH_DATA_LENGTH</tt> andis set to 29 by default; you are welcome to experiment with larger datapackets but some nontrivial hacking of the code may be required :-) Herewe are encapsulating an <tt>IntMsg</tt> within the data payload field ofthe <tt>TOS_Msg</tt> structure. </p><p>The <tt>SendMsg.send()</tt> command is split-phase; it signals the <tt>SendMsg.sendDone()</tt>event when the message transmission has completed. If <tt>send()</tt>succeeds, the message is queued for transmission, and if it fails, themessaging component was unable to accept the message. </p><p>TinyOS Active Message buffers follow a strict alternating ownershipprotocol to avoid expensive memory management, while still allowingconcurrent operation. If the message layer accepts the <tt>send()</tt>command, it owns the send buffer and the requesting component should notmodify the buffer until the send is complete (as indicated by the <tt>sendDone()</tt>event). </p><p><tt>IntToRfmM</tt> uses a <tt>pending</tt> flag to keep track of thestatus of the buffer. If the previous message is still being sent, wecannot modify the buffer, so we drop the <tt>output()</tt> operationand return <tt>FAIL</tt>. If the send buffer is available, we can fillin the buffer and send a message. <br>&nbsp;<table border="0" cellspacing="2" cellpadding="3" width="100%" hspace="4">  <tbody>    <tr bgcolor="#e0e0ff">      <td width="100%"><b><nobr><font face="arial,helvetica">TheGenericComm Network Stack</font></nobr></b></td>    </tr>  </tbody></table></p><p>Recall that <tt>IntToRfm</tt>'s <tt>SendMsg</tt> interface is wiredto <tt>GenericComm</tt>, a "generic" TinyOS network stackimplementation (found in <tt>tos/system/GenericComm.nc</tt>). If youlook at the <tt>GenricComm.nc</tt>, you'll see that it makes use of anumber of low-level interfaces to implement communication: <tt>AMStandard</tt>to implement Active Message sending and reception, <tt>UARTNoCRCPacket</tt>to communicate over the mote's serial port, <tt>RadioCRCPacket</tt> tocommunicate over the radio, and so forth. You don't need to understandall of the details of these modules but you should be able to followthe <tt>GenericComm.nc</tt> wiring configuration by now. </p><p>If you're really curious, check out <tt>AMStandard.nc</tt> for somedetails on how the ActiveMessage layer is built. For example, itimplements <tt>SendMsg.send()</tt> by posting a task to take themessage buffer and send it over the serial port (if the destinationaddress is <tt>TOS_UART_ADDR</tt> or the radio radio (if thedestination is anything else). You can dig down through the variouslayers of code until you see the mechanism that actually transmits abyte over the radio or UART.<table border="0" cellspacing="2" cellpadding="3" width="100%" hspace="4">  <tbody>    <tr bgcolor="#e0e0ff">      <td width="100%"><b><nobr><font face="arial,helvetica">ReceivingMessages with RfmToLeds</font></nobr></b></td>    </tr>  </tbody></table></p><p>The <tt>RfmToLeds</tt> application is defined by a simpleconfiguration that uses the <tt>RfmToInt</tt> component to receive amessage, and the <tt>IntToLeds</tt> component to display the receivedvalue on the LEDs. Like <tt>IntToRfm</tt>, the <tt>RfmToInt</tt>component uses <tt>GenericComm</tt> to receive messages. Most of <tt>RfmToInt.nc</tt>should be familiar to you by now, but look at the line: </p><pre>&nbsp; RfmToIntM.ReceiveIntMsg -&gt; GenericComm.ReceiveMsg[AM_INTMSG];</pre>This is how we specify that Active Messages received with the <tt>AM_INTMSG</tt>handler ID should be wired to the <tt>RfmToIntM.ReceiveMsg</tt>interface. The direction of the arrow might be a little confusing here.The <tt>ReceiveMsg</tt> interface (found in <tt>tos/interfaces/ReceiveMsg.nc</tt>)<b>only</b>declares an event: <tt>receive()</tt>, which is signaled with a pointerto the received message. So <tt>RfmToIntM</tt> <i>uses</i> the <tt>ReceiveMsg</tt>interface, although that interface does not have any commands to call --just an event that can be signaled.<p>Memory management for incoming messages is inherently dynamic. Amessage arrives and fills a buffer, and the Active Message layerdecodes the handler type and dispatches it. The buffer is handed to theapplication component (through the <tt>ReceiveMsg.receive()</tt>event), but, critically, <b>the application component must return apointer to a buffer upon completion</b>. </p><p>For example, looking at <tt>RfmToIntM.nc</tt>, </p><center><table border="0" cellspacing="2" cellpadding="3" width="80%" hspace="4">  <tbody>    <tr bgcolor="#e0e0e0">      <td width="100%"><b>RfmToIntM.nc</b>      <pre>&nbsp; /* ... */<br>&nbsp; event TOS_MsgPtr ReceiveIntMsg.receive(TOS_MsgPtr m) {<br>&nbsp;&nbsp;&nbsp; IntMsg *message = (IntMsg *)m-&gt;data;<br>&nbsp;&nbsp;&nbsp; call IntOutput.output(message-&gt;val);<br><br>&nbsp;&nbsp;&nbsp; return m;<br>&nbsp; }</pre>      </td>    </tr>  </tbody></table></center><p>Note that the last line returns the original message buffer, sincethe application is done with it. If your component needs to save themessage contents for later use, it needs to copy the message to a newbuffer, or return a new (free) message buffer for use by the networkstack.<table border="0" cellspacing="2" cellpadding="3" width="100%" hspace="4">  <tbody>    <tr bgcolor="#e0e0ff">      <td width="100%"><b><nobr><font face="arial,helvetica">UnderlyingDetails</font></nobr></b></td>    </tr>  </tbody></table></p><p>TinyOS messages contain a "group ID" in the header, which allowsmultiple distinct groups of motes to share the same radio channel. Ifyou have multiple groups of motes in your lab, you should set thegroup ID to a unique 8-bit value to avoid receiving messages for othergroups. The default group ID is <tt>0x7D</tt>. You can set the groupID by defining the preprocessor symbol <tt>DEFAULT_LOCAL_GROUP</tt>.</p><pre>&nbsp; DEFAULT_LOCAL_GROUP = 0x42&nbsp;&nbsp;&nbsp; # for example...</pre><p>Use the <tt><a href="buildenv.html">Makelocal</a></tt> file to setthe group ID for all your applications.</p><p>In addition, the message header carries a 16-bit destination node address. Each communicating node within a group is given a unique address assigned at compile time.&nbsp; Two common reserved destination addresses we've introduced thus far are <tt>TOS_BCAST_ADDR (0xfff)</tt> to broadcast to all nodes or <tt>TOS_UART_ADDR (0x007e)</tt> to send to the serial port. </p><p>The node address may be any value EXCEPT the two reserved values described above.&nbsp; To specify the local address of your mote, use the following install syntax: </p><pre>&nbsp; make mica install.&lt;addr&gt;</pre>where <i>&lt;addr&gt;</i> is the local node ID that you wish to programinto the mote.&nbsp; For example,<pre>&nbsp; make mica install.38</pre>compiles the application for a mica and programs the mote with ID 38. Read<a href="programmers.html">Programming Devices</a> for additional information.<table border="0" cellspacing="2" cellpadding="3" width="100%" hspace="4">  <tbody>    <tr bgcolor="#e0e0ff">      <td width="100%"><b><nobr><font face="arial,helvetica">Exercises</font></nobr></b></td>    </tr>  </tbody></table><ol>  <li> Question: What would happen if you built multiple <tt>CntToLedsAndRfm</tt>nodes and turned them on?</li>  <li> Program one mote with <tt>CntToLedsAndRfm</tt> and another with <tt>RfmToLeds</tt>.When you turn on <tt>CntToLedsAndRfm</tt>, you should see the countdisplayed on the <tt>RfmToLeds</tt> device. Congratulations - you aredoing wireless networking. Can you change this to implement a wirelesssensor? (Hint: Check out <tt><a href="../../apps/SenseToRfm">apps/SenseToRfm</a></tt>.)</li></ol><hr><b><a href="lesson3.html">&lt; Previous Lesson</a></b> | <b><a href="lesson5.html">Next Lesson &gt;</a></b> | <b><a href="index.html">Top</a></b></body></html><!--  LocalWords:  TinyOS nesC nc async norace BlinkM FooM ncc SingleTimer Leds --><!--  LocalWords:  LedsC StdControl tos init TimerC redOn redOff uint redToggle --><!--  LocalWords:  metadata html nesdoc gcc exe avr objcopy srec uisp mib dprog --><!--  LocalWords:  towards dapa xff ThinkPad dlpt Makelocal micasb Wshadow DDEF --><!--  LocalWords:  finline fnesc cfile lm Atmel ATmega nesC's nesc SenseM rdata --><!--  LocalWords:  ADCControl SounderControl dataReady getData rcombine someval --><!--  LocalWords:  ADControl fooControl barControl MyTimer uniqueCount basicsb --><!--  LocalWords:  sensorboard Makerules sensorboards SenseTask taskname INTMSG --><!--  LocalWords:  SenseTaskM putdata processData CntToLedsAndRfm RfmToLeds Msg --><!--  LocalWords:  CntToRfmAndLeds IntToLeds IntToRfm IntOutput outputComplete --><!--  LocalWords:  IntToRfmM GenericComm SendMsg bool struct IntMsg src BCAST --><!--  LocalWords:  ADDR sizeof TOSH sendDone GenricComm AMStandard RfmToInt --><!--  LocalWords:  UARTNoCRCPacket RadioCRCPacket ActiveMessage RfmToIntM xfff --><!--  LocalWords:  ReceiveIntMsg ReceiveMsg MsgPtr addr SenseToRfm -->

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -