<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://anrg.usc.edu/contiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shanpei</id>
		<title>Contiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://anrg.usc.edu/contiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Shanpei"/>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php/Special:Contributions/Shanpei"/>
		<updated>2026-07-18T18:35:42Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.26.2</generator>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=394</id>
		<title>Meeting Logs</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=394"/>
				<updated>2014-04-11T23:44:13Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* Apr/04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Feb/7 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Professor Bhaskar gave us his wishlist. See a brief outline at [[Wishlist]].&lt;br /&gt;
&lt;br /&gt;
We got the Contiki oscilloscope up and running, and played around with it using two motes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Suvil is going to investigate options for a mailing list and also get the issue with uploading images to the wiki fixed.&lt;br /&gt;
&lt;br /&gt;
Nikhil will set up a Google Drive share for us to use for prototyping our tutorials when appropriate. It would allow for us to collaboratively edit in real-time and provide us all the conveniences of a modern word processor (spell check, etc.) We should probably discuss this more next time.&lt;br /&gt;
&lt;br /&gt;
Yash will spend the time catching up and going through our existing tutorials.&lt;br /&gt;
&lt;br /&gt;
Lakshmi has graciously volunteered to present Cristian&amp;#039;s algorithm to us.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will start a new tutorial for using the Oscilloscope.&lt;br /&gt;
&lt;br /&gt;
Kevin will explore methods for on-board data storage on the sky mote, both volatile and non-volatile.&lt;br /&gt;
&lt;br /&gt;
Pedro, Suvil, and Kwame will work on running Contiki on the testbed and starting a tutorial. Also, thinking about how we can refactor some of our theoretical tutorials to be more activity oriented.&lt;br /&gt;
&lt;br /&gt;
Everyone should update their tutorials to include the primary contributors. Perhaps somewhere at the end.&lt;br /&gt;
&lt;br /&gt;
== Feb/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Pedro&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Lakshmi presented the paper [[Probabilistic Clock Synchronization http://kom.aau.dk/~rlo/lectures/algoAndArchIII_2009/ChristiansAlgorithm.pdf]]. We had a very interesting discussion about the terms and concepts behind synchronization and clock in network nodes. We might in the future see how this algorithm can be implemented in a WSN or check whether its main ideas are already implemented in the &amp;quot;Implicit network time synchronization&amp;quot;, present in ContikiOS ([http://contiki.sourceforge.net/docs/2.6/a01741.html])&lt;br /&gt;
&lt;br /&gt;
Everyone gave an updated about what have been done during last week. We have some material for two tutorials: the &amp;#039;&amp;#039;Oscilloscope&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Coffee File System&amp;#039;&amp;#039;. This material is yet in the Google Doc create for prototyping and should be posted in the Wiki soon.&lt;br /&gt;
&lt;br /&gt;
Kwame guided the group in the first 4 sessions of ContikiOS Crash Course [[File:Seniot09cccc-notes.pdf]]. We played with LEDs and push button. This example should give a new tutorial on how to use all the sensors/actuators (light, temperature, push button, etc.) on the motes.&lt;br /&gt;
&lt;br /&gt;
We decided that each week one person will be responsible for creating this meeting log, so everyone can keep track of what has been discussed every week. Below we have the expected date of our next meetings and a tentative assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin will give a brief talk about Coffee file system and show us the material he obtained and the tutorial he started to write.&lt;br /&gt;
&lt;br /&gt;
Yash will start to study and collect material about processes and protothreads. He may give a talk about these topics in two weeks.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will keep working on the Oscilloscope tutorial.&lt;br /&gt;
&lt;br /&gt;
Pedro and Kwame will start to work on the Tutornet testbed.&lt;br /&gt;
&lt;br /&gt;
Suvil will fix some issues we are facing in the Wiki with code formatting and help us with account creation/setup of the testbed.&lt;br /&gt;
&lt;br /&gt;
== Feb/21 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Suvil&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin gave a presentation about Coffee File System. He showed the main interface and functions that can be used by Tmote Sky. He also showed an example where a node was programmed to create and write 3 different files on Flash Memory and after reboot output the content of the files reading then from the memory. The presentation slides can be found here:[] and the example code can be found here:[]. He started to create a tutorial on Coffee on the shared Doc file and you may create a tutorial about this topic in our Wiki soon.&lt;br /&gt;
&lt;br /&gt;
We went through the example in: examples/rime/example-neighbors.c, suggested by Bhavana. Basically this example makes all node generate beacons and create a list of neighbors of each node. It prints out the list of neighbors with the corresponding RSSI value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We should continue to work on the tutorials, trying to polish and review them for final publication.&lt;br /&gt;
&lt;br /&gt;
== Feb/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Leo&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pedro gave a presentation of a few of the features available in the Cooja simulator. Some of what he covered, which will be put in the Cooja tutorial, includes how to build Cooja from the terminal and automatically start a simulation, locate source files for debugging, and use the single-step and breakpoint debugging tools available for debugging each node. Afterwards, we looked at examples-neighbors.c in more detail, noting the size of the data structures and the way certain values were calculated, such as RSSI. Lastly, we briefly looked over some of the Contiki OS files in the documentation and flipped through a comprehensive Contiki presentation here [http://www.ee.kth.se/~mikaelj/wsn_course/contiki-course-kth-9oct2008-draft.pdf].&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Several more tutorials should be done by our next meeting.&lt;br /&gt;
&lt;br /&gt;
== Mar/07 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Nikhil&lt;br /&gt;
&lt;br /&gt;
== Mar/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash gave a presentation on Processes and Protothreads. The group expressed interest in learning more about the hardware behind the Tmote Sky, such as the TI MSP430 microprocessor and the CC2420 radio. We&amp;#039;ll probably include some of those as the topic of future talks.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Enjoy Spring Break!&lt;br /&gt;
&lt;br /&gt;
== Mar/21 ==&lt;br /&gt;
&lt;br /&gt;
Spring Break, no meeting&lt;br /&gt;
&lt;br /&gt;
== Mar/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Deepanker&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We successfully programmed a multi-hop communication between 5 motes. We also discussed the ways in which motes can talk to each other, namely - unicast, multicast and reliable unicast - and discussed the pros and cons of each with respect to our application.&lt;br /&gt;
&lt;br /&gt;
We discussed a little bit about the connections on the mote, specifically the interaction of MSP430 with CC2420.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash will give an introduction to MSP430. Completion of tutorials on wiki and proofreading of the already completed will be done by the people who are assigned the task.&lt;br /&gt;
&lt;br /&gt;
== Apr/04 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kevin&lt;br /&gt;
Bhavana introduced us how to use Shell in a process. We went through some instructions and source code to understand how it works. Also, we ran an example on the Sky-Mote and tried the Blink instruction. Everything worked good.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Yash will give an introduction to MSP430.&lt;br /&gt;
&lt;br /&gt;
== Apr/11 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Timothy&lt;br /&gt;
&lt;br /&gt;
== Apr/18 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Bhavana&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=393</id>
		<title>Meeting Logs</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=393"/>
				<updated>2014-04-11T23:43:11Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* Apr/04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Feb/7 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Professor Bhaskar gave us his wishlist. See a brief outline at [[Wishlist]].&lt;br /&gt;
&lt;br /&gt;
We got the Contiki oscilloscope up and running, and played around with it using two motes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Suvil is going to investigate options for a mailing list and also get the issue with uploading images to the wiki fixed.&lt;br /&gt;
&lt;br /&gt;
Nikhil will set up a Google Drive share for us to use for prototyping our tutorials when appropriate. It would allow for us to collaboratively edit in real-time and provide us all the conveniences of a modern word processor (spell check, etc.) We should probably discuss this more next time.&lt;br /&gt;
&lt;br /&gt;
Yash will spend the time catching up and going through our existing tutorials.&lt;br /&gt;
&lt;br /&gt;
Lakshmi has graciously volunteered to present Cristian&amp;#039;s algorithm to us.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will start a new tutorial for using the Oscilloscope.&lt;br /&gt;
&lt;br /&gt;
Kevin will explore methods for on-board data storage on the sky mote, both volatile and non-volatile.&lt;br /&gt;
&lt;br /&gt;
Pedro, Suvil, and Kwame will work on running Contiki on the testbed and starting a tutorial. Also, thinking about how we can refactor some of our theoretical tutorials to be more activity oriented.&lt;br /&gt;
&lt;br /&gt;
Everyone should update their tutorials to include the primary contributors. Perhaps somewhere at the end.&lt;br /&gt;
&lt;br /&gt;
== Feb/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Pedro&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Lakshmi presented the paper [[Probabilistic Clock Synchronization http://kom.aau.dk/~rlo/lectures/algoAndArchIII_2009/ChristiansAlgorithm.pdf]]. We had a very interesting discussion about the terms and concepts behind synchronization and clock in network nodes. We might in the future see how this algorithm can be implemented in a WSN or check whether its main ideas are already implemented in the &amp;quot;Implicit network time synchronization&amp;quot;, present in ContikiOS ([http://contiki.sourceforge.net/docs/2.6/a01741.html])&lt;br /&gt;
&lt;br /&gt;
Everyone gave an updated about what have been done during last week. We have some material for two tutorials: the &amp;#039;&amp;#039;Oscilloscope&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Coffee File System&amp;#039;&amp;#039;. This material is yet in the Google Doc create for prototyping and should be posted in the Wiki soon.&lt;br /&gt;
&lt;br /&gt;
Kwame guided the group in the first 4 sessions of ContikiOS Crash Course [[File:Seniot09cccc-notes.pdf]]. We played with LEDs and push button. This example should give a new tutorial on how to use all the sensors/actuators (light, temperature, push button, etc.) on the motes.&lt;br /&gt;
&lt;br /&gt;
We decided that each week one person will be responsible for creating this meeting log, so everyone can keep track of what has been discussed every week. Below we have the expected date of our next meetings and a tentative assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin will give a brief talk about Coffee file system and show us the material he obtained and the tutorial he started to write.&lt;br /&gt;
&lt;br /&gt;
Yash will start to study and collect material about processes and protothreads. He may give a talk about these topics in two weeks.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will keep working on the Oscilloscope tutorial.&lt;br /&gt;
&lt;br /&gt;
Pedro and Kwame will start to work on the Tutornet testbed.&lt;br /&gt;
&lt;br /&gt;
Suvil will fix some issues we are facing in the Wiki with code formatting and help us with account creation/setup of the testbed.&lt;br /&gt;
&lt;br /&gt;
== Feb/21 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Suvil&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin gave a presentation about Coffee File System. He showed the main interface and functions that can be used by Tmote Sky. He also showed an example where a node was programmed to create and write 3 different files on Flash Memory and after reboot output the content of the files reading then from the memory. The presentation slides can be found here:[] and the example code can be found here:[]. He started to create a tutorial on Coffee on the shared Doc file and you may create a tutorial about this topic in our Wiki soon.&lt;br /&gt;
&lt;br /&gt;
We went through the example in: examples/rime/example-neighbors.c, suggested by Bhavana. Basically this example makes all node generate beacons and create a list of neighbors of each node. It prints out the list of neighbors with the corresponding RSSI value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We should continue to work on the tutorials, trying to polish and review them for final publication.&lt;br /&gt;
&lt;br /&gt;
== Feb/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Leo&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pedro gave a presentation of a few of the features available in the Cooja simulator. Some of what he covered, which will be put in the Cooja tutorial, includes how to build Cooja from the terminal and automatically start a simulation, locate source files for debugging, and use the single-step and breakpoint debugging tools available for debugging each node. Afterwards, we looked at examples-neighbors.c in more detail, noting the size of the data structures and the way certain values were calculated, such as RSSI. Lastly, we briefly looked over some of the Contiki OS files in the documentation and flipped through a comprehensive Contiki presentation here [http://www.ee.kth.se/~mikaelj/wsn_course/contiki-course-kth-9oct2008-draft.pdf].&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Several more tutorials should be done by our next meeting.&lt;br /&gt;
&lt;br /&gt;
== Mar/07 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Nikhil&lt;br /&gt;
&lt;br /&gt;
== Mar/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash gave a presentation on Processes and Protothreads. The group expressed interest in learning more about the hardware behind the Tmote Sky, such as the TI MSP430 microprocessor and the CC2420 radio. We&amp;#039;ll probably include some of those as the topic of future talks.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Enjoy Spring Break!&lt;br /&gt;
&lt;br /&gt;
== Mar/21 ==&lt;br /&gt;
&lt;br /&gt;
Spring Break, no meeting&lt;br /&gt;
&lt;br /&gt;
== Mar/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Deepanker&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We successfully programmed a multi-hop communication between 5 motes. We also discussed the ways in which motes can talk to each other, namely - unicast, multicast and reliable unicast - and discussed the pros and cons of each with respect to our application.&lt;br /&gt;
&lt;br /&gt;
We discussed a little bit about the connections on the mote, specifically the interaction of MSP430 with CC2420.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash will give an introduction to MSP430. Completion of tutorials on wiki and proofreading of the already completed will be done by the people who are assigned the task.&lt;br /&gt;
&lt;br /&gt;
== Apr/04 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kevin&lt;br /&gt;
Bhavana introduced us how to use Shell in a process. We went through some instructions and source code to understand how it works. Also, we ran an example on the Sky-Mote and tried the Blink instruction. Everything worked good.&lt;br /&gt;
&lt;br /&gt;
== Apr/11 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Timothy&lt;br /&gt;
&lt;br /&gt;
== Apr/18 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Bhavana&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=392</id>
		<title>Meeting Logs</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=392"/>
				<updated>2014-04-11T17:53:17Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* Apr/04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Feb/7 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Professor Bhaskar gave us his wishlist. See a brief outline at [[Wishlist]].&lt;br /&gt;
&lt;br /&gt;
We got the Contiki oscilloscope up and running, and played around with it using two motes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Suvil is going to investigate options for a mailing list and also get the issue with uploading images to the wiki fixed.&lt;br /&gt;
&lt;br /&gt;
Nikhil will set up a Google Drive share for us to use for prototyping our tutorials when appropriate. It would allow for us to collaboratively edit in real-time and provide us all the conveniences of a modern word processor (spell check, etc.) We should probably discuss this more next time.&lt;br /&gt;
&lt;br /&gt;
Yash will spend the time catching up and going through our existing tutorials.&lt;br /&gt;
&lt;br /&gt;
Lakshmi has graciously volunteered to present Cristian&amp;#039;s algorithm to us.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will start a new tutorial for using the Oscilloscope.&lt;br /&gt;
&lt;br /&gt;
Kevin will explore methods for on-board data storage on the sky mote, both volatile and non-volatile.&lt;br /&gt;
&lt;br /&gt;
Pedro, Suvil, and Kwame will work on running Contiki on the testbed and starting a tutorial. Also, thinking about how we can refactor some of our theoretical tutorials to be more activity oriented.&lt;br /&gt;
&lt;br /&gt;
Everyone should update their tutorials to include the primary contributors. Perhaps somewhere at the end.&lt;br /&gt;
&lt;br /&gt;
== Feb/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Pedro&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Lakshmi presented the paper [[Probabilistic Clock Synchronization http://kom.aau.dk/~rlo/lectures/algoAndArchIII_2009/ChristiansAlgorithm.pdf]]. We had a very interesting discussion about the terms and concepts behind synchronization and clock in network nodes. We might in the future see how this algorithm can be implemented in a WSN or check whether its main ideas are already implemented in the &amp;quot;Implicit network time synchronization&amp;quot;, present in ContikiOS ([http://contiki.sourceforge.net/docs/2.6/a01741.html])&lt;br /&gt;
&lt;br /&gt;
Everyone gave an updated about what have been done during last week. We have some material for two tutorials: the &amp;#039;&amp;#039;Oscilloscope&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Coffee File System&amp;#039;&amp;#039;. This material is yet in the Google Doc create for prototyping and should be posted in the Wiki soon.&lt;br /&gt;
&lt;br /&gt;
Kwame guided the group in the first 4 sessions of ContikiOS Crash Course [[File:Seniot09cccc-notes.pdf]]. We played with LEDs and push button. This example should give a new tutorial on how to use all the sensors/actuators (light, temperature, push button, etc.) on the motes.&lt;br /&gt;
&lt;br /&gt;
We decided that each week one person will be responsible for creating this meeting log, so everyone can keep track of what has been discussed every week. Below we have the expected date of our next meetings and a tentative assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin will give a brief talk about Coffee file system and show us the material he obtained and the tutorial he started to write.&lt;br /&gt;
&lt;br /&gt;
Yash will start to study and collect material about processes and protothreads. He may give a talk about these topics in two weeks.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will keep working on the Oscilloscope tutorial.&lt;br /&gt;
&lt;br /&gt;
Pedro and Kwame will start to work on the Tutornet testbed.&lt;br /&gt;
&lt;br /&gt;
Suvil will fix some issues we are facing in the Wiki with code formatting and help us with account creation/setup of the testbed.&lt;br /&gt;
&lt;br /&gt;
== Feb/21 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Suvil&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin gave a presentation about Coffee File System. He showed the main interface and functions that can be used by Tmote Sky. He also showed an example where a node was programmed to create and write 3 different files on Flash Memory and after reboot output the content of the files reading then from the memory. The presentation slides can be found here:[] and the example code can be found here:[]. He started to create a tutorial on Coffee on the shared Doc file and you may create a tutorial about this topic in our Wiki soon.&lt;br /&gt;
&lt;br /&gt;
We went through the example in: examples/rime/example-neighbors.c, suggested by Bhavana. Basically this example makes all node generate beacons and create a list of neighbors of each node. It prints out the list of neighbors with the corresponding RSSI value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We should continue to work on the tutorials, trying to polish and review them for final publication.&lt;br /&gt;
&lt;br /&gt;
== Feb/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Leo&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pedro gave a presentation of a few of the features available in the Cooja simulator. Some of what he covered, which will be put in the Cooja tutorial, includes how to build Cooja from the terminal and automatically start a simulation, locate source files for debugging, and use the single-step and breakpoint debugging tools available for debugging each node. Afterwards, we looked at examples-neighbors.c in more detail, noting the size of the data structures and the way certain values were calculated, such as RSSI. Lastly, we briefly looked over some of the Contiki OS files in the documentation and flipped through a comprehensive Contiki presentation here [http://www.ee.kth.se/~mikaelj/wsn_course/contiki-course-kth-9oct2008-draft.pdf].&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Several more tutorials should be done by our next meeting.&lt;br /&gt;
&lt;br /&gt;
== Mar/07 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Nikhil&lt;br /&gt;
&lt;br /&gt;
== Mar/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash gave a presentation on Processes and Protothreads. The group expressed interest in learning more about the hardware behind the Tmote Sky, such as the TI MSP430 microprocessor and the CC2420 radio. We&amp;#039;ll probably include some of those as the topic of future talks.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Enjoy Spring Break!&lt;br /&gt;
&lt;br /&gt;
== Mar/21 ==&lt;br /&gt;
&lt;br /&gt;
Spring Break, no meeting&lt;br /&gt;
&lt;br /&gt;
== Mar/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Deepanker&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We successfully programmed a multi-hop communication between 5 motes. We also discussed the ways in which motes can talk to each other, namely - unicast, multicast and reliable unicast - and discussed the pros and cons of each with respect to our application.&lt;br /&gt;
&lt;br /&gt;
We discussed a little bit about the connections on the mote, specifically the interaction of MSP430 with CC2420.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash will give an introduction to MSP430. Completion of tutorials on wiki and proofreading of the already completed will be done by the people who are assigned the task.&lt;br /&gt;
&lt;br /&gt;
== Apr/04 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kevin&lt;br /&gt;
&lt;br /&gt;
== Apr/11 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Timothy&lt;br /&gt;
&lt;br /&gt;
== Apr/18 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Bhavana&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=391</id>
		<title>Meeting Logs</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=Meeting_Logs&amp;diff=391"/>
				<updated>2014-04-11T17:50:59Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* Apr/04 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Feb/7 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Professor Bhaskar gave us his wishlist. See a brief outline at [[Wishlist]].&lt;br /&gt;
&lt;br /&gt;
We got the Contiki oscilloscope up and running, and played around with it using two motes.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Suvil is going to investigate options for a mailing list and also get the issue with uploading images to the wiki fixed.&lt;br /&gt;
&lt;br /&gt;
Nikhil will set up a Google Drive share for us to use for prototyping our tutorials when appropriate. It would allow for us to collaboratively edit in real-time and provide us all the conveniences of a modern word processor (spell check, etc.) We should probably discuss this more next time.&lt;br /&gt;
&lt;br /&gt;
Yash will spend the time catching up and going through our existing tutorials.&lt;br /&gt;
&lt;br /&gt;
Lakshmi has graciously volunteered to present Cristian&amp;#039;s algorithm to us.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will start a new tutorial for using the Oscilloscope.&lt;br /&gt;
&lt;br /&gt;
Kevin will explore methods for on-board data storage on the sky mote, both volatile and non-volatile.&lt;br /&gt;
&lt;br /&gt;
Pedro, Suvil, and Kwame will work on running Contiki on the testbed and starting a tutorial. Also, thinking about how we can refactor some of our theoretical tutorials to be more activity oriented.&lt;br /&gt;
&lt;br /&gt;
Everyone should update their tutorials to include the primary contributors. Perhaps somewhere at the end.&lt;br /&gt;
&lt;br /&gt;
== Feb/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Pedro&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Lakshmi presented the paper [[Probabilistic Clock Synchronization http://kom.aau.dk/~rlo/lectures/algoAndArchIII_2009/ChristiansAlgorithm.pdf]]. We had a very interesting discussion about the terms and concepts behind synchronization and clock in network nodes. We might in the future see how this algorithm can be implemented in a WSN or check whether its main ideas are already implemented in the &amp;quot;Implicit network time synchronization&amp;quot;, present in ContikiOS ([http://contiki.sourceforge.net/docs/2.6/a01741.html])&lt;br /&gt;
&lt;br /&gt;
Everyone gave an updated about what have been done during last week. We have some material for two tutorials: the &amp;#039;&amp;#039;Oscilloscope&amp;#039;&amp;#039; and &amp;#039;&amp;#039;Coffee File System&amp;#039;&amp;#039;. This material is yet in the Google Doc create for prototyping and should be posted in the Wiki soon.&lt;br /&gt;
&lt;br /&gt;
Kwame guided the group in the first 4 sessions of ContikiOS Crash Course [[File:Seniot09cccc-notes.pdf]]. We played with LEDs and push button. This example should give a new tutorial on how to use all the sensors/actuators (light, temperature, push button, etc.) on the motes.&lt;br /&gt;
&lt;br /&gt;
We decided that each week one person will be responsible for creating this meeting log, so everyone can keep track of what has been discussed every week. Below we have the expected date of our next meetings and a tentative assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin will give a brief talk about Coffee file system and show us the material he obtained and the tutorial he started to write.&lt;br /&gt;
&lt;br /&gt;
Yash will start to study and collect material about processes and protothreads. He may give a talk about these topics in two weeks.&lt;br /&gt;
&lt;br /&gt;
Nikhil, Bhavana, Rahul, and Deepanker will keep working on the Oscilloscope tutorial.&lt;br /&gt;
&lt;br /&gt;
Pedro and Kwame will start to work on the Tutornet testbed.&lt;br /&gt;
&lt;br /&gt;
Suvil will fix some issues we are facing in the Wiki with code formatting and help us with account creation/setup of the testbed.&lt;br /&gt;
&lt;br /&gt;
== Feb/21 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Suvil&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Kevin gave a presentation about Coffee File System. He showed the main interface and functions that can be used by Tmote Sky. He also showed an example where a node was programmed to create and write 3 different files on Flash Memory and after reboot output the content of the files reading then from the memory. The presentation slides can be found here:[] and the example code can be found here:[]. He started to create a tutorial on Coffee on the shared Doc file and you may create a tutorial about this topic in our Wiki soon.&lt;br /&gt;
&lt;br /&gt;
We went through the example in: examples/rime/example-neighbors.c, suggested by Bhavana. Basically this example makes all node generate beacons and create a list of neighbors of each node. It prints out the list of neighbors with the corresponding RSSI value.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We should continue to work on the tutorials, trying to polish and review them for final publication.&lt;br /&gt;
&lt;br /&gt;
== Feb/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Leo&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pedro gave a presentation of a few of the features available in the Cooja simulator. Some of what he covered, which will be put in the Cooja tutorial, includes how to build Cooja from the terminal and automatically start a simulation, locate source files for debugging, and use the single-step and breakpoint debugging tools available for debugging each node. Afterwards, we looked at examples-neighbors.c in more detail, noting the size of the data structures and the way certain values were calculated, such as RSSI. Lastly, we briefly looked over some of the Contiki OS files in the documentation and flipped through a comprehensive Contiki presentation here [http://www.ee.kth.se/~mikaelj/wsn_course/contiki-course-kth-9oct2008-draft.pdf].&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Several more tutorials should be done by our next meeting.&lt;br /&gt;
&lt;br /&gt;
== Mar/07 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Nikhil&lt;br /&gt;
&lt;br /&gt;
== Mar/14 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kwame&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash gave a presentation on Processes and Protothreads. The group expressed interest in learning more about the hardware behind the Tmote Sky, such as the TI MSP430 microprocessor and the CC2420 radio. We&amp;#039;ll probably include some of those as the topic of future talks.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Enjoy Spring Break!&lt;br /&gt;
&lt;br /&gt;
== Mar/21 ==&lt;br /&gt;
&lt;br /&gt;
Spring Break, no meeting&lt;br /&gt;
&lt;br /&gt;
== Mar/28 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Deepanker&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Meeting summary:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
We successfully programmed a multi-hop communication between 5 motes. We also discussed the ways in which motes can talk to each other, namely - unicast, multicast and reliable unicast - and discussed the pros and cons of each with respect to our application.&lt;br /&gt;
&lt;br /&gt;
We discussed a little bit about the connections on the mote, specifically the interaction of MSP430 with CC2420.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For next week:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Yash will give an introduction to MSP430. Completion of tutorials on wiki and proofreading of the already completed will be done by the people who are assigned the task.&lt;br /&gt;
&lt;br /&gt;
== Apr/04 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Kevin&lt;br /&gt;
&lt;br /&gt;
This W&lt;br /&gt;
&lt;br /&gt;
== Apr/11 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Timothy&lt;br /&gt;
&lt;br /&gt;
== Apr/18 ==&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Secretary:&amp;#039;&amp;#039;&amp;#039; Bhavana&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=390</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=390"/>
				<updated>2014-04-04T23:40:01Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
For detail interface introduction, please refer to the below link:&lt;br /&gt;
&lt;br /&gt;
http://contiki.sourceforge.net/docs/2.6/a00128.html&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
For detail interface introduction, please refer to the below link:&lt;br /&gt;
&lt;br /&gt;
http://contiki.sourceforge.net/docs/2.6/a00122.html&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Summary==&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
==An Example of Running Coffee on Tmote Sky==&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int file_test(const char *filename, char *msg)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int dir_test(void)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;cd contiki-2.7/examples/sky&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;sudo make TARGET=sky example-coffee.upload login&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;sudo make TARGET=sky login&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=380</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=380"/>
				<updated>2014-03-28T23:19:36Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* An Example of Running Coffee on Tmote Sky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_open(const char* name, int flags)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a file with specific flags. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file want to be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;: The way the file will be opened: CFS_READ, CFS_WRITE, CFS_APPEND or their combiantion.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;return value&amp;#039;&amp;#039;&amp;#039;: A file descriptor, if the file could be opened, or -1 if the file could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: fd = cfs_open(“Contiki_Group”, CFS_READ | CFS_WRITE | CFS_APPEND)&lt;br /&gt;
&lt;br /&gt;
Open a file called “Contiki_Group” which allow both to read and to write. Notice the “CFS_WRITE | CFS_APPEND” means append to the file. Only make use of CFS_APPEND will not achieve this goal. CFS_WRITE has to be included.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_close(int fd)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close a open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: cfs_close(fd)&lt;br /&gt;
&lt;br /&gt;
Close the file with file descriptor fd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_read(int fd, void* buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read data from a open file and fills buf with at most len bytes, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer in which data should be read from the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually read from the file or -1 if an error happens&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_read(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Read from file with file descriptor fd and fill buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that read from the file or -1 if an error happens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_write(int fd, const void *buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write len bytes from the memory buffer buf into the file, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer from which data should be written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be written.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_write(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Write to file with file descriptor fd from buffer buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move the current file position to the position determined by the combination of the offset and the whence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;offset&amp;#039;&amp;#039;&amp;#039;: A position, either relative or absolute, in the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;whence&amp;#039;&amp;#039;&amp;#039;: Determines how to interpret the offset parameter. CFS_SEEK_SET computes the offset from the beginning of the file; CFS_SEEK_CUR computes the offset from the current position of the file position; CFS_SEEK_END computes the offset in relation to the end of the file. Negative offset values are accepted by both CFS_SEEK_CUR and CFS_SEEK_END. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The new absolute file position upon success, or -1 if the file pointer could not be moved to the requested position.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_seek(fd, 0, CFS_SEEK_SET)&lt;br /&gt;
&lt;br /&gt;
Move the file position to the beginning of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_remove(const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove a file with name name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 if the file was removed or -1 if the file could not be removed or if it doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = sfc_remove(name)&lt;br /&gt;
&lt;br /&gt;
Remove the file with name pointed by name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_opendir(struct cfs_dir *dirp, const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the directory name and fills in an opaque handle pointed to by dirp. The contents of this handle is unspecified and is only for use internally by CFS implementation.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dir {&lt;br /&gt;
	char dummy_space[32];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that is filled in by the function.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the directory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if the directory could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Open the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read one entry of directroy dirp at a time. Write the directory entry into the space pointed to by dirent. dirent should be preallocated.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dirent {&lt;br /&gt;
	char name[32];&lt;br /&gt;
	cfs_offset_t size;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirent&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dirent that is filled in by cfs_readdir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if no more directory entries can be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: if (cfs_opendir(&amp;amp;dir, “/”) == 0) {&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) != -1) {&lt;br /&gt;
		printf(“File: %s (%ld bytes)\n”, dirent.name, (long)dirent.size);&lt;br /&gt;
	}&lt;br /&gt;
	cfs_closedir(&amp;amp;dir);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
The first line opens the root directory. If it successes, the while() in the second line reads all the entries in root directory and prints the name and size of those entries. After that, close the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_closedir(struct cfs_dir *dirp)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close the dirctory dirp opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_format(void)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Coffee formats the underlying storage by setting all bits to zero. Formatting must be done before using Coffee for the first time in a mote.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_reserve(const char *name, cfs_offset_t size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reserve space for a file of name with size.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the on-demand log file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
==An Example of Running Coffee on Tmote Sky==&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int file_test(const char *filename, char *msg)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int dir_test(void)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;cd contiki-2.7/examples/sky&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;sudo make TARGET=sky example-coffee.upload login&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;code&amp;gt;sudo make TARGET=sky login&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=379</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=379"/>
				<updated>2014-03-28T23:16:10Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* An Example of Running Coffee on Tmote Sky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_open(const char* name, int flags)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a file with specific flags. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file want to be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;: The way the file will be opened: CFS_READ, CFS_WRITE, CFS_APPEND or their combiantion.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;return value&amp;#039;&amp;#039;&amp;#039;: A file descriptor, if the file could be opened, or -1 if the file could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: fd = cfs_open(“Contiki_Group”, CFS_READ | CFS_WRITE | CFS_APPEND)&lt;br /&gt;
&lt;br /&gt;
Open a file called “Contiki_Group” which allow both to read and to write. Notice the “CFS_WRITE | CFS_APPEND” means append to the file. Only make use of CFS_APPEND will not achieve this goal. CFS_WRITE has to be included.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_close(int fd)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close a open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: cfs_close(fd)&lt;br /&gt;
&lt;br /&gt;
Close the file with file descriptor fd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_read(int fd, void* buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read data from a open file and fills buf with at most len bytes, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer in which data should be read from the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually read from the file or -1 if an error happens&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_read(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Read from file with file descriptor fd and fill buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that read from the file or -1 if an error happens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_write(int fd, const void *buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write len bytes from the memory buffer buf into the file, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer from which data should be written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be written.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_write(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Write to file with file descriptor fd from buffer buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move the current file position to the position determined by the combination of the offset and the whence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;offset&amp;#039;&amp;#039;&amp;#039;: A position, either relative or absolute, in the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;whence&amp;#039;&amp;#039;&amp;#039;: Determines how to interpret the offset parameter. CFS_SEEK_SET computes the offset from the beginning of the file; CFS_SEEK_CUR computes the offset from the current position of the file position; CFS_SEEK_END computes the offset in relation to the end of the file. Negative offset values are accepted by both CFS_SEEK_CUR and CFS_SEEK_END. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The new absolute file position upon success, or -1 if the file pointer could not be moved to the requested position.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_seek(fd, 0, CFS_SEEK_SET)&lt;br /&gt;
&lt;br /&gt;
Move the file position to the beginning of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_remove(const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove a file with name name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 if the file was removed or -1 if the file could not be removed or if it doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = sfc_remove(name)&lt;br /&gt;
&lt;br /&gt;
Remove the file with name pointed by name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_opendir(struct cfs_dir *dirp, const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the directory name and fills in an opaque handle pointed to by dirp. The contents of this handle is unspecified and is only for use internally by CFS implementation.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dir {&lt;br /&gt;
	char dummy_space[32];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that is filled in by the function.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the directory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if the directory could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Open the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read one entry of directroy dirp at a time. Write the directory entry into the space pointed to by dirent. dirent should be preallocated.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dirent {&lt;br /&gt;
	char name[32];&lt;br /&gt;
	cfs_offset_t size;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirent&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dirent that is filled in by cfs_readdir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if no more directory entries can be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: if (cfs_opendir(&amp;amp;dir, “/”) == 0) {&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) != -1) {&lt;br /&gt;
		printf(“File: %s (%ld bytes)\n”, dirent.name, (long)dirent.size);&lt;br /&gt;
	}&lt;br /&gt;
	cfs_closedir(&amp;amp;dir);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
The first line opens the root directory. If it successes, the while() in the second line reads all the entries in root directory and prints the name and size of those entries. After that, close the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_closedir(struct cfs_dir *dirp)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close the dirctory dirp opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_format(void)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Coffee formats the underlying storage by setting all bits to zero. Formatting must be done before using Coffee for the first time in a mote.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_reserve(const char *name, cfs_offset_t size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reserve space for a file of name with size.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the on-demand log file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
==An Example of Running Coffee on Tmote Sky==&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int file_test(const char *filename, char *msg)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;static int dir_test(void)&amp;lt;/code&amp;gt;&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
cd contiki-2.7/examples/sky &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
sudo make TARGET=sky example-coffee.upload login&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
sudo make TARGET=sky login&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=378</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=378"/>
				<updated>2014-03-28T23:12:52Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* CFS-Coffee Interface Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_open(const char* name, int flags)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a file with specific flags. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file want to be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;: The way the file will be opened: CFS_READ, CFS_WRITE, CFS_APPEND or their combiantion.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;return value&amp;#039;&amp;#039;&amp;#039;: A file descriptor, if the file could be opened, or -1 if the file could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: fd = cfs_open(“Contiki_Group”, CFS_READ | CFS_WRITE | CFS_APPEND)&lt;br /&gt;
&lt;br /&gt;
Open a file called “Contiki_Group” which allow both to read and to write. Notice the “CFS_WRITE | CFS_APPEND” means append to the file. Only make use of CFS_APPEND will not achieve this goal. CFS_WRITE has to be included.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_close(int fd)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close a open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: cfs_close(fd)&lt;br /&gt;
&lt;br /&gt;
Close the file with file descriptor fd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_read(int fd, void* buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read data from a open file and fills buf with at most len bytes, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer in which data should be read from the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually read from the file or -1 if an error happens&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_read(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Read from file with file descriptor fd and fill buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that read from the file or -1 if an error happens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_write(int fd, const void *buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write len bytes from the memory buffer buf into the file, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer from which data should be written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be written.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_write(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Write to file with file descriptor fd from buffer buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move the current file position to the position determined by the combination of the offset and the whence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;offset&amp;#039;&amp;#039;&amp;#039;: A position, either relative or absolute, in the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;whence&amp;#039;&amp;#039;&amp;#039;: Determines how to interpret the offset parameter. CFS_SEEK_SET computes the offset from the beginning of the file; CFS_SEEK_CUR computes the offset from the current position of the file position; CFS_SEEK_END computes the offset in relation to the end of the file. Negative offset values are accepted by both CFS_SEEK_CUR and CFS_SEEK_END. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The new absolute file position upon success, or -1 if the file pointer could not be moved to the requested position.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_seek(fd, 0, CFS_SEEK_SET)&lt;br /&gt;
&lt;br /&gt;
Move the file position to the beginning of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_remove(const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove a file with name name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 if the file was removed or -1 if the file could not be removed or if it doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = sfc_remove(name)&lt;br /&gt;
&lt;br /&gt;
Remove the file with name pointed by name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_opendir(struct cfs_dir *dirp, const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the directory name and fills in an opaque handle pointed to by dirp. The contents of this handle is unspecified and is only for use internally by CFS implementation.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dir {&lt;br /&gt;
	char dummy_space[32];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that is filled in by the function.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the directory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if the directory could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Open the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read one entry of directroy dirp at a time. Write the directory entry into the space pointed to by dirent. dirent should be preallocated.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dirent {&lt;br /&gt;
	char name[32];&lt;br /&gt;
	cfs_offset_t size;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirent&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dirent that is filled in by cfs_readdir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if no more directory entries can be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: if (cfs_opendir(&amp;amp;dir, “/”) == 0) {&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) != -1) {&lt;br /&gt;
		printf(“File: %s (%ld bytes)\n”, dirent.name, (long)dirent.size);&lt;br /&gt;
	}&lt;br /&gt;
	cfs_closedir(&amp;amp;dir);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
The first line opens the root directory. If it successes, the while() in the second line reads all the entries in root directory and prints the name and size of those entries. After that, close the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_closedir(struct cfs_dir *dirp)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close the dirctory dirp opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_format(void)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Coffee formats the underlying storage by setting all bits to zero. Formatting must be done before using Coffee for the first time in a mote.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_reserve(const char *name, cfs_offset_t size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reserve space for a file of name with size.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the on-demand log file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
==An Example of Running Coffee on Tmote Sky==&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
static int file_test(const char *filename, char *msg) opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
static int dir_test(void) opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
cd contiki-2.7/examples/sky &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
sudo make TARGET=sky example-coffee.upload login&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
sudo make TARGET=sky login&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=377</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=377"/>
				<updated>2014-03-28T23:10:28Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* An Example of Running Coffee on Tmote Sky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_open(const char* name, int flags)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a file with specific flags. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file want to be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;: The way the file will be opened: CFS_READ, CFS_WRITE, CFS_APPEND or their combiantion.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;return value&amp;#039;&amp;#039;&amp;#039;: A file descriptor, if the file could be opened, or -1 if the file could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: fd = cfs_open(“Contiki_Group”, CFS_READ | CFS_WRITE | CFS_APPEND)&lt;br /&gt;
&lt;br /&gt;
Open a file called “Contiki_Group” which allow both to read and to write. Notice the “CFS_WRITE | CFS_APPEND” means append to the file. Only make use of CFS_APPEND will not achieve this goal. CFS_WRITE has to be included.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_close(int fd)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close a open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: cfs_close(fd)&lt;br /&gt;
&lt;br /&gt;
Close the file with file descriptor fd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_read(int fd, void* buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read data from a open file and fills buf with at most len bytes, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer in which data should be read from the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually read from the file or -1 if an error happens&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_read(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Read from file with file descriptor fd and fill buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that read from the file or -1 if an error happens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_write(int fd, const void *buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write len bytes from the memory buffer buf into the file, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer from which data should be written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be written.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_write(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Write to file with file descriptor fd from buffer buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move the current file position to the position determined by the combination of the offset and the whence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;offset&amp;#039;&amp;#039;&amp;#039;: A position, either relative or absolute, in the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;whence&amp;#039;&amp;#039;&amp;#039;: Determines how to interpret the offset parameter. CFS_SEEK_SET computes the offset from the beginning of the file; CFS_SEEK_CUR computes the offset from the current position of the file position; CFS_SEEK_END computes the offset in relation to the end of the file. Negative offset values are accepted by both CFS_SEEK_CUR and CFS_SEEK_END. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The new absolute file position upon success, or -1 if the file pointer could not be moved to the requested position.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_seek(fd, 0, CFS_SEEK_SET)&lt;br /&gt;
&lt;br /&gt;
Move the file position to the beginning of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_remove(const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove a file with name name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 if the file was removed or -1 if the file could not be removed or if it doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = sfc_remove(name)&lt;br /&gt;
&lt;br /&gt;
Remove the file with name pointed by name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_opendir(struct cfs_dir *dirp, const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the directory name and fills in an opaque handle pointed to by dirp. The contents of this handle is unspecified and is only for use internally by CFS implementation.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dir {&lt;br /&gt;
	char dummy_space[32];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that is filled in by the function.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the directory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if the directory could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Open the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read one entry of directroy dirp at a time. Write the directory entry into the space pointed to by dirent. dirent should be preallocated.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dirent {&lt;br /&gt;
	char name[32];&lt;br /&gt;
	cfs_offset_t size;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirent&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dirent that is filled in by cfs_readdir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if no more directory entries can be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: if (cfs_opendir(&amp;amp;dir, “/”) == 0) {&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) != -1) {&lt;br /&gt;
		printf(“File: %s (%ld bytes)\n”, dirent.name, (long)dirent.size);&lt;br /&gt;
	}&lt;br /&gt;
	cfs_closedir(&amp;amp;dir);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
The first line opens the root directory. If it successes, the while() in the second line reads all the entries in root directory and prints the name and size of those entries. After that, close the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_closedir(struct cfs_dir *dirp)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close the dirctory dirp opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_format(void)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Coffee formats the underlying storage by setting all bits to zero. Formatting must be done before using Coffee for the first time in a mote.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_reserve(const char *name, cfs_offset_t size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reserve space for a file of name with size.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the on-demand log file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
An Example of Running Coffee on Tmote Sky&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
static int file_test(const char *filename, char *msg) opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
static int dir_test(void) opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
cd contiki-2.7/examples/sky &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
sudo make TARGET=sky example-coffee.upload login&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
sudo make TARGET=sky login&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=376</id>
		<title>CFS-Coffee</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=CFS-Coffee&amp;diff=376"/>
				<updated>2014-03-28T23:05:41Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: /* CFS-Coffee Interface Extensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Permanent Storage of Contiki on Tmote Sky (CFS-Coffee) ==&lt;br /&gt;
&lt;br /&gt;
Contiki provides File System to achieve the goal of permanent storage. The Contiki File System(CFS) works as a Virtual File System and provides some interfaces for different file systems. CFS-POSIX and Coffee are two with full functionalities. CFS-POSIX is used in Contiki platforms that runs in native mode. Coffee, on the other hand, is primarily aimed at sensor devices that equiped with Flash Memories or EEPROM.&lt;br /&gt;
&lt;br /&gt;
==The CFS Programming Interface==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_open(const char* name, int flags)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a file with specific flags. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file want to be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;flags&amp;#039;&amp;#039;&amp;#039;: The way the file will be opened: CFS_READ, CFS_WRITE, CFS_APPEND or their combiantion.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;return value&amp;#039;&amp;#039;&amp;#039;: A file descriptor, if the file could be opened, or -1 if the file could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: fd = cfs_open(“Contiki_Group”, CFS_READ | CFS_WRITE | CFS_APPEND)&lt;br /&gt;
&lt;br /&gt;
Open a file called “Contiki_Group” which allow both to read and to write. Notice the “CFS_WRITE | CFS_APPEND” means append to the file. Only make use of CFS_APPEND will not achieve this goal. CFS_WRITE has to be included.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_close(int fd)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close a open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: cfs_close(fd)&lt;br /&gt;
&lt;br /&gt;
Close the file with file descriptor fd.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_read(int fd, void* buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read data from a open file and fills buf with at most len bytes, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer in which data should be read from the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually read from the file or -1 if an error happens&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_read(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Read from file with file descriptor fd and fill buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that read from the file or -1 if an error happens.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_write(int fd, const void *buf, unsigned int len)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Write len bytes from the memory buffer buf into the file, starting from the current position in the file descriptor.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;buf&amp;#039;&amp;#039;&amp;#039;: The buffer from which data should be written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;len&amp;#039;&amp;#039;&amp;#039;: The number of bytes that should be written.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The number of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_write(fd, buf, sizeof(buf))&lt;br /&gt;
&lt;br /&gt;
Write to file with file descriptor fd from buffer buf with at most its size. Here buf is a pointer. ret contains the numbers of bytes that was actually written to the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;cfs_offset_t cfs_seek(int fd, cfs_offset_t offset, int whence)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Move the current file position to the position determined by the combination of the offset and the whence.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;fd&amp;#039;&amp;#039;&amp;#039;: The file descriptor of the open file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;offset&amp;#039;&amp;#039;&amp;#039;: A position, either relative or absolute, in the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;whence&amp;#039;&amp;#039;&amp;#039;: Determines how to interpret the offset parameter. CFS_SEEK_SET computes the offset from the beginning of the file; CFS_SEEK_CUR computes the offset from the current position of the file position; CFS_SEEK_END computes the offset in relation to the end of the file. Negative offset values are accepted by both CFS_SEEK_CUR and CFS_SEEK_END. &lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: The new absolute file position upon success, or -1 if the file pointer could not be moved to the requested position.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_seek(fd, 0, CFS_SEEK_SET)&lt;br /&gt;
&lt;br /&gt;
Move the file position to the beginning of the file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_remove(const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Remove a file with name name.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 if the file was removed or -1 if the file could not be removed or if it doesn’t exist.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = sfc_remove(name)&lt;br /&gt;
&lt;br /&gt;
Remove the file with name pointed by name.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_opendir(struct cfs_dir *dirp, const char *name)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the directory name and fills in an opaque handle pointed to by dirp. The contents of this handle is unspecified and is only for use internally by CFS implementation.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dir {&lt;br /&gt;
	char dummy_space[32];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that is filled in by the function.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;#039;: The name of the directory.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if the directory could not be opened.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: ret = cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Open the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_readdir(struct cfs_dir *dirp, struct cfs_dirent *dirent)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Read one entry of directroy dirp at a time. Write the directory entry into the space pointed to by dirent. dirent should be preallocated.&lt;br /&gt;
&lt;br /&gt;
struct cfs_dirent {&lt;br /&gt;
	char name[32];&lt;br /&gt;
	cfs_offset_t size;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirent&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dirent that is filled in by cfs_readdir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 or -1 if no more directory entries can be read.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;e.g&amp;#039;&amp;#039;&amp;#039;: if (cfs_opendir(&amp;amp;dir, “/”) == 0) {&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) != -1) {&lt;br /&gt;
		printf(“File: %s (%ld bytes)\n”, dirent.name, (long)dirent.size);&lt;br /&gt;
	}&lt;br /&gt;
	cfs_closedir(&amp;amp;dir);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
The first line opens the root directory. If it successes, the while() in the second line reads all the entries in root directory and prints the name and size of those entries. After that, close the root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;void cfs_closedir(struct cfs_dir *dirp)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Close the dirctory dirp opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;dirp&amp;#039;&amp;#039;&amp;#039;: A pointer to a struct cfs_dir that has been opened with cfs_opendir().&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction to Coffee==&lt;br /&gt;
&lt;br /&gt;
Coffee is a fully functional file system designed specifically for the characteristics of flash memories and EEPROM. Coffee is usually used in sensor devices with flash (e.g Tmote Sky), so two principles are pretty important. First, the metadata stored in RAM for each file should be small because sensor devices have very limited RAM space. Second, bits in flash memories can be toggled from 1 to 0, but not toggled back from 0 to 1 without doing an expensive erase. Thus, when modifying a file, Coffee creates an invisible micro log which is linked to the original file. The micro log contains the lastest data of the file. For user, the micro log and the original file is just one logical file, as if they modify the original file. When the micro log eventually fills up, Coffee transparently merges the content of the original file and the micro log into a new file, and deletes the two former files. &lt;br /&gt;
&lt;br /&gt;
Coffee has a flat directory structure. It only has the root directory. Thus, cfs_opendir() only accept “/” or “.” as the second argument. When removing a file from a Coffee, there are two steps. First, external user calls cfs_remove(). The file mentioned by user will be marked as obsolete. Obsolete files cannot be seen by external users. Coffee will actually delete files only when a new file reservation request cannot be granted.&lt;br /&gt;
&lt;br /&gt;
The implementation of Coffee in core/cfs/cfs-coffee.c is totally platform independent. The specific configuration of Coffee for different platforms is written in csf-coffee-arch.c. We can see many csf-coffee-arch.c files in plarform/./csf-coffee-arch.c, e.g plarform/z1/csf-coffee-arch.c, plarform/esb/csf-coffee-arch.c, plarform/sky/csf-coffee-arch.c. When we decide the platform, such as TARGET=sky, we compile plarform/sky/csf-coffee-arch.c and ignore all other csf-coffee-arch.c files. Macro definitions in plarform/sky/csf-coffee-arch.c configure the details of coffee in Sky Mote. Macro definition contains parameters like COFFEE_SECTOR_SIZE, COFFEE_PAGE_SIZE, COFFEE_FD_SET_SIZE, COFFEE_MICRO_LOGS and so on. Also, it defines COFFEE_WRITE, COFFEE_READ and COFFEE_ERASE to point to the device drivers I/O function. &lt;br /&gt;
&lt;br /&gt;
==CFS-Coffee Interface Extensions==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_format(void)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Coffee formats the underlying storage by setting all bits to zero. Formatting must be done before using Coffee for the first time in a mote.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_reserve(const char *name, cfs_offset_t size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reserve space for a file of name with size.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;int cfs_coffee_configure_log(const char *file, unsigned log_size, unsigned log_entry_size)&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Configure the on-demand log file.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Return Value&amp;#039;&amp;#039;&amp;#039;: 0 on success, -1 on failure.&lt;br /&gt;
&lt;br /&gt;
cfs_coffee_format() may take a few second because all sectors must be erased.  cfs_coffee_reserve() and int cfs_coffee_configure_log() can optimize Coffee’s handling of the file.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how everything works. Suppose we want to run Contiki on Sky Mote. First make sure TARGET=sky. Then every file about sky is compiled and you can also see a new folder which is created called sky_obj. Inside contains everything you need to run on Sky Mote. Suppose you want to use Coffee as the File System. Write cfs_coffee_format() before the first time you try to operate on Coffee. This function notice the system that you want to use Coffee and the system will do some formatting. Let’s say then you want to read something from an existing file with the function call cfs_read(). This function is defined in core/cfs/cfs.h. Because we make use of Coffee, the implementation of this function will be in core/cfs/cfs-coffee.c. The function cfs_read() actually calls the macro definition COFFEE_READ(). The definition of COFFEE_READ() is in cfs-coffee-arch.c. Since we make TARGET=sky, the one that was compiled and used by us is platform/sky/cfs-coffee-arch.c. This file defines COFFEE_READ() to point to Sky Mote drivers I/O function. Finally, the external users’ cfs_read() gets to the Sky Driver I/O function.&lt;br /&gt;
&lt;br /&gt;
==An Example of Running Coffee on Tmote Sky==&lt;br /&gt;
&lt;br /&gt;
This example shows the basic way to open, read, write and append files in Coffee. The platform we choose here is Tmote Sky.&lt;br /&gt;
First, open an example provided by Contiki (/home/user/contiki-2.7/example/sky/example- coffee.c).&lt;br /&gt;
Here, it defines two test functions:&lt;br /&gt;
static int file_test(const char *filename, char *msg) opens a file named FILENAME with CFS_WRITE | CFS_APPEND | CFS_READ. It appends the opening file with records and prints out everything in the file.&lt;br /&gt;
static int dir_test(void) opens the root directory and prints out all entries of root.&lt;br /&gt;
The Process calls file_test() twice and dir_test() once. Then the process ends.&lt;br /&gt;
Now, we do some modifications based on this example. First we add a function static int read_test(void). The implementation of this function is shown as below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
static int&lt;br /&gt;
read_test(void)&lt;br /&gt;
{&lt;br /&gt;
	struct cfs_dir dir;&lt;br /&gt;
	struct cfs_dirent dirent;&lt;br /&gt;
&lt;br /&gt;
	int fd;&lt;br /&gt;
	int r;&lt;br /&gt;
&lt;br /&gt;
	struct record {&lt;br /&gt;
    		char message[16];&lt;br /&gt;
    		uint8_t sequence;&lt;br /&gt;
  	} record;&lt;br /&gt;
&lt;br /&gt;
	static int i = 0;&lt;br /&gt;
	if (cfs_opendir(&amp;amp;dir, &amp;quot;/&amp;quot;) != 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;Fail to open the root directory\n&amp;quot;);&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
	while(cfs_readdir(&amp;amp;dir, &amp;amp;dirent) == 0)&lt;br /&gt;
	{&lt;br /&gt;
		i ++;&lt;br /&gt;
		printf(&amp;quot;\nFile name: %s\n&amp;quot;, dirent.name);&lt;br /&gt;
		if ((fd =cfs_open(dirent.name, CFS_READ)) != -1)&lt;br /&gt;
		{&lt;br /&gt;
			cfs_seek(fd, 0, CFS_SEEK_SET);&lt;br /&gt;
			for(;;) &lt;br /&gt;
			{&lt;br /&gt;
    				r = cfs_read(fd, &amp;amp;record, sizeof(record));&lt;br /&gt;
    				if(r == 0) {&lt;br /&gt;
      					break;&lt;br /&gt;
    				} else if(r &amp;gt; sizeof(record)) {&lt;br /&gt;
      					printf(&amp;quot;failed to read %d bytes from %s, got %d\n&amp;quot;,(int)sizeof(record), dirent.name, r);&lt;br /&gt;
      					cfs_close(fd);&lt;br /&gt;
      					return -1;&lt;br /&gt;
    				}&lt;br /&gt;
&lt;br /&gt;
    				printf(&amp;quot;Read message \&amp;quot;%s\&amp;quot;, sequence %u\n&amp;quot;,record.message, record.sequence);&lt;br /&gt;
  			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (i == 0)&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nNo file exists.\n&amp;quot;);&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		return 1;&lt;br /&gt;
	}&lt;br /&gt;
		&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of read_test() is quite simple. It opens the root file system and reads all the data in the file system. In the while() loop, it reads an entry of a file. Then it makes use of the entry to open the file and read all the data out.&lt;br /&gt;
&lt;br /&gt;
Also, in the process, we add an etimer at the beginning. The process can only move on either when the timer expired or someone push a button. If the timer expire, the process will run cfs_coffee_format(), which will set all the flash to 1. Otherwise, we don’t do this. Then we call read_test(), which read all the data in the file system. After that, we check whether there are files exist in the system. If there is, we give up wirting. Otherwise, we create two files and write some data in.&lt;br /&gt;
The process then looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PROCESS_THREAD(example_coffee_process, ev, data)&lt;br /&gt;
{&lt;br /&gt;
  PROCESS_BEGIN();&lt;br /&gt;
&lt;br /&gt;
	static int flag = 0;&lt;br /&gt;
	button_sensor.configure(SENSORS_ACTIVE, 1);&lt;br /&gt;
&lt;br /&gt;
	static struct etimer ak;&lt;br /&gt;
	etimer_set(&amp;amp;ak, CLOCK_SECOND * 6);&lt;br /&gt;
	&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER || ev == sensors_event &amp;amp;&amp;amp; data == &amp;amp;button_sensor);&lt;br /&gt;
&lt;br /&gt;
	if (ev == PROCESS_EVENT_TIMER)&lt;br /&gt;
		cfs_coffee_format();	&lt;br /&gt;
&lt;br /&gt;
	if ((flag = read_test()) == -1)&lt;br /&gt;
		PROCESS_EXIT();&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	static struct etimer et;&lt;br /&gt;
	etimer_set(&amp;amp;et, CLOCK_SECOND * 2);&lt;br /&gt;
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);&lt;br /&gt;
&lt;br /&gt;
	if (flag == 1)&lt;br /&gt;
		printf(&amp;quot;\nData exists...No written again...\n&amp;quot;);&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		printf(&amp;quot;\nData begin to write...\n&amp;quot;);&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The first test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 1 failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
		if(file_test(FILENAME_1, &amp;quot;The second test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 2 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(file_test(FILENAME_2, &amp;quot;The third test&amp;quot;) == 0) {&lt;br /&gt;
    			printf(&amp;quot;file test 3 failed\n&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if(dir_test() == 0) {&lt;br /&gt;
    			printf(&amp;quot;dir test failed\n&amp;quot;);&lt;br /&gt;
  		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
  PROCESS_END();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, connect your mote to your PC’s USB port and change directory. &lt;br /&gt;
cd contiki-2.7/examples/sky &lt;br /&gt;
&lt;br /&gt;
Compile this Coffee example to Sky Mote.&lt;br /&gt;
sudo make TARGET=sky example-coffee.upload login&lt;br /&gt;
&lt;br /&gt;
Once login, wait for 6 seconds patiently for the first time out.If it success, we should see terminal has the output like this:&lt;br /&gt;
Here you can see, we create two files and write some data in. Then, disconnect your mote and do whatever you want. Maybe one day later, you come back. Now it’s the time to keep moving. &lt;br /&gt;
Welcome back. Now connect your mote with USB port again and do:&lt;br /&gt;
sudo make TARGET=sky login&lt;br /&gt;
You are in the process again and please follow the following two steps:&lt;br /&gt;
1. push “RESET” button;&lt;br /&gt;
2. push “USER” button within 6 seconds.&lt;br /&gt;
Now, the program will not call cfs_coffee_format(). If succeed, you will see: &lt;br /&gt;
As you can see, we read out all the data that you wrote in one day ago. Everything is right there without any change.&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	<entry>
		<id>http://anrg.usc.edu/contiki/index.php?title=Contiki_tutorials&amp;diff=213</id>
		<title>Contiki tutorials</title>
		<link rel="alternate" type="text/html" href="http://anrg.usc.edu/contiki/index.php?title=Contiki_tutorials&amp;diff=213"/>
				<updated>2014-02-15T19:08:19Z</updated>
		
		<summary type="html">&lt;p&gt;Shanpei: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Main_Page | Back to Main Page]]&lt;br /&gt;
&lt;br /&gt;
== List of Tutorials ==&lt;br /&gt;
&lt;br /&gt;
Completed&lt;br /&gt;
&lt;br /&gt;
Need review&lt;br /&gt;
# [[Installation]]&lt;br /&gt;
# [[Hello World]]&lt;br /&gt;
# [[Broadcast Example]]&lt;br /&gt;
&lt;br /&gt;
Starting&lt;br /&gt;
# [[Tutornet]]&lt;br /&gt;
# [[Timers]]&lt;br /&gt;
# [[Cooja Simulator]]&lt;br /&gt;
# [[Contiki build system]]&lt;br /&gt;
# [[Processes]]&lt;br /&gt;
# [[Protocols stack]]&lt;br /&gt;
# [[CFS-Coffee]]&lt;/div&gt;</summary>
		<author><name>Shanpei</name></author>	</entry>

	</feed>