📄 storage - tinyos documentation wiki.htm
字号:
application requirement. Logged data should not be lost if a system crashes.
Logs can be either linear (stop logging when the volume is full) or circular
(overwrite the least recently written data when the volume is full). </P>
<P>The TinyOS LogStorage abstraction supports these requirements. The log is
record based: each call to LogWrite.append (see below) creates a new record. On
failure (a crash or power cycle), the log only loses whole records from the end
of the log. Additionally, once a circular log wraps around, log writes only lose
whole records from the beginning of the log. </P>
<P>A demo application called <CODE>PacketParrot</CODE> shows how to use the
<CODE>LogWrite</CODE> and <CODE>LogRead</CODE> abstractions. A node writes
received packets to a circular log and retransmits the logged packets (or at
least the parts of the packets above the AM layer) when power is cycled. </P>
<P>See <A class="external text"
title=http://www.tinyos.net/tinyos-2.x/apps/tutorials/PacketParrot/
href="http://www.tinyos.net/tinyos-2.x/apps/tutorials/PacketParrot/"
rel=nofollow><CODE>tinyos-2.x/apps/tutorials/PacketParrot/</CODE></A> for the
accompanying code. </P>
<P>The application logs packets it receives from the radio to flash. On a
subsequent power cycle, the application transmits any logged packets, erases the
log, and then continues to log packets again. The red LED is on when the log is
being erased. The blue (yellow) LED turns on when a packet is received and turns
off when a packet has been logged successfully. The blue (yellow) LED remains on
when packets are being received but are not logged (because the log is being
erased). The green LED flickers rapidly after a power cycle when logged packets
are transmitted. </P>
<OL>
<LI>The first step when using the log is to decide what kind of data you want
to store in the log. In this case, we will declare a struct of the type: <PRE> typedef nx_struct logentry_t {
nx_uint8_t len;
message_t msg;
} logentry_t;
</PRE>
<LI>Unlike Config storage, Log storage does not require the volume to be
explicitly mounted by the application. Instead, a simple read suffices in
which a buffer and the number of bytes to read are passed to
<CODE>LogRead.read</CODE>: <PRE> event void AMControl.startDone(error_t err) {
if (err == SUCCESS) {
if (call LogRead.read(&m_entry, sizeof(logentry_t)) != SUCCESS) {
// Handle error
}
}
else {
call AMControl.start();
}
}
</PRE>
<LI>If the call to <CODE>LogRead.read</CODE> returns SUCCESS, then a
<CODE>LogRead.readDone</CODE> event will be signaled shortly thereafter. When
that happens, we check if the data that was returned is the same length as
what we expected. If it is, we use the data but if not, we assume that either
the log is empty or that we have lost synchronization, so the log is erased: <PRE> event void LogRead.readDone(void* buf, storage_len_t len, error_t err) {
if ( (len == sizeof(logentry_t)) && (buf == &m_entry) ) {
call Send.send(&m_entry.msg, m_entry.len);
call Leds.led1On();
}
else {
if (call LogWrite.erase() != SUCCESS) {
// Handle error.
}
call Leds.led0On();
}
}
</PRE>
<LI>The <CODE>PacketParrot</CODE> application stores packets received over the
radio to flash by first saving the <CODE>message_t</CODE> and its length to a
<CODE>log_entry_t</CODE> struct and then calling <CODE>LogWrite.append</CODE>:
<PRE> event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len){
call Leds.led2On();
if (!m_busy) {
m_busy = TRUE;
m_entry.len = len;
m_entry.msg = *msg;
if (call LogWrite.append(&m_entry, sizeof(logentry_t)) != SUCCESS) {
m_busy = FALSE;
}
}
return msg;
}
</PRE>
<LI>If the <CODE>LogWrite.write</CODE> returned SUCCESS, then a short time
later, a <CODE>LogWrite.appendDone</CODE> will be signaled. This event returns
the details of the write including the source buffer, length of data written,
whether any records were lost (if this is a circular buffer) and any error
code. If no errors occurred, then the data was written to flash with
atomicity, consistency, and durability guarantees (and will survive node
crashes and reboots): <PRE> event void LogWrite.appendDone(void* buf, storage_len_t len,
bool recordsLost, error_t err) {
m_busy = FALSE;
call Leds.led2Off();
}
</PRE></LI></OL><A name=Storing_Large_Objects></A>
<H1><SPAN class=mw-headline>Storing Large Objects</SPAN></H1>
<P>Block storage is generally used for storing large objects that cannot easily
fit in RAM. Block is a low-level system interface that requires care when using
since it is essentially a write-once model of storage. Rewriting requires an
erase which is time-consuming, occurs at large granularity (e.g. 256 B to 64
KB), and can only happen a limited number of times (e.g. 10,000 to 100,000 times
is typical). The TinyOS network reprogramming system uses Block storage to store
program images. </P>
<P>See <A class="external text"
title=http://www.tinyos.net/tinyos-2.x/apps/tests/storage/Block/
href="http://www.tinyos.net/tinyos-2.x/apps/tests/storage/Block/"
rel=nofollow><CODE>tinyos-2.x/apps/tests/storage/Block/</CODE></A> for an
example of code that uses the Block storage abstraction. </P><A
name=Conclusions></A>
<H1><SPAN class=mw-headline>Conclusions</SPAN></H1>
<P>This lesson introduced the basic storage abstractions in Tiny 2.x. </P><A
name=Related_Documentation></A>
<H1><SPAN class=mw-headline>Related Documentation</SPAN></H1>
<OL class=references>
<LI id=_note-fn1><A title=""
href="http://docs.tinyos.net/index.php/Storage#_ref-fn1_0">↑</A> <A
class="external text"
title=http://www.tinyos.net/tinyos-2.x/doc/html/tep103.html
href="http://www.tinyos.net/tinyos-2.x/doc/html/tep103.html" rel=nofollow>TEP
103: Permanent Data Storage</A></LI></OL>
<P><A title="Getting Started with TinyOS"
href="http://docs.tinyos.net/index.php/Getting_Started_with_TinyOS">Getting
Started with TinyOS and nesC</A> <I>TinyOS Programming</I> </P>
<HR>
<CENTER>
<P>< <B><A title="Boot Sequence"
href="http://docs.tinyos.net/index.php/Boot_Sequence">Previous Lesson</A></B> |
<B><A title=""
href="http://docs.tinyos.net/index.php/Storage#Introduction">Top</A></B> | <B><A
title="Resource Arbitration and Power Management"
href="http://docs.tinyos.net/index.php/Resource_Arbitration_and_Power_Management">Next
Lesson</A> ></B> </P></CENTER><!-- Saved in parser cache with key tinyosdocs:pcache:idhash:13-0!1!0!!en!2!edit=0 and timestamp 20080401165604 -->
<DIV class=printfooter>Retrieved from "<A
href="http://docs.tinyos.net/index.php/Storage">http://docs.tinyos.net/index.php/Storage</A>"</DIV><!-- end content -->
<DIV class=visualClear></DIV></DIV></DIV></DIV>
<DIV id=column-one>
<DIV class=portlet id=p-cactions>
<H5>Views</H5>
<DIV class=pBody>
<UL>
<LI class=selected id=ca-nstab-main><A title="View the content page [c]"
accessKey=c href="http://docs.tinyos.net/index.php/Storage">Article</A>
<LI class=new id=ca-talk><A title="Discussion about the content page [t]"
accessKey=t
href="http://docs.tinyos.net/index.php?title=Talk:Storage&action=edit">Discussion</A>
<LI id=ca-viewsource><A
title="This page is protected. You can view its source. [e]" accessKey=e
href="http://docs.tinyos.net/index.php?title=Storage&action=edit">View
source</A>
<LI id=ca-history><A title="Past versions of this page. [h]" accessKey=h
href="http://docs.tinyos.net/index.php?title=Storage&action=history">History</A>
</LI></UL></DIV></DIV>
<DIV class=portlet id=p-personal>
<H5>Personal tools</H5>
<DIV class=pBody>
<UL>
<LI id=pt-login><A
title="You are encouraged to log in, it is not mandatory however. [o]"
accessKey=o
href="http://docs.tinyos.net/index.php?title=Special:Userlogin&returnto=Storage">Log
in / create account</A> </LI></UL></DIV></DIV>
<DIV class=portlet id=p-logo><A title="Visit the Main Page [z]"
style="BACKGROUND-IMAGE: url(/images/tos-jwall-small.jpg)" accessKey=z
href="http://docs.tinyos.net/index.php/Main_Page"></A></DIV>
<SCRIPT type=text/javascript> if (window.isMSIE55) fixalpha(); </SCRIPT>
<DIV class=portlet id=p-navigation>
<H5>Navigation</H5>
<DIV class=pBody>
<UL>
<LI id=n-mainpage><A title="Visit the Main Page [z]" accessKey=z
href="http://docs.tinyos.net/index.php/Main_Page">Main Page</A>
<LI id=n-portal><A
title="About the project, what you can do, where to find things"
href="http://docs.tinyos.net/index.php/TinyOS_Documentation_Wiki:Community_Portal">Community
portal</A>
<LI id=n-currentevents><A
title="Find background information on current events"
href="http://docs.tinyos.net/index.php/Current_events">Current events</A>
<LI id=n-recentchanges><A title="The list of recent changes in the wiki. [r]"
accessKey=r
href="http://docs.tinyos.net/index.php/Special:Recentchanges">Recent
changes</A>
<LI id=n-randompage><A title="Load a random page [x]" accessKey=x
href="http://docs.tinyos.net/index.php/Special:Random">Random page</A>
<LI id=n-help><A title="The place to find out."
href="http://docs.tinyos.net/index.php/Help:Contents">Help</A>
<LI id=n-sitesupport><A title="Support us"
href="http://docs.tinyos.net/index.php/TinyOS_Documentation_Wiki:Site_support">Donations</A>
</LI></UL></DIV></DIV>
<DIV class=portlet id=p-search>
<H5><LABEL for=searchInput>Search</LABEL></H5>
<DIV class=pBody id=searchBody>
<FORM id=searchform action=/index.php/Special:Search>
<DIV><INPUT id=searchInput title="Search TinyOS Documentation Wiki [f]"
accessKey=f name=search> <INPUT class=searchButton id=searchGoButton type=submit value=Go name=go> <INPUT class=searchButton id=mw-searchButton type=submit value=Search name=fulltext>
</DIV></FORM></DIV></DIV>
<DIV class=portlet id=p-tb>
<H5>Toolbox</H5>
<DIV class=pBody>
<UL>
<LI id=t-whatlinkshere><A title="List of all wiki pages that link here [j]"
accessKey=j
href="http://docs.tinyos.net/index.php/Special:Whatlinkshere/Storage">What
links here</A>
<LI id=t-recentchangeslinked><A
title="Recent changes in pages linked from this page [k]" accessKey=k
href="http://docs.tinyos.net/index.php/Special:Recentchangeslinked/Storage">Related
changes</A>
<LI id=t-upload><A title="Upload images or media files [u]" accessKey=u
href="http://docs.tinyos.net/index.php/Special:Upload">Upload file</A>
<LI id=t-specialpages><A title="List of all special pages [q]" accessKey=q
href="http://docs.tinyos.net/index.php/Special:Specialpages">Special pages</A>
<LI id=t-print><A title="Printable version of this page [p]" accessKey=p
href="http://docs.tinyos.net/index.php?title=Storage&printable=yes">Printable
version</A>
<LI id=t-permalink><A title="Permanent link to this version of the page"
href="http://docs.tinyos.net/index.php?title=Storage&oldid=674">Permanent
link</A> </LI></UL></DIV></DIV></DIV><!-- end of the left (by default at least) column -->
<DIV class=visualClear></DIV>
<DIV id=footer>
<DIV id=f-poweredbyico><A href="http://www.mediawiki.org/"><IMG
alt="Powered by MediaWiki"
src="Storage - TinyOS Documentation Wiki.files/poweredby_mediawiki_88x31.png"></A></DIV>
<UL id=f-list>
<LI id=lastmod>This page was last modified 01:03, 23 January 2008.
<LI id=viewcount>This page has been accessed 703 times.
<LI id=privacy><A title="TinyOS Documentation Wiki:Privacy policy"
href="http://docs.tinyos.net/index.php/TinyOS_Documentation_Wiki:Privacy_policy">Privacy
policy</A>
<LI id=about><A title="TinyOS Documentation Wiki:About"
href="http://docs.tinyos.net/index.php/TinyOS_Documentation_Wiki:About">About
TinyOS Documentation Wiki</A>
<LI id=disclaimer><A title="TinyOS Documentation Wiki:General disclaimer"
href="http://docs.tinyos.net/index.php/TinyOS_Documentation_Wiki:General_disclaimer">Disclaimers</A>
</LI></UL></DIV>
<SCRIPT type=text/javascript>if (window.runOnloadHook) runOnloadHook();</SCRIPT>
</DIV><!-- Served in 0.307 secs. --></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -