--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+generic module BaseSendReceiveP() {
+ uses {
+ interface Boot;
+ interface Thread as ReceiveThread;
+ interface Thread as SendThread;
+ interface ConditionVariable;
+ interface Mutex;
+ interface Pool<message_t>;
+ interface Queue<message_t*>;
+ interface Leds;
+
+ interface BlockingReceive as BlockingReceiveAny;
+ interface BlockingAMSend as BlockingAMSend[uint8_t id];
+ interface Packet as ReceivePacket;
+ interface Packet as SendPacket;
+ interface AMPacket as ReceiveAMPacket;
+ interface AMPacket as SendAMPacket;
+ }
+}
+
+implementation {
+ condvar_t c_queue, c_pool;
+ mutex_t m_queue, m_pool;
+
+ event void Boot.booted() {
+ call ConditionVariable.init(&c_queue);
+ call ConditionVariable.init(&c_pool);
+ call Mutex.init(&m_queue);
+ call Mutex.init(&m_pool);
+ call ReceiveThread.start(NULL);
+ call SendThread.start(NULL);
+ }
+
+ event void ReceiveThread.run(void* arg) {
+ message_t* msg;
+ call Mutex.lock(&m_pool);
+ msg = call Pool.get();
+ call Mutex.unlock(&m_pool);
+ for(;;) {
+ if(call BlockingReceiveAny.receive(msg, 0) == SUCCESS) {
+ call Leds.led0Toggle();
+
+ call Mutex.lock(&m_queue);
+ call Queue.enqueue(msg);
+ call Mutex.unlock(&m_queue);
+ if( call Queue.size() == 1 ) {
+ call ConditionVariable.signalAll(&c_queue);
+ }
+
+ call Mutex.lock(&m_pool);
+ while( call Pool.empty() )
+ call ConditionVariable.wait(&c_pool, &m_pool);
+ msg = call Pool.get();
+ call Mutex.unlock(&m_pool);
+
+ }
+ else call Leds.led2Toggle();
+ }
+ }
+
+ event void SendThread.run(void* arg) {
+ message_t* msg;
+ am_id_t id;
+ am_addr_t source;
+ am_addr_t dest;
+ uint8_t len;
+
+ for(;;) {
+ call Mutex.lock(&m_queue);
+ while( call Queue.empty() )
+ call ConditionVariable.wait(&c_queue, &m_queue);
+ msg = call Queue.dequeue();
+ call Mutex.unlock(&m_queue);
+
+ id = call ReceiveAMPacket.type(msg);
+ source = call ReceiveAMPacket.source(msg);
+ dest = call ReceiveAMPacket.destination(msg);
+ len = call ReceivePacket.payloadLength(msg);
+
+ call SendPacket.clear(msg);
+ call SendAMPacket.setSource(msg, source);
+
+ call BlockingAMSend.send[id](dest, msg, len);
+ call Leds.led1Toggle();
+
+ call Mutex.lock(&m_pool);
+ call Pool.put(msg);
+ call Mutex.unlock(&m_pool);
+ if( call Pool.size() == 1 ) {
+ call ConditionVariable.signalAll(&c_pool);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "base_station.h"
+#include "stack.h"
+#include "message.h"
+
+configuration BaseStationAppC {}
+
+implementation
+{
+ components MainC,
+ BaseStationC,
+ new BaseSendReceiveP() as RadioReceiveSerialSendP,
+ new BaseSendReceiveP() as SerialReceiveRadioSendP,
+
+ new ThreadC(BOOT_THREAD_STACK_SIZE) as BootThread,
+ new ThreadC(RADIO_RECEIVE_THREAD_STACK_SIZE) as RadioReceiveThread,
+ new ThreadC(SERIAL_SEND_THREAD_STACK_SIZE) as SerialSendThread,
+ new ThreadC(SERIAL_RECEIVE_THREAD_STACK_SIZE) as SerialReceiveThread,
+ new ThreadC(RADIO_SEND_THREAD_STACK_SIZE) as RadioSendThread,
+
+ new PoolC(message_t, BASE_STATION_MSG_QUEUE_SIZE) as RadioReceivePool,
+ new QueueC(message_t*, BASE_STATION_MSG_QUEUE_SIZE) as RadioReceiveQueue,
+ new PoolC(message_t, BASE_STATION_MSG_QUEUE_SIZE) as SerialReceivePool,
+ new QueueC(message_t*, BASE_STATION_MSG_QUEUE_SIZE) as SerialReceiveQueue,
+
+ ThreadSynchronizationC,
+ LedsC;
+
+ BaseStationC.Boot -> MainC;
+ RadioReceiveSerialSendP.Boot -> BaseStationC;
+ SerialReceiveRadioSendP.Boot -> BaseStationC;
+
+ BaseStationC.BootThread -> BootThread;
+ RadioReceiveSerialSendP.ReceiveThread -> RadioReceiveThread;
+ RadioReceiveSerialSendP.SendThread -> SerialSendThread;
+ SerialReceiveRadioSendP.ReceiveThread -> SerialReceiveThread;
+ SerialReceiveRadioSendP.SendThread -> RadioSendThread;
+
+ RadioReceiveSerialSendP.Pool -> RadioReceivePool;
+ RadioReceiveSerialSendP.Queue -> RadioReceiveQueue;
+ SerialReceiveRadioSendP.Pool -> SerialReceivePool;
+ SerialReceiveRadioSendP.Queue -> SerialReceiveQueue;
+
+ RadioReceiveSerialSendP.ConditionVariable -> ThreadSynchronizationC;
+ RadioReceiveSerialSendP.Mutex -> ThreadSynchronizationC;
+ RadioReceiveSerialSendP.Leds -> LedsC;
+ SerialReceiveRadioSendP.ConditionVariable -> ThreadSynchronizationC;
+ SerialReceiveRadioSendP.Mutex -> ThreadSynchronizationC;
+ SerialReceiveRadioSendP.Leds -> LedsC;
+
+ components BlockingActiveMessageC as BlockingRadioActiveMessageC,
+ BlockingSerialActiveMessageC;
+
+ BaseStationC.BlockingRadioAMControl -> BlockingRadioActiveMessageC;
+ BaseStationC.BlockingSerialAMControl -> BlockingSerialActiveMessageC;
+
+ RadioReceiveSerialSendP.ReceivePacket -> BlockingRadioActiveMessageC;
+ RadioReceiveSerialSendP.SendPacket -> BlockingSerialActiveMessageC;
+ RadioReceiveSerialSendP.ReceiveAMPacket -> BlockingRadioActiveMessageC;
+ RadioReceiveSerialSendP.SendAMPacket -> BlockingSerialActiveMessageC;
+ RadioReceiveSerialSendP.BlockingReceiveAny -> BlockingRadioActiveMessageC.BlockingReceiveAny;
+ RadioReceiveSerialSendP.BlockingAMSend -> BlockingSerialActiveMessageC;
+
+ SerialReceiveRadioSendP.ReceivePacket -> BlockingSerialActiveMessageC;
+ SerialReceiveRadioSendP.SendPacket -> BlockingRadioActiveMessageC;
+ SerialReceiveRadioSendP.ReceiveAMPacket -> BlockingSerialActiveMessageC;
+ SerialReceiveRadioSendP.SendAMPacket -> BlockingRadioActiveMessageC;
+ SerialReceiveRadioSendP.BlockingReceiveAny -> BlockingSerialActiveMessageC.BlockingReceiveAny;
+ SerialReceiveRadioSendP.BlockingAMSend -> BlockingRadioActiveMessageC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+module BaseStationC {
+ provides {
+ interface Boot as BaseStationBoot;
+ }
+ uses {
+ interface Boot;
+ interface Thread as BootThread;
+ interface BlockingStdControl as BlockingRadioAMControl;
+ interface BlockingStdControl as BlockingSerialAMControl;
+ }
+}
+
+implementation {
+
+ event void Boot.booted() {
+ call BootThread.start(NULL);
+ }
+
+ event void BootThread.run(void* arg) {
+ call BlockingRadioAMControl.start();
+ call BlockingSerialAMControl.start();
+ signal BaseStationBoot.booted();
+ }
+}
--- /dev/null
+COMPONENT=BaseStationAppC
+
+CFLAGS+=-DCC2420_DEF_CHANNEL=26
+
+CFLAGS+=-DCC2420_NO_ACKNOWLEDGEMENTS
+CFLAGS+=-DCC2420_NO_ADDRESS_RECOGNITION
+CFLAGS+=-DTOSH_DATA_LENGTH=115
+
+include $(MAKERULES)
--- /dev/null
+ /*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Header file for declaring constants and AM types for use by the
+ * BaseStation application
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#ifndef BASE_STATION_H
+#define BASE_STATION_H
+
+enum {
+ BASE_STATION_MSG_QUEUE_SIZE = 3,
+};
+
+enum {
+ AM_SERIAL_BASE_MSG = 0,
+};
+
+#endif //BASE_STATION_H
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#ifndef BASE_STATION_APP_STACK_H
+#define BASE_STATION_APP_STACK_H
+
+enum {
+ BOOT_THREAD_STACK_SIZE = 200,
+ RADIO_RECEIVE_THREAD_STACK_SIZE = 600,
+ SERIAL_SEND_THREAD_STACK_SIZE = 600,
+ SERIAL_RECEIVE_THREAD_STACK_SIZE = 600,
+ RADIO_SEND_THREAD_STACK_SIZE = 600,
+};
+
+#endif //BASE_STATION_APP_STACK_H
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+configuration BlinkAppC {
+}
+implementation {
+ components MainC, BlinkC, LedsC;
+ components new ThreadC(800) as NullThread;
+ components new ThreadC(800) as TinyThread0;
+ components new ThreadC(800) as TinyThread1;
+ components new ThreadC(800) as TinyThread2;
+
+ MainC.Boot <- BlinkC;
+ BlinkC.NullThread -> NullThread;
+ BlinkC.TinyThread0 -> TinyThread0;
+ BlinkC.TinyThread1 -> TinyThread1;
+ BlinkC.TinyThread2 -> TinyThread2;
+
+ BlinkC.Leds -> LedsC;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+module BlinkC {
+ uses {
+ interface Boot;
+ interface Thread as NullThread;
+ interface Thread as TinyThread0;
+ interface Thread as TinyThread1;
+ interface Thread as TinyThread2;
+ interface Leds;
+ }
+}
+
+implementation {
+ event void Boot.booted() {
+ //call NullThread.start(NULL);
+ call TinyThread0.start(NULL);
+ call TinyThread1.start(NULL);
+ call TinyThread2.start(NULL);
+ }
+
+ event void NullThread.run(void* arg) {
+ for(;;){
+ }
+ }
+ event void TinyThread0.run(void* arg) {
+ for(;;){
+ call Leds.led0Toggle();
+ call TinyThread0.sleep(200);
+ }
+ }
+ event void TinyThread1.run(void* arg) {
+ for(;;){
+ call Leds.led1Toggle();
+ call TinyThread1.sleep(1000);
+ }
+ }
+ event void TinyThread2.run(void* arg) {
+ for(;;){
+ call Leds.led2Toggle();
+ call TinyThread2.sleep(1000);
+ }
+ }
+}
--- /dev/null
+COMPONENT=BlinkAppC
+CFLAGS += -I$(TOS_THREADS_DIR)/tos/sensorboards/tmote_onboard
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This application is derived from a similar application in the TinyThread
+ * implementation by William P. McCartney from Cleveland State University (2006)
+ *
+ * This application implements a threaded approach to bouncing messages back and forth
+ * between two motes. To run it you will need to burn one mote with node ID 0, and a
+ * second mote with node ID 1. Three different threads run that each send a
+ * message and then wait to receive a message before sending their next one. After
+ * each message reception, an LED is toggled to indicate that it was received. Thread
+ * 0 blinks led0, thread 1 blinks led1, and thread 2 blinks led2. The three
+ * threads run independently, and three different messages are bounced back and
+ * forth between the two motes in an unsynchronized fashion. In contrast to the simple
+ * Bounce application also found in this directory, once a thread receives a message
+ * it waits on a Barrier before continuing on and turning on its led. A synchronization
+ * thread is used to wait until all three messages have been received before unblocking
+ * the barrier. In this way, messages are still bounced back and forth between the
+ * two motes in an asynchronous fashion, but all leds come on at the same time
+ * because of the Barrier and the synchronization thread. The effect is that all three
+ * leds on one mote flash in unison, followed by all three on the other mote back
+ * and forth forever.
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#include "barrier_bounce.h"
+#include "stack.h"
+
+configuration BarrierBounceAppC {
+}
+implementation {
+ components MainC, BarrierBounceC as BounceC, LedsC;
+ components BlockingActiveMessageC;
+ MainC.Boot <- BounceC;
+ BounceC.BlockingAMControl -> BlockingActiveMessageC;
+ BounceC.Leds -> LedsC;
+
+ // Included to allow the use of barriers in our application
+ components ThreadSynchronizationC;
+ BounceC.Barrier -> ThreadSynchronizationC;
+
+ // Thread and Bounce Message handlers for thread 0
+ components new ThreadC(BOUNCE_THREAD0_STACK_SIZE) as BounceThread0;
+ components new BlockingAMSenderC(AM_BOUNCE0_MSG) as BlockingAMSender0;
+ components new BlockingAMReceiverC(AM_BOUNCE0_MSG) as BlockingAMReceiver0;
+ BounceC.BounceThread0 -> BounceThread0;
+ BounceC.BlockingAMSend0 -> BlockingAMSender0;
+ BounceC.BlockingReceive0 -> BlockingAMReceiver0;
+
+ // Thread and Bounce Message handlers for thread 1
+ components new ThreadC(BOUNCE_THREAD1_STACK_SIZE) as BounceThread1;
+ components new BlockingAMSenderC(AM_BOUNCE1_MSG) as BlockingAMSender1;
+ components new BlockingAMReceiverC(AM_BOUNCE1_MSG) as BlockingAMReceiver1;
+ BounceC.BounceThread1 -> BounceThread1;
+ BounceC.BlockingAMSend1 -> BlockingAMSender1;
+ BounceC.BlockingReceive1 -> BlockingAMReceiver1;
+
+ // Thread and Bounce Message handlers for thread 2
+ components new ThreadC(BOUNCE_THREAD2_STACK_SIZE) as BounceThread2;
+ components new BlockingAMSenderC(AM_BOUNCE2_MSG) as BlockingAMSender2;
+ components new BlockingAMReceiverC(AM_BOUNCE2_MSG) as BlockingAMReceiver2;
+ BounceC.BounceThread2 -> BounceThread2;
+ BounceC.BlockingAMSend2 -> BlockingAMSender2;
+ BounceC.BlockingReceive2 -> BlockingAMReceiver2;
+
+ // Synchronization thread to keep all threads in sync so that
+ // none of them are able to continue execution until all of them
+ // have both sent and received a message
+ components new ThreadC(SYNC_THREAD_STACK_SIZE) as SyncThread;
+ BounceC.SyncThread -> SyncThread;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This application is derived from a similar application in the TinyThread
+ * implementation by William P. McCartney from Cleveland State University (2006)
+ *
+ * This application implements a threaded approach to bouncing messages back and forth
+ * between two motes. To run it you will need to burn one mote with node ID 0, and a
+ * second mote with node ID 1. Three different threads run that each send a
+ * message and then wait to receive a message before sending their next one. After
+ * each message reception, an LED is toggled to indicate that it was received. Thread
+ * 0 blinks led0, thread 1 blinks led1, and thread 2 blinks led2. The three
+ * threads run independently, and three different messages are bounced back and
+ * forth between the two motes in an unsynchronized fashion. In contrast to the simple
+ * Bounce application also found in this directory, once a thread receives a message
+ * it waits on a Barrier before continuing on and turning on its led. A synchronization
+ * thread is used to wait until all three messages have been received before unblocking
+ * the barrier. In this way, messages are still bounced back and forth between the
+ * two motes in an asynchronous fashion, but all leds come on at the same time
+ * because of the Barrier and the synchronization thread. The effect is that all three
+ * leds on one mote flash in unison, followed by all three on the other mote back
+ * and forth forever.
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+module BarrierBounceC {
+ uses {
+ interface Boot;
+ interface BlockingStdControl as BlockingAMControl;
+ interface Barrier;
+
+ interface Thread as BounceThread0;
+ interface BlockingAMSend as BlockingAMSend0;
+ interface BlockingReceive as BlockingReceive0;
+
+ interface Thread as BounceThread1;
+ interface BlockingAMSend as BlockingAMSend1;
+ interface BlockingReceive as BlockingReceive1;
+
+ interface Thread as BounceThread2;
+ interface BlockingAMSend as BlockingAMSend2;
+ interface BlockingReceive as BlockingReceive2;
+
+ interface Thread as SyncThread;
+
+ interface Leds;
+ }
+}
+
+implementation {
+ message_t m0,m1,m2;
+ barrier_t b0;
+
+ event void Boot.booted() {
+ //Reset all barriers used in this program at initialization
+ call Barrier.reset(&b0, 4);
+
+ //Start the sync thread to power up the AM layer
+ call SyncThread.start(NULL);
+ }
+
+ event void BounceThread0.run(void* arg) {
+ for(;;) {
+ call Leds.led0Off();
+ call BlockingAMSend0.send(!TOS_NODE_ID, &m0, 0);
+ if(call BlockingReceive0.receive(&m0, 5000) == SUCCESS) {
+ call Barrier.block(&b0);
+ call Leds.led0On();
+ call BounceThread0.sleep(500);
+ }
+ }
+ }
+
+ event void BounceThread1.run(void* arg) {
+ for(;;) {
+ call Leds.led1Off();
+ call BlockingAMSend1.send(!TOS_NODE_ID, &m1, 0);
+ if(call BlockingReceive1.receive(&m1, 5000) == SUCCESS) {
+ call Barrier.block(&b0);
+ call Leds.led1On();
+ call BounceThread1.sleep(500);
+ }
+ }
+ }
+
+ event void BounceThread2.run(void* arg) {
+ for(;;) {
+ call Leds.led2Off();
+ call BlockingAMSend2.send(!TOS_NODE_ID, &m2, 0);
+ if(call BlockingReceive2.receive(&m2, 5000) == SUCCESS) {
+ call Barrier.block(&b0);
+ call Leds.led2On();
+ call BounceThread2.sleep(500);
+ }
+ }
+ }
+
+ event void SyncThread.run(void* arg) {
+ //Once the am layer is powered on, start the rest of
+ // the threads
+ call BlockingAMControl.start();
+ call BounceThread0.start(NULL);
+ call BounceThread1.start(NULL);
+ call BounceThread2.start(NULL);
+
+ for(;;) {
+ call Barrier.block(&b0);
+ call Barrier.reset(&b0, 4);
+ }
+ }
+}
--- /dev/null
+COMPONENT=BarrierBounceAppC
+PFLAGS += -DCC2420_HW_ACKNOWLEDGEMENTS
+include $(MAKERULES)
--- /dev/null
+ /*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Header file for declaring AM types for Bounce messages
+ * in the BarrierBounce application
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#ifndef BARRIER_BOUNCE_H
+#define BARRIER_BOUNCE_H
+
+enum {
+ AM_BOUNCE0_MSG = 0x90,
+ AM_BOUNCE1_MSG = 0x91,
+ AM_BOUNCE2_MSG = 0x92,
+};
+
+#endif //BARRIER_BOUNCE_H
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#ifndef BARRIER_BOUNCE_APP_STACK_H
+#define BARRIER_BOUNCE_APP_STACK_H
+
+enum {
+ BOUNCE_THREAD0_STACK_SIZE = 600,
+ BOUNCE_THREAD1_STACK_SIZE = 600,
+ BOUNCE_THREAD2_STACK_SIZE = 600,
+ SYNC_THREAD_STACK_SIZE = 600,
+};
+
+#endif //BARRIER_BOUNCE_APP_STACK_H
--- /dev/null
+#-*-makefile-*-
+######################################################################
+#
+# Makes the entire suite of TinyOS applications for a given platform.
+#
+# Author: Martin Turon
+# Date: August 18, 2005
+#
+######################################################################
+# $Id$
+
+# MAKECMDGOALS is the way to get the arguments passed into a Makefile ...
+TARGET=$(MAKECMDGOALS)
+NESDOC_TARGET=$(filter-out nesdoc,$(TARGET))
+
+# Here is a way to get the list of subdirectories in a Makefile ...
+ROOT=.
+SUBDIRS := $(shell find * -type d)
+
+# Okay, match any target, and recurse the subdirectories
+%:
+ @for i in $(SUBDIRS); do \
+ HERE=$$PWD; \
+ if [ -f $$i/Makefile ]; then \
+ echo Building ... $(PWD)/$$i; \
+ echo make $(TARGET); \
+ cd $$i; \
+ $(MAKE) $(TARGET); \
+ cd $$HERE; \
+ fi; \
+ done
+
+threads:
+ @:
+cthreads:
+ @:
+dynthreads:
+ @:
+
+BASEDIR = $(shell pwd | sed 's@\(.*\)/apps.*$$@\1@' )
+# The output directory for generated documentation
+DOCDIR = $(BASEDIR)/doc/nesdoc
+
+nesdoc:
+ @echo This target rebuilds documentation for all known platforms.
+ @echo It DOES NOT overwrite any existing documentation, thus, it
+ @echo is best run after deleting all old documentation.
+ @echo
+ @echo To delete all old documentation, delete the contents of the
+ @echo $(DOCDIR) directory.
+ @echo
+ @echo Press Enter to continue, or ^C to abort.
+ @read
+ for platform in `ncc -print-platforms`; do \
+ $(MAKE) $$platform docs.nohtml.preserve; \
+ nesdoc -o $(DOCDIR) -html -target=$$platform; \
+ done
--- /dev/null
+COMPONENT=RadioStressAppC
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This application stresses the blocking send and receive commands for the TinyOS
+ * thread implementation. Three threads are run, each thread toggling a different
+ * colored LED. If a node has TOS_NODE_ID == 0 it will try and receive in
+ * an infinite loop, toggling one of the three Leds upon reception. If it has
+ * TOS_NODE_ID == 1, it will try to send in an infinite loop, toggling one of the three
+ * Leds upon the completion of a send. Thread 0 toggles the Led0, Thread 1 toggles
+ * Led1, and Thread 2 toggles Led2.
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+configuration RadioStressAppC {
+}
+implementation {
+ components MainC, RadioStressC, LedsC;
+ components BlockingActiveMessageC;
+ MainC.Boot <- RadioStressC;
+ RadioStressC.BlockingAMControl -> BlockingActiveMessageC;
+ RadioStressC.Leds -> LedsC;
+
+ components new ThreadC(300) as RadioStressThread0;
+ components new BlockingAMSenderC(20) as BlockingAMSender0;
+ components new BlockingAMReceiverC(20) as BlockingAMReceiver0;
+ RadioStressC.RadioStressThread0 -> RadioStressThread0;
+ RadioStressC.BlockingAMSend0 -> BlockingAMSender0;
+ RadioStressC.BlockingReceive0 -> BlockingAMReceiver0;
+
+ components new ThreadC(300) as RadioStressThread1;
+ components new BlockingAMSenderC(21) as BlockingAMSender1;
+ components new BlockingAMReceiverC(21) as BlockingAMReceiver1;
+ RadioStressC.RadioStressThread1 -> RadioStressThread1;
+ RadioStressC.BlockingAMSend1 -> BlockingAMSender1;
+ RadioStressC.BlockingReceive1 -> BlockingAMReceiver1;
+
+ components new ThreadC(300) as RadioStressThread2;
+ components new BlockingAMSenderC(22) as BlockingAMSender2;
+ components new BlockingAMReceiverC(22) as BlockingAMReceiver2;
+ RadioStressC.RadioStressThread2 -> RadioStressThread2;
+ RadioStressC.BlockingAMSend2 -> BlockingAMSender2;
+ RadioStressC.BlockingReceive2 -> BlockingAMReceiver2;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This application stresses the blocking send and receive commands for the TinyOS
+ * thread implementation. Three threads are run, each thread toggling a different
+ * colored LED. If a node has TOS_NODE_ID == 0 it will try and receive in
+ * an infinite loop, toggling one of the three Leds upon reception. If it has
+ * TOS_NODE_ID == 1, it will try to send in an infinite loop, toggling one of the three
+ * Leds upon the completion of a send. Thread 0 toggles the Led0, Thread 1 toggles
+ * Led1, and Thread 2 toggles Led2.
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#include "AM.h"
+
+module RadioStressC {
+ uses {
+ interface Boot;
+ interface BlockingStdControl as BlockingAMControl;
+
+ interface Thread as RadioStressThread0;
+ interface BlockingAMSend as BlockingAMSend0;
+ interface BlockingReceive as BlockingReceive0;
+
+ interface Thread as RadioStressThread1;
+ interface BlockingAMSend as BlockingAMSend1;
+ interface BlockingReceive as BlockingReceive1;
+
+ interface Thread as RadioStressThread2;
+ interface BlockingAMSend as BlockingAMSend2;
+ interface BlockingReceive as BlockingReceive2;
+
+ interface Leds;
+ }
+}
+
+implementation {
+ message_t m0;
+ message_t m1;
+ message_t m2;
+
+ event void Boot.booted() {
+ call RadioStressThread0.start(NULL);
+ call RadioStressThread1.start(NULL);
+ call RadioStressThread2.start(NULL);
+ }
+
+ event void RadioStressThread0.run(void* arg) {
+ call BlockingAMControl.start();
+ for(;;) {
+ if(TOS_NODE_ID == 0) {
+ call BlockingReceive0.receive(&m0, 5000);
+ call Leds.led0Toggle();
+ }
+ else {
+ call BlockingAMSend0.send(!TOS_NODE_ID, &m0, 0);
+ call Leds.led0Toggle();
+ //call RadioStressThread0.sleep(500);
+ }
+ }
+ }
+
+ event void RadioStressThread1.run(void* arg) {
+ call BlockingAMControl.start();
+ for(;;) {
+ if(TOS_NODE_ID == 0) {
+ call BlockingReceive1.receive(&m1, 5000);
+ call Leds.led1Toggle();
+ }
+ else {
+ call BlockingAMSend1.send(!TOS_NODE_ID, &m1, 0);
+ call Leds.led1Toggle();
+ //call RadioStressThread1.sleep(500);
+ }
+ }
+ }
+
+ event void RadioStressThread2.run(void* arg) {
+ call BlockingAMControl.start();
+ for(;;) {
+ if(TOS_NODE_ID == 0) {
+ call BlockingReceive2.receive(&m2, 5000);
+ call Leds.led2Toggle();
+ }
+ else {
+ call BlockingAMSend2.send(!TOS_NODE_ID, &m2, 0);
+ call Leds.led2Toggle();
+ //call RadioStressThread2.sleep(500);
+ }
+ }
+ }
+}
--- /dev/null
+COMPONENT=SerialCompressAppC
+
+CFLAGS += -I../bcl-1.2.0/src
+
+include $(MAKERULES)
--- /dev/null
+#include "StorageVolumes.h"
+
+configuration SerialCompressAppC {}
+
+implementation
+{
+ components MainC,
+ LedsC,
+ SerialActiveMessageC,
+ new SerialAMReceiverC(0x25),
+ new SerialAMSenderC(0x25),
+ new LogStorageC(VOLUME_SENSORLOG, TRUE),
+ SerialCompressP;
+
+ SerialCompressP.Boot -> MainC;
+ SerialCompressP.Leds -> LedsC;
+ SerialCompressP.LogRead -> LogStorageC;
+ SerialCompressP.LogWrite -> LogStorageC;
+ SerialCompressP.SerialSplitControl -> SerialActiveMessageC;
+ SerialCompressP.AMSend -> SerialAMSenderC;
+ SerialCompressP.Receive -> SerialAMReceiverC;
+ SerialCompressP.AMPacket -> SerialActiveMessageC;
+}
--- /dev/null
+#include "lz.c"
+#include "lz.h"
+
+#define NUM_RECORDS_TO_COMPRESS 50
+
+module SerialCompressP {
+ uses {
+ interface Boot;
+ interface Leds;
+ interface LogRead;
+ interface LogWrite;
+ interface SplitControl as SerialSplitControl;
+ interface Receive;
+ interface AMSend;
+ interface AMPacket;
+ }
+}
+
+implementation {
+ typedef nx_struct serial_data {
+ nx_uint32_t pktNum;
+ nx_uint8_t data[0];
+ } serial_data_t;
+
+ serial_data_t *writeEntry;
+ bool isBusy_writeEntry = FALSE;
+ serial_data_t *readEntry;
+ bool isBusy_readEntry = FALSE;
+
+ uint16_t numRecords = 0;
+ uint16_t MAX_SERIAL_DATA_LENGTH = TOSH_DATA_LENGTH - sizeof(serial_data_t);
+ uint32_t expectedPktNum = 0;
+ uint32_t pktLoss = 0;
+ //uint8_t in[NUM_RECORDS_TO_COMPRESS * MAX_SERIAL_DATA_LENGTH];
+ //uint8_t out[((NUM_RECORDS_TO_COMPRESS * MAX_SERIAL_DATA_LENGTH * 257 - 1) / 256) + 1 + 1];
+ uint8_t *in;
+ uint8_t *out;
+
+ message_t mesg;
+
+ event void AMSend.sendDone(message_t *msg, error_t error) {}
+
+ event void Boot.booted()
+ {
+ call Leds.set(7);
+ writeEntry = (serial_data_t *)malloc(TOSH_DATA_LENGTH);
+ readEntry = (serial_data_t *)malloc(TOSH_DATA_LENGTH);
+ in = malloc(NUM_RECORDS_TO_COMPRESS * MAX_SERIAL_DATA_LENGTH);
+ out = malloc(NUM_RECORDS_TO_COMPRESS * MAX_SERIAL_DATA_LENGTH * 2);
+ while (call LogWrite.erase() != SUCCESS) {}
+ }
+
+ event message_t* Receive.receive(message_t *msg, void *msg_payload, uint8_t len)
+ {
+ if (isBusy_writeEntry == FALSE) {
+ serial_data_t *payload = (serial_data_t *)msg_payload;
+
+ writeEntry->pktNum = payload->pktNum;
+ memcpy(writeEntry->data, payload->data, MAX_SERIAL_DATA_LENGTH);
+
+ if (payload->pktNum == 0xFFFFFFFF) {
+ uint8_t *p = (uint8_t *) call AMSend.getPayload(&mesg, 4);
+ p[0] = (pktLoss >> 24) & 0xFF;
+ p[1] = (pktLoss >> 16) & 0xFF;
+ p[2] = (pktLoss >> 8) & 0xFF;
+ p[3] = pktLoss & 0xFF;
+ call AMSend.send(AM_BROADCAST_ADDR, &mesg, 4);
+ } else if (payload->pktNum != expectedPktNum) {
+ pktLoss += payload->pktNum - expectedPktNum;
+ call Leds.led1Toggle();
+ }
+ expectedPktNum = payload->pktNum + 1;
+
+ if (call LogWrite.append(writeEntry, TOSH_DATA_LENGTH) == SUCCESS) {
+ isBusy_writeEntry = TRUE;
+ }
+ }
+
+ return msg;
+ }
+
+ task void processLog()
+ {
+ if (call LogRead.currentOffset() < call LogWrite.currentOffset()) {
+ if (isBusy_readEntry == FALSE) {
+ if (call LogRead.read(readEntry, TOSH_DATA_LENGTH) == SUCCESS) {
+ isBusy_readEntry = TRUE;
+ } else {
+ post processLog();
+ }
+ }
+ }
+ }
+
+ task void readDoneTask()
+ {
+ memcpy(&(in[numRecords * MAX_SERIAL_DATA_LENGTH]), readEntry->data, MAX_SERIAL_DATA_LENGTH);
+ numRecords++;
+
+ if (numRecords == NUM_RECORDS_TO_COMPRESS) {
+ call Leds.led2Toggle();
+ LZ_Compress(in, out, NUM_RECORDS_TO_COMPRESS * MAX_SERIAL_DATA_LENGTH);
+ numRecords = 0;
+ }
+
+ isBusy_readEntry = FALSE;
+ post processLog();
+ }
+
+ event void LogRead.readDone(void* buf, storage_len_t len, error_t error)
+ {
+ if (error == SUCCESS) {
+ post readDoneTask();
+ } else {
+ isBusy_readEntry = FALSE;
+ post processLog();
+ }
+ }
+
+ event void LogWrite.appendDone(void* buf, storage_len_t len, bool recordsLost, error_t error)
+ {
+ isBusy_writeEntry = FALSE;
+
+ if (error == SUCCESS) {
+ post processLog();
+ }
+ }
+
+ event void LogWrite.eraseDone(error_t error)
+ {
+ if (error == SUCCESS) {
+ while (call SerialSplitControl.start() != SUCCESS) {}
+ } else {
+ while (call LogWrite.erase() != SUCCESS) {}
+ }
+ }
+
+ event void LogRead.seekDone(error_t error) {}
+
+ event void SerialSplitControl.startDone(error_t error)
+ {
+ if (error == SUCCESS) {
+ call Leds.set(0);
+ } else {
+ while (call SerialSplitControl.start() != SUCCESS) {}
+ }
+ }
+
+ event void SerialSplitControl.stopDone(error_t error) {}
+ event void LogWrite.syncDone(error_t error) {}
+}
--- /dev/null
+/*************************************************************************
+* Name: lz.c
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder implementation.
+* Reentrant: Yes
+*
+* The LZ77 compression scheme is a substitutional compression scheme
+* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
+* its design, and uses no fancy bit level compression.
+*
+* This is my first attempt at an implementation of a LZ77 code/decoder.
+*
+* The principle of the LZ77 compression algorithm is to store repeated
+* occurrences of strings as references to previous occurrences of the same
+* string. The point is that the reference consumes less space than the
+* string itself, provided that the string is long enough (in this
+* implementation, the string has to be at least 4 bytes long, since the
+* minimum coded reference is 3 bytes long). Also note that the term
+* "string" refers to any kind of byte sequence (it does not have to be
+* an ASCII string, for instance).
+*
+* The coder uses a brute force approach to finding string matches in the
+* history buffer (or "sliding window", if you wish), which is very, very
+* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
+* depending on the input data.
+*
+* There is also a faster implementation that uses a large working buffer
+* in which a "jump table" is stored, which is used to quickly find
+* possible string matches (see the source code for LZ_CompressFast() for
+* more information). The faster method is an order of magnitude faster,
+* but still quite slow compared to other compression methods.
+*
+* The upside is that decompression is very fast, and the compression ratio
+* is often very good.
+*
+* The reference to a string is coded as a (length,offset) pair, where the
+* length indicates the length of the string, and the offset gives the
+* offset from the current data position. To distinguish between string
+* references and literal strings (uncompressed bytes), a string reference
+* is preceded by a marker byte, which is chosen as the least common byte
+* symbol in the input data stream (this marker byte is stored in the
+* output stream as the first byte).
+*
+* Occurrences of the marker byte in the stream are encoded as the marker
+* byte followed by a zero byte, which means that occurrences of the marker
+* byte have to be coded with two bytes.
+*
+* The lengths and offsets are coded in a variable length fashion, allowing
+* values of any magnitude (up to 4294967295 in this implementation).
+*
+* With this compression scheme, the worst case compression result is
+* (257/256)*insize + 1.
+*
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+
+/*************************************************************************
+* Constants used for LZ77 coding
+*************************************************************************/
+
+/* Maximum offset (can be any size < 2^31). Lower values give faster
+ compression, while higher values gives better compression. The default
+ value of 100000 is quite high. Experiment to see what works best for
+ you. */
+#define LZ_MAX_OFFSET 100000
+
+
+
+/*************************************************************************
+* INTERNAL FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* _LZ_StringCompare() - Return maximum length string match.
+*************************************************************************/
+
+static uint32_t _LZ_StringCompare( unsigned char * str1,
+ unsigned char * str2, uint32_t minlen, uint32_t maxlen )
+{
+ uint32_t len;
+
+ for( len = minlen; (len < maxlen) && (str1[len] == str2[len]); ++ len );
+
+ return len;
+}
+
+
+/*************************************************************************
+* _LZ_WriteVarSize() - Write uint32_teger with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_WriteVarSize( uint32_t x, unsigned char * buf )
+{
+ uint32_t y;
+ int num_bytes, i, b;
+
+ /* Determine number of bytes needed to store the number x */
+ y = x >> 3;
+ for( num_bytes = 5; num_bytes >= 2; -- num_bytes )
+ {
+ if( y & 0xfe000000 ) break;
+ y <<= 7;
+ }
+
+ /* Write all bytes, seven bits in each, with 8:th bit set for all */
+ /* but the last byte. */
+ for( i = num_bytes-1; i >= 0; -- i )
+ {
+ b = (x >> (i*7)) & 0x0000007f;
+ if( i > 0 )
+ {
+ b |= 0x00000080;
+ }
+ *buf ++ = (unsigned char) b;
+ }
+
+ /* Return number of bytes written */
+ return num_bytes;
+}
+
+
+/*************************************************************************
+* _LZ_ReadVarSize() - Read uint32_teger with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_ReadVarSize( uint32_t * x, unsigned char * buf )
+{
+ uint32_t y, b, num_bytes;
+
+ /* Read complete value (stop when byte contains zero in 8:th bit) */
+ y = 0;
+ num_bytes = 0;
+ do
+ {
+ b = (uint32_t) (*buf ++);
+ y = (y << 7) | (b & 0x0000007f);
+ ++ num_bytes;
+ }
+ while( b & 0x00000080 );
+
+ /* Store value in x */
+ *x = y;
+
+ /* Return number of bytes read */
+ return num_bytes;
+}
+
+
+
+/*************************************************************************
+* PUBLIC FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* LZ_Compress() - Compress a block of data using an LZ77 coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 0.4% larger
+* than the input buffer, plus one byte.
+* insize - Number of input bytes.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+int LZ_Compress( unsigned char *in, unsigned char *out,
+ uint32_t insize )
+{
+ unsigned char marker, symbol;
+ uint32_t inpos, outpos, bytesleft, i;
+ uint32_t maxoffset, offset, bestoffset;
+ uint32_t maxlength, length, bestlength;
+ uint32_t histogram[ 256 ];
+ unsigned char *ptr1, *ptr2;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Create histogram */
+ for( i = 0; i < 256; ++ i )
+ {
+ histogram[ i ] = 0;
+ }
+ for( i = 0; i < insize; ++ i )
+ {
+ ++ histogram[ in[ i ] ];
+ }
+
+ /* Find the least common byte, and use it as the marker symbol */
+ marker = 0;
+ for( i = 1; i < 256; ++ i )
+ {
+ if( histogram[ i ] < histogram[ marker ] )
+ {
+ marker = i;
+ }
+ }
+
+ /* Remember the marker symbol for the decoder */
+ out[ 0 ] = marker;
+
+ /* Start of compression */
+ inpos = 0;
+ outpos = 1;
+
+ /* Main compression loop */
+ bytesleft = insize;
+ do
+ {
+ /* Determine most distant position */
+ if( inpos > LZ_MAX_OFFSET ) {
+ maxoffset = LZ_MAX_OFFSET;
+ }
+ else {
+ maxoffset = inpos;
+ }
+
+ /* Get pointer to current position */
+ ptr1 = &in[ inpos ];
+
+ /* Search history window for maximum length string match */
+ bestlength = 3;
+ bestoffset = 0;
+ for( offset = 3; offset <= maxoffset; ++ offset )
+ {
+ /* Get pointer to candidate string */
+ ptr2 = &ptr1[ -(int)offset ];
+
+ /* Quickly determine if this is a candidate (for speed) */
+ if( (ptr1[ 0 ] == ptr2[ 0 ]) &&
+ (ptr1[ bestlength ] == ptr2[ bestlength ]) )
+ {
+ /* Determine maximum length for this offset */
+ maxlength = (bytesleft < offset ? bytesleft : offset);
+
+ /* Count maximum length match at this offset */
+ length = _LZ_StringCompare( ptr1, ptr2, 0, maxlength );
+
+ /* Better match than any previous match? */
+ if( length > bestlength )
+ {
+ bestlength = length;
+ bestoffset = offset;
+ }
+ }
+ }
+
+ /* Was there a good enough match? */
+ if( (bestlength >= 8) ||
+ ((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
+ ((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
+ ((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
+ ((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
+ {
+ out[ outpos ++ ] = (unsigned char) marker;
+ outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
+ outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
+ inpos += bestlength;
+ bytesleft -= bestlength;
+ }
+ else
+ {
+ /* Output single byte (or two bytes if marker byte) */
+ symbol = in[ inpos ++ ];
+ out[ outpos ++ ] = symbol;
+ if( symbol == marker )
+ {
+ out[ outpos ++ ] = 0;
+ }
+ -- bytesleft;
+ }
+ }
+ while( bytesleft > 3 );
+
+ /* Dump remaining bytes, if any */
+ while( inpos < insize )
+ {
+ if( in[ inpos ] == marker )
+ {
+ out[ outpos ++ ] = marker;
+ out[ outpos ++ ] = 0;
+ }
+ else
+ {
+ out[ outpos ++ ] = in[ inpos ];
+ }
+ ++ inpos;
+ }
+
+ return outpos;
+}
+
+
+/*************************************************************************
+* LZ_CompressFast() - Compress a block of data using an LZ77 coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 0.4% larger
+* than the input buffer, plus one byte.
+* insize - Number of input bytes.
+* work - Pointer to a temporary buffer (internal working buffer), which
+* must be able to hold (insize+65536) uint32_tegers.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+int LZ_CompressFast( unsigned char *in, unsigned char *out,
+ uint32_t insize, uint32_t *work )
+{
+ unsigned char marker, symbol;
+ uint32_t inpos, outpos, bytesleft, i, index, symbols;
+ uint32_t offset, bestoffset;
+ uint32_t maxlength, length, bestlength;
+ uint32_t histogram[ 256 ], *lastindex, *jumptable;
+ unsigned char *ptr1, *ptr2;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Assign arrays to the working area */
+ lastindex = work;
+ jumptable = &work[ 65536 ];
+
+ /* Build a "jump table". Here is how the jump table works:
+ jumptable[i] points to the nearest previous occurrence of the same
+ symbol pair as in[i]:in[i+1], so in[i] == in[jumptable[i]] and
+ in[i+1] == in[jumptable[i]+1], and so on... Following the jump table
+ gives a dramatic boost for the string search'n'match loop compared
+ to doing a brute force search. The jump table is built in O(n) time,
+ so it is a cheap operation in terms of time, but it is expensice in
+ terms of memory consumption. */
+ for( i = 0; i < 65536; ++ i )
+ {
+ lastindex[ i ] = 0xffffffff;
+ }
+ for( i = 0; i < insize-1; ++ i )
+ {
+ symbols = (((uint32_t)in[i]) << 8) | ((uint32_t)in[i+1]);
+ index = lastindex[ symbols ];
+ lastindex[ symbols ] = i;
+ jumptable[ i ] = index;
+ }
+ jumptable[ insize-1 ] = 0xffffffff;
+
+ /* Create histogram */
+ for( i = 0; i < 256; ++ i )
+ {
+ histogram[ i ] = 0;
+ }
+ for( i = 0; i < insize; ++ i )
+ {
+ ++ histogram[ in[ i ] ];
+ }
+
+ /* Find the least common byte, and use it as the marker symbol */
+ marker = 0;
+ for( i = 1; i < 256; ++ i )
+ {
+ if( histogram[ i ] < histogram[ marker ] )
+ {
+ marker = i;
+ }
+ }
+
+ /* Remember the marker symbol for the decoder */
+ out[ 0 ] = marker;
+
+ /* Start of compression */
+ inpos = 0;
+ outpos = 1;
+
+ /* Main compression loop */
+ bytesleft = insize;
+ do
+ {
+ /* Get pointer to current position */
+ ptr1 = &in[ inpos ];
+
+ /* Search history window for maximum length string match */
+ bestlength = 3;
+ bestoffset = 0;
+ index = jumptable[ inpos ];
+ while( (index != 0xffffffff) && ((inpos - index) < LZ_MAX_OFFSET) )
+ {
+ /* Get pointer to candidate string */
+ ptr2 = &in[ index ];
+
+ /* Quickly determine if this is a candidate (for speed) */
+ if( ptr2[ bestlength ] == ptr1[ bestlength ] )
+ {
+ /* Determine maximum length for this offset */
+ offset = inpos - index;
+ maxlength = (bytesleft < offset ? bytesleft : offset);
+
+ /* Count maximum length match at this offset */
+ length = _LZ_StringCompare( ptr1, ptr2, 2, maxlength );
+
+ /* Better match than any previous match? */
+ if( length > bestlength )
+ {
+ bestlength = length;
+ bestoffset = offset;
+ }
+ }
+
+ /* Get next possible index from jump table */
+ index = jumptable[ index ];
+ }
+
+ /* Was there a good enough match? */
+ if( (bestlength >= 8) ||
+ ((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
+ ((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
+ ((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
+ ((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
+ {
+ out[ outpos ++ ] = (unsigned char) marker;
+ outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
+ outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
+ inpos += bestlength;
+ bytesleft -= bestlength;
+ }
+ else
+ {
+ /* Output single byte (or two bytes if marker byte) */
+ symbol = in[ inpos ++ ];
+ out[ outpos ++ ] = symbol;
+ if( symbol == marker )
+ {
+ out[ outpos ++ ] = 0;
+ }
+ -- bytesleft;
+ }
+ }
+ while( bytesleft > 3 );
+
+ /* Dump remaining bytes, if any */
+ while( inpos < insize )
+ {
+ if( in[ inpos ] == marker )
+ {
+ out[ outpos ++ ] = marker;
+ out[ outpos ++ ] = 0;
+ }
+ else
+ {
+ out[ outpos ++ ] = in[ inpos ];
+ }
+ ++ inpos;
+ }
+
+ return outpos;
+}
+
+
+/*************************************************************************
+* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
+* in - Input (compressed) buffer.
+* out - Output (uncompressed) buffer. This buffer must be large
+* enough to hold the uncompressed data.
+* insize - Number of input bytes.
+*************************************************************************/
+
+void LZ_Uncompress( unsigned char *in, unsigned char *out,
+ uint32_t insize )
+{
+ unsigned char marker, symbol;
+ uint32_t i, inpos, outpos, length, offset;
+
+ /* Do we have anything to uncompress? */
+ if( insize < 1 )
+ {
+ return;
+ }
+
+ /* Get marker symbol from input stream */
+ marker = in[ 0 ];
+ inpos = 1;
+
+ /* Main decompression loop */
+ outpos = 0;
+ do
+ {
+ symbol = in[ inpos ++ ];
+ if( symbol == marker )
+ {
+ /* We had a marker byte */
+ if( in[ inpos ] == 0 )
+ {
+ /* It was a single occurrence of the marker byte */
+ out[ outpos ++ ] = marker;
+ ++ inpos;
+ }
+ else
+ {
+ /* Extract true length and offset */
+ inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
+ inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
+
+ /* Copy corresponding data from history window */
+ for( i = 0; i < length; ++ i )
+ {
+ out[ outpos ] = out[ outpos - offset ];
+ ++ outpos;
+ }
+ }
+ }
+ else
+ {
+ /* No marker, plain copy */
+ out[ outpos ++ ] = symbol;
+ }
+ }
+ while( inpos < insize );
+}
--- /dev/null
+/*************************************************************************
+* Name: lz.h
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder interface.
+* Reentrant: Yes
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+#ifndef _lz_h_
+#define _lz_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*************************************************************************
+* Function prototypes
+*************************************************************************/
+
+int LZ_Compress( unsigned char *in, unsigned char *out,
+ uint32_t insize );
+int LZ_CompressFast( unsigned char *in, unsigned char *out,
+ uint32_t insize, uint32_t *work );
+void LZ_Uncompress( unsigned char *in, unsigned char *out,
+ uint32_t insize );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _lz_h_ */
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="262144" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="1048576" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+COMPONENT=TestBlockStorageAppC
+
+include $(MAKERULES)
--- /dev/null
+This program erases volume, then randomly write (then verified by read).
+Led0 is ON during the test, and Led1 is ON if all tests pass. If there is a problem, all three LEDs will be ON.
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "StorageVolumes.h"
+
+configuration TestBlockStorageAppC {}
+
+implementation
+{
+ components MainC,
+ TestBlockStorageP,
+ LedsC,
+ new ThreadC(500) as TinyThread1,
+ new BlockingBlockStorageC(VOLUME_TESTBLOCKSTORAGE1) as BlockingBlockStorage1,
+ RandomC;
+
+ TestBlockStorageP.Boot -> MainC;
+ TestBlockStorageP.Leds -> LedsC;
+ TestBlockStorageP.BlockingBlock1 -> BlockingBlockStorage1;
+ TestBlockStorageP.TinyThread1 -> TinyThread1;
+ TestBlockStorageP.Random -> RandomC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "Storage.h"
+
+module TestBlockStorageP
+{
+ uses {
+ interface Boot;
+ interface Leds;
+ interface Thread as TinyThread1;
+ interface BlockingBlock as BlockingBlock1;
+ interface Random;
+ }
+}
+
+implementation
+{
+ event void Boot.booted() {
+ call TinyThread1.start(NULL);
+ }
+
+ event void TinyThread1.run(void* arg)
+ {
+ int i;
+ error_t error;
+
+ call Leds.set(1);
+
+ if (call BlockingBlock1.getSize() != 1048576) {
+ call Leds.set(7);
+ return;
+ }
+
+ error = call BlockingBlock1.erase();
+ if (error != SUCCESS) {
+ call Leds.set(7);
+ return;
+ }
+
+ for (i = 0; i < 20; i++) {
+ storage_addr_t writeAddr = call Random.rand32() % (call BlockingBlock1.getSize() - sizeof(storage_addr_t));
+ storage_len_t len = sizeof(storage_addr_t);
+ storage_addr_t readBuf;
+
+ error = call BlockingBlock1.write(writeAddr, &writeAddr, &len);
+ if (error == SUCCESS) {
+ len = sizeof(storage_addr_t);
+ call BlockingBlock1.read(writeAddr, &readBuf, &len);
+ if (readBuf != writeAddr) {
+ call Leds.set(7);
+ return;
+ }
+ } else {
+ call Leds.set(7);
+ return;
+ }
+ }
+
+ call Leds.set(2);
+ }
+}
--- /dev/null
+<volume_table>
+ <volume name="TESTBLOCKSTORAGE1" size="262144" type="block"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="TESTBLOCKSTORAGE1" size="1048576" type="block"/>
+</volume_table>
--- /dev/null
+COMPONENT=TestLogStorageAppC
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "StorageVolumes.h"
+
+configuration TestLogStorageAppC {}
+
+implementation
+{
+ components new BlockingLogStorageC(VOLUME_TESTLOGSTORAGE, TRUE);
+}
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "Storage.h"
+
+module TestLogStorageP
+{
+ uses {
+ interface Boot;
+ }
+}
+
+implementation
+{
+ event void Boot.booted() {
+ }
+}
--- /dev/null
+<volume_table>
+ <volume name="TESTLOGSTORAGE" size="262144" type="log" />
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="TESTLOGSTORAGE" size="1048576" type="log"/>
+</volume_table>
--- /dev/null
+COMPONENT=TestPrintfAppC
+PFLAGS += -I$(TOSDIR)/lib/tosthreads/lib/printf
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+#include "printf.h"
+
+configuration TestPrintfAppC {
+}
+implementation {
+ components MainC, TestPrintfC;
+ components PrintfC;
+ components new ThreadC(200);
+
+ MainC.Boot <- TestPrintfC;
+ TestPrintfC.Thread -> ThreadC;
+
+ components LedsC;
+ TestPrintfC.Leds -> LedsC;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+module TestPrintfC {
+ uses {
+ interface Boot;
+ interface Thread;
+ interface Leds;
+ }
+}
+
+implementation {
+ event void Boot.booted() {
+ call Thread.start(NULL);
+ }
+
+ event void Thread.run(void* arg) {
+ uint32_t counter = 0;
+ for(;;){
+ printf("Counter: %lu\n", counter++);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Base station implementation using tosthreads
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+//#include "stack.h"
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_amserial.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+
+#define MSG_QUEUE_SIZE 3
+
+//Parameters associated with each of the two base station paths
+// radio -> serial
+// serial -> radio
+typedef struct bs_params {
+ tosthread_t receive_handle;
+ tosthread_t snoop_handle;
+ tosthread_t send_handle;
+ mutex_t mutex;
+ condvar_t condvar;
+ message_t shared_msgs[MSG_QUEUE_SIZE];
+ uint8_t shared_msg_queue_size;
+ uint8_t shared_msg_queue_index;
+} bs_params_t;
+
+//Declare parameters associated with radio RX thread
+bs_params_t radioRx_params;
+void radioReceive_thread(void* arg);
+void radioSnoop_thread(void* arg);
+void serialSend_thread(void* arg);
+
+//Declare parameters associated with serial RX thread
+bs_params_t serialRx_params;
+void serialReceive_thread(void* arg);
+void radioSend_thread(void* arg);
+
+/********* Initialize base station parameters ********/
+void bs_params_init(bs_params_t* p) {
+ mutex_init( &(p->mutex) );
+ condvar_init( &(p->condvar) );
+ p->shared_msg_queue_size = 0;
+ p->shared_msg_queue_index = 0;
+}
+
+/*********** Main function thread ************/
+void tosthread_main(void* arg) {
+ bs_params_init( &radioRx_params );
+ bs_params_init( &serialRx_params );
+
+ amRadioStart();
+ amSerialStart();
+ tosthread_create(&(radioRx_params.receive_handle), radioReceive_thread, NULL, 200);
+ tosthread_create(&(radioRx_params.snoop_handle), radioSnoop_thread, NULL, 200);
+ tosthread_create(&(radioRx_params.send_handle), serialSend_thread, NULL, 200);
+ tosthread_create(&(serialRx_params.receive_handle), serialReceive_thread, NULL, 200);
+ tosthread_create(&(serialRx_params.send_handle), radioSend_thread, NULL, 200);
+}
+
+/******************** Enqueue and dequeue Messages ****************/
+error_t enqueueMsg(bs_params_t* p, message_t* m) {
+ if(p->shared_msg_queue_size < MSG_QUEUE_SIZE) {
+ (p->shared_msgs)[p->shared_msg_queue_index] = *m;
+ (p->shared_msg_queue_index) = (p->shared_msg_queue_index + 1) % MSG_QUEUE_SIZE;
+ (p->shared_msg_queue_size)++;
+ return SUCCESS;
+ }
+ return FAIL;
+}
+
+message_t* dequeueMsg(bs_params_t* p) {
+ if(p->shared_msg_queue_size > 0) {
+ message_t* m;
+ m = &((p->shared_msgs)[(p->shared_msg_queue_index + (MSG_QUEUE_SIZE - p->shared_msg_queue_size)) % MSG_QUEUE_SIZE]);
+ (p->shared_msg_queue_size)--;
+ return m;
+ }
+ return NULL;
+}
+
+/******************** Send Serial vs. Radio Messages ****************/
+error_t sendSerialMsg(message_t* msg) {
+ am_id_t id = amRadioGetType(msg);
+ am_addr_t source = amRadioGetSource(msg);
+ am_addr_t dest = amRadioGetDestination(msg);
+ uint8_t len = radioGetPayloadLength(msg);
+ serialClear(msg);
+ amSerialSetSource(msg, source);
+
+ return amSerialSend(dest, msg, len, id);
+}
+
+error_t sendRadioMsg(message_t* msg) {
+ am_id_t id = amSerialGetType(msg);
+ am_addr_t source = amSerialGetSource(msg);
+ am_addr_t dest = amSerialGetDestination(msg);
+ uint8_t len = serialGetPayloadLength(msg);
+ radioClear(msg);
+ amRadioSetSource(msg, source);
+
+ return amRadioSend(dest, msg, len, id);
+}
+
+
+/***********************************************************/
+/** Generic implementations of send/receive functionality **/
+/***********************************************************/
+void bs_receive(error_t (*recv_func)(message_t*, uint32_t, am_id_t), bs_params_t* p) {
+ message_t m;
+
+ for(;;) {
+ if( (*(recv_func))(&m, 0, AM_RECEIVE_FROM_ANY) == SUCCESS ) {
+ led0Toggle();
+
+ mutex_lock( &(p->mutex) );
+ while( enqueueMsg(p, &m) == FAIL )
+ condvar_wait( &(p->condvar), &(p->mutex) );
+ mutex_unlock( &(p->mutex) );
+ condvar_signalAll( &(p->condvar) );
+ }
+ else led2Toggle();
+ }
+}
+
+void bs_send(void* send_func, bs_params_t* p) {
+ message_t m;
+ message_t* m_ptr;
+
+ for(;;) {
+ mutex_lock( &(p->mutex) );
+ while( (m_ptr = dequeueMsg(p)) == NULL )
+ condvar_wait( &(p->condvar), &(p->mutex) );
+ m = *m_ptr;
+ mutex_unlock( &(p->mutex) );
+ condvar_signalAll( &(p->condvar) );
+
+ if(send_func == amSerialSend)
+ sendSerialMsg(&m);
+ else
+ sendRadioMsg(&m);
+ led1Toggle();
+ }
+}
+
+/******************** Actual thread implementations ******************/
+void radioReceive_thread(void* arg) {
+ bs_receive(amRadioReceive, &radioRx_params);
+}
+void radioSnoop_thread(void* arg) {
+ bs_receive(amRadioSnoop, &radioRx_params);
+}
+void serialSend_thread(void* arg) {
+ bs_send(amSerialSend, &radioRx_params);
+}
+void serialReceive_thread(void* arg) {
+ bs_receive(amSerialReceive, &serialRx_params);
+}
+void radioSend_thread(void* arg) {
+ bs_send(amRadioSend, &serialRx_params);
+}
--- /dev/null
+TOSTHREAD_MAIN=BaseStation.c
+CFLAGS += -DCC2420_NO_ACKNOWLEDGEMENTS
+CFLAGS += -DCC2420_NO_ADDRESS_RECOGNITION
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+#include "stack.h"
+#include "tosthread.h"
+#include "tosthread_leds.h"
+
+//Initialize variables associated with each thread
+tosthread_t blink0;
+tosthread_t blink1;
+tosthread_t blink2;
+
+void blink0_thread(void* arg);
+void blink1_thread(void* arg);
+void blink2_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ //Use stack estimator to calculate maximum stack size
+ // on a thread by thread basis
+ tosthread_create(&blink0, blink0_thread, NULL, BLINK0_STACK_SIZE);
+ tosthread_create(&blink1, blink1_thread, NULL, BLINK1_STACK_SIZE);
+ tosthread_create(&blink2, blink2_thread, NULL, BLINK2_STACK_SIZE);
+}
+
+void blink0_thread(void* arg) {
+ for(;;) {
+ led0Toggle();
+ tosthread_sleep(1000);
+ }
+}
+
+void blink1_thread(void* arg) {
+ for(;;) {
+ led1Toggle();
+ tosthread_sleep(1000);
+ }
+}
+
+void blink2_thread(void* arg) {
+ for(;;) {
+ led2Toggle();
+ tosthread_sleep(1000);
+ }
+}
--- /dev/null
+TOSTHREAD_MAIN=Blink.c
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+enum {
+ NOTHING_STACK_SIZE = 500,
+ BLINK0_STACK_SIZE = 500,
+ BLINK1_STACK_SIZE = 500,
+ BLINK2_STACK_SIZE = 500,
+};
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "tosthread.h"
+#include "tosthread_leds.h"
+#include "tosthread_amradio.h"
+
+//Initialize variables associated with each thread
+tosthread_t bounceThread0;
+tosthread_t bounceThread1;
+tosthread_t bounceThread2;
+
+void bounceThread0_start(void* arg);
+void bounceThread1_start(void* arg);
+void bounceThread2_start(void* arg);
+
+void tosthread_main(void* arg) {
+ amRadioStart();
+
+ tosthread_create(&bounceThread0, bounceThread0_start, NULL, 300);
+ tosthread_create(&bounceThread1, bounceThread1_start, NULL, 300);
+ tosthread_create(&bounceThread2, bounceThread2_start, NULL, 300);
+}
+
+void bounceThread0_start(void *arg) {
+ message_t msg0;
+
+ for(;;) {
+ while (amRadioSend(AM_BROADCAST_ADDR, &msg0, 0, 20) == EBUSY) {}
+ led0Off();
+
+ if(amRadioReceive(&msg0, 5000, 20) == SUCCESS) {
+ led0On();
+ }
+
+ tosthread_sleep(500);
+ }
+}
+
+void bounceThread1_start(void *arg) {
+ message_t msg1;
+
+ for(;;) {
+ while (amRadioSend(AM_BROADCAST_ADDR, &msg1, 0, 21) == EBUSY) {}
+ led1Off();
+
+ if(amRadioReceive(&msg1, 5000, 21) == SUCCESS) {
+ led1On();
+ }
+
+ tosthread_sleep(500);
+ }
+}
+
+void bounceThread2_start(void *arg) {
+ message_t msg2;
+
+ for(;;) {
+ while (amRadioSend(AM_BROADCAST_ADDR, &msg2, 0, 22) == EBUSY) {}
+ led2Off();
+
+ if(amRadioReceive(&msg2, 5000, 22) == SUCCESS) {
+ led2On();
+ }
+
+ tosthread_sleep(500);
+ }
+}
--- /dev/null
+TOSTHREAD_MAIN=Bounce.c
+
+include $(MAKERULES)
--- /dev/null
+#-*-makefile-*-
+######################################################################
+#
+# Makes the entire suite of TinyOS applications for a given platform.
+#
+# Author: Martin Turon
+# Date: August 18, 2005
+#
+######################################################################
+# $Id$
+
+# MAKECMDGOALS is the way to get the arguments passed into a Makefile ...
+TARGET=$(MAKECMDGOALS)
+NESDOC_TARGET=$(filter-out nesdoc,$(TARGET))
+
+# Here is a way to get the list of subdirectories in a Makefile ...
+ROOT=.
+SUBDIRS := $(shell find * -type d)
+
+# Okay, match any target, and recurse the subdirectories
+%:
+ @for i in $(SUBDIRS); do \
+ HERE=$$PWD; \
+ if [ -f $$i/Makefile ]; then \
+ echo Building ... $(PWD)/$$i; \
+ echo make $(TARGET); \
+ cd $$i; \
+ $(MAKE) $(TARGET); \
+ cd $$HERE; \
+ fi; \
+ done
+
+threads:
+ @:
+cthreads:
+ @:
+dynthreads:
+ @:
+
+BASEDIR = $(shell pwd | sed 's@\(.*\)/apps.*$$@\1@' )
+# The output directory for generated documentation
+DOCDIR = $(BASEDIR)/doc/nesdoc
+
+nesdoc:
+ @echo This target rebuilds documentation for all known platforms.
+ @echo It DOES NOT overwrite any existing documentation, thus, it
+ @echo is best run after deleting all old documentation.
+ @echo
+ @echo To delete all old documentation, delete the contents of the
+ @echo $(DOCDIR) directory.
+ @echo
+ @echo Press Enter to continue, or ^C to abort.
+ @read
+ for platform in `ncc -print-platforms`; do \
+ $(MAKE) $$platform docs.nohtml.preserve; \
+ nesdoc -o $(DOCDIR) -html -target=$$platform; \
+ done
--- /dev/null
+TOSTHREAD_MAIN=Null.c
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Johns Hopkins University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written
+ * agreement is hereby granted, provided that the above copyright
+ * notice, the (updated) modification history and the author appear in
+ * all copies of this source code.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA,
+ * OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * @author Chieh-Jan Mike Liang <cliang4@cs.jhu.edu>
+ */
+
+#include "tosthread.h"
+
+void tosthread_main(void* arg) {}
--- /dev/null
+TOSTHREAD_MAIN=RadioStress.c
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This application stresses the blocking send and receive commands for the c based
+ * API of tosthreads. Three threads are run, each thread toggling a different
+ * colored LED. If a node has TOS_NODE_ID == 0 it will try and receive in
+ * an infinite loop, toggling one of the three Leds upon reception. If it has
+ * TOS_NODE_ID == 1, it will try to send in an infinite loop, toggling one of the three
+ * Leds upon the completion of a send. Thread 0 toggles the Led0, Thread 1 toggles
+ * Led1, and Thread 2 toggles Led2.
+ *
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+//#include "stack.h"
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_leds.h"
+
+typedef nx_struct RadioCountMsg {
+ nx_uint16_t counter;
+} RadioCountMsg;
+
+enum {
+ AM_RADIOCOUNTMSG = 6,
+};
+
+//Initialize variables associated with the RadioStress thread
+tosthread_t timerHandle;
+tosthread_t receiveHandle;
+tosthread_t sendHandle;
+void timer_thread(void* arg);
+void receive_thread(void* arg);
+void send_thread(void* arg);
+
+//Initialize the message variable
+message_t send_packet;
+message_t receive_packet;
+
+//Initalize counter variables
+uint32_t txCounter = 0;
+uint32_t ackCounter = 0;
+uint32_t rxCounter = 0;
+int16_t timerCounter = -1;
+uint16_t errorCounter = 0;
+
+void tosthread_main(void* arg) {
+ led0On();
+ while( amRadioStart() != SUCCESS );
+ led1On();
+ tosthread_create(&timerHandle, timer_thread, NULL, 200);
+ tosthread_create(&receiveHandle, receive_thread, NULL, 200);
+}
+
+void sendPacket() {
+ RadioCountMsg* rcm = (RadioCountMsg*)radioGetPayload(&send_packet, sizeof(RadioCountMsg));
+ rcm->counter = txCounter;
+ while( amRadioSend(AM_BROADCAST_ADDR, &send_packet, 2, AM_RADIOCOUNTMSG) != SUCCESS )
+ errorCounter++;
+}
+
+void timer_thread(void* arg) {
+ tosthread_sleep(1000);
+ tosthread_create(&sendHandle, send_thread, NULL, 200);
+ for(;;) {
+ led2Toggle();
+ timerCounter++;
+ tosthread_sleep(1000);
+ sendPacket();
+ }
+}
+
+void receive_thread(void* arg) {
+ for(;;) {
+ amRadioReceive(&receive_packet, 0, AM_RADIOCOUNTMSG);
+ rxCounter++;
+ if ((rxCounter % 32) == 0) {
+ led0Toggle();
+ }
+ }
+}
+
+void send_thread(void* arg) {
+ for(;;) {
+ sendPacket();
+ txCounter++;
+ if (txCounter % 32 == 0) {
+ led1Toggle();
+ }
+ if ( radioWasAcked(&send_packet) ) {
+ ackCounter++;
+ if (ackCounter % 32 == 0) {
+ led2Toggle();
+ }
+ }
+ }
+}
--- /dev/null
+TOSTHREAD_MAIN=SenseAndSend.c
+CFLAGS += -I$(TOSDIR)/lib/tosthreads/sensorboards/tmote_onboard
+
+ifneq ($(filter telosb tmote clean,$(MAKECMDGOALS)),)
+ include $(MAKERULES)
+else
+%:
+ @echo " Sorry, this application is only written to work with telos based motes equipped with onboard sensors.."
+cthreads:
+ @:
+dynthreads:
+ @:
+endif
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+#include "tosthread_hamamatsuS1087.h"
+#include "tosthread_hamamatsuS10871.h"
+#include "tosthread_sensirionSht11.h"
+
+#define NUM_SENSORS 4
+#define SAMPLING_PERIOD 3000
+#define AM_SENSOR_DATA_MSG 0x25
+
+//Data structure for storing sensor data
+typedef struct sensor_data {
+ nx_uint32_t seq_no;
+ nx_uint16_t hum;
+ nx_uint16_t temp;
+ nx_uint16_t tsr;
+ nx_uint16_t par;
+} sensor_data_t;
+
+//Initialize variables associated with each thread
+tosthread_t humidity;
+tosthread_t temperature;
+tosthread_t total_solar;
+tosthread_t photo_active;
+tosthread_t send_handler;
+
+message_t send_msg;
+sensor_data_t* sensor_data; //pointer into message structure
+mutex_t data_mutex;
+barrier_t send_barrier;
+barrier_t sense_barrier;
+
+void humidity_thread(void* arg);
+void temperature_thread(void* arg);
+void total_solar_thread(void* arg);
+void photo_active_thread(void* arg);
+void send_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ mutex_init(&data_mutex);
+ barrier_reset(&send_barrier, NUM_SENSORS+1);
+ barrier_reset(&sense_barrier, NUM_SENSORS+1);
+ sensor_data = radioGetPayload(&send_msg, sizeof(sensor_data_t));
+ //sensor_data->seq_no = 0;
+ __nesc_hton_uint32((unsigned char *)&sensor_data->seq_no, (unsigned long )0);
+
+ amRadioStart();
+ tosthread_create(&humidity, humidity_thread, NULL, 200);
+ tosthread_create(&temperature, temperature_thread, NULL, 200);
+ tosthread_create(&total_solar, total_solar_thread, NULL, 200);
+ tosthread_create(&photo_active, photo_active_thread, NULL, 200);
+ tosthread_create(&send_handler, send_thread, NULL, 200);
+}
+
+void read_sensor(error_t (*read)(uint16_t*), nx_uint16_t* nx_val) {
+ uint16_t val;
+ for(;;) {
+ (*read)(&val);
+ mutex_lock(&data_mutex);
+ // *nx_val = val;
+ __nesc_hton_uint16((unsigned char *)&*nx_val, val);
+ mutex_unlock(&data_mutex);
+ barrier_block(&send_barrier);
+ barrier_block(&sense_barrier);
+ }
+}
+
+void humidity_thread(void* arg) {
+ read_sensor(sensirionSht11_humidity_read, &(sensor_data->hum));
+}
+void temperature_thread(void* arg) {
+ read_sensor(sensirionSht11_temperature_read, &(sensor_data->temp));
+}
+void total_solar_thread(void* arg) {
+ read_sensor(hamamatsuS10871_tsr_read, &(sensor_data->tsr));
+}
+void photo_active_thread(void* arg) {
+ read_sensor(hamamatsuS1087_par_read, &(sensor_data->par));
+}
+void send_thread(void* arg) {
+ //Only needed for nesC magic.... I hate this hack.....
+ unsigned long __nesc_temp43;
+ unsigned char *__nesc_temp42;
+
+ for(;;) {
+ barrier_block(&send_barrier);
+ barrier_reset(&send_barrier, NUM_SENSORS + 1);
+
+ if(amRadioSend(AM_BROADCAST_ADDR, &send_msg, sizeof(sensor_data_t), AM_SENSOR_DATA_MSG) == SUCCESS) {
+ //sensor_data->seq_no++;
+ (__nesc_temp42 = (unsigned char *)&sensor_data->seq_no, __nesc_hton_uint32(__nesc_temp42, (__nesc_temp43 = __nesc_ntoh_uint32(__nesc_temp42)) + 1), __nesc_temp43);
+ led0Toggle();
+ }
+ //tosthread_sleep(SAMPLING_PERIOD);
+ barrier_block(&sense_barrier);
+ barrier_reset(&sense_barrier, NUM_SENSORS + 1);
+ }
+}
--- /dev/null
+TOSTHREAD_MAIN=ReceiveStoreDecompress.c
+CFLAGS += -I..
+
+ifneq ($(filter telosb tmote clean,$(MAKECMDGOALS)),)
+ include $(MAKERULES)
+else
+%:
+ @echo " Sorry, this application is only written to work with telos based motes equipped with onboard sensors.."
+cthreads:
+ @:
+dynthreads:
+ @:
+endif
--- /dev/null
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_amserial.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+#include "tosthread_logstorage.h"
+#include "StorageVolumes.h"
+#include "lz.c"
+#include "lz.h"
+
+#define SENDING_PERIOD 1
+#define AM_SENSOR_DATA_MSG 0x25
+#define NUM_RECORDS_TO_COMPRESS 50
+
+//Data structure for storing sensor data
+typedef nx_struct sensor_data {
+ nx_uint32_t seq_no;
+ nx_uint16_t hum;
+ nx_uint16_t temp;
+ nx_uint16_t tsr;
+ nx_uint16_t par;
+} sensor_data_t;
+
+typedef nx_struct radio_data {
+ nx_uint8_t taskNum;
+ nx_uint16_t pktNum;
+ nx_uint8_t more;
+ nx_uint8_t data[0];
+} radio_data_t;
+
+typedef struct log_entry {
+ uint8_t taskNum;
+ uint16_t pktNum;
+ uint8_t more;
+ uint8_t srcNodeId;
+ uint8_t len;
+ uint8_t data[TOSH_DATA_LENGTH - sizeof(radio_data_t)];
+} log_entry_t;
+
+//Initialize variables associated with each thread
+tosthread_t receive_handler;
+tosthread_t decompress_handler;
+
+mutex_t log_mutex;
+
+void receive_thread(void* arg);
+void decompress_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ mutex_init(&log_mutex);
+ amRadioStart();
+amSerialStart();
+ led0Toggle();
+ volumeLogErase(VOLUME_SENSORLOG);
+ volumeLogSeek(VOLUME_SENSORLOG, SEEK_BEGINNING);
+ led0Toggle();
+ tosthread_create(&receive_handler, receive_thread, NULL, 1000);
+ tosthread_create(&decompress_handler, decompress_thread, NULL, 5000);
+}
+
+void receive_thread(void* arg) {
+ message_t mesg;
+ log_entry_t entry;
+ bool data_lost;
+ uint8_t payload_len;
+ storage_len_t entry_len;
+ radio_data_t *payload;
+
+ for (;;) {
+ if (amRadioReceive(&mesg, 0, AM_SENSOR_DATA_MSG) == SUCCESS) {
+ payload_len = radioGetPayloadLength(&mesg);
+ payload = (radio_data_t *)radioGetPayload(&mesg, payload_len);
+
+ entry.taskNum = payload->taskNum;
+ entry.pktNum = payload->pktNum;
+ entry.more = payload->more;
+ entry.srcNodeId = amRadioGetSource(&mesg) & 0xFF;
+ entry.len = payload_len - sizeof(radio_data_t);
+ memcpy(entry.data, payload->data, entry.len);
+
+/*
+ {
+ int i;
+ for (i = 0; i < entry.len; i++) {
+ entry.data[i] = payload->data[i];
+ }
+ }
+*/
+
+ entry_len = sizeof(log_entry_t);
+ mutex_lock(&log_mutex);
+ while( volumeLogAppend(VOLUME_SENSORLOG, &entry, &entry_len, &data_lost) != SUCCESS );
+ mutex_unlock(&log_mutex);
+ }
+ }
+}
+
+void decompress_thread(void* arg) {
+ storage_len_t entry_len;
+ log_entry_t entry;
+ uint16_t insize[2] = {0, 0};
+ uint8_t taskNum[2] = {0, 0};
+ uint16_t pktNum[2] = {0, 0};
+ uint8_t in[2][((NUM_RECORDS_TO_COMPRESS * sizeof(sensor_data_t) * 257 - 1) / 256) + 1 + 1];
+ uint8_t out[NUM_RECORDS_TO_COMPRESS * sizeof(sensor_data_t)];
+// uint32_t pktLoss[2] = {0, 0};
+ bool isComplete[2];
+
+ for(;;) {
+ tosthread_sleep(SENDING_PERIOD);
+
+ while( volumeLogCurrentReadOffset(VOLUME_SENSORLOG) != volumeLogCurrentWriteOffset(VOLUME_SENSORLOG) ) {
+ entry_len = sizeof(log_entry_t);
+ mutex_lock(&log_mutex);
+ while( volumeLogRead(VOLUME_SENSORLOG, &entry, &entry_len) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ if (entry.pktNum == 0) {
+ led2Toggle();
+
+ taskNum[entry.srcNodeId] = entry.taskNum;
+ pktNum[entry.srcNodeId] = 1;
+ isComplete[entry.srcNodeId] = TRUE;
+ memcpy(in[entry.srcNodeId], entry.data, entry.len);
+ insize[entry.srcNodeId] = entry.len;
+ } else {
+ led0Toggle();
+ if (entry.taskNum == taskNum[entry.srcNodeId] && entry.pktNum == pktNum[entry.srcNodeId]) {
+// uint16_t startIndex = (TOSH_DATA_LENGTH - sizeof(radio_data_t)) * pktNum[entry.srcNodeId];
+// memcpy(&(in[entry.srcNodeId][startIndex]), entry.data, entry.len);
+// memcpy(&(in[entry.srcNodeId][insize[entry.srcNodeId] - 1]), entry.data, entry.len);
+
+ {
+ int i;
+ for (i = 0; i < entry.len; i++) {
+ (in[entry.srcNodeId])[insize[entry.srcNodeId] + i] = entry.data[i];
+ }
+ }
+
+ insize[entry.srcNodeId] += entry.len;
+ pktNum[entry.srcNodeId]++;
+
+ if (entry.more == FALSE && isComplete[entry.srcNodeId] == TRUE) {
+ led1Toggle();
+
+ LZ_Uncompress(in[entry.srcNodeId], out, insize[entry.srcNodeId]);
+
+/*
+ {
+ int tempinsize = insize[entry.srcNodeId], sendSize = 0, sendIndex = 0;
+ void *serialMsg_payload;
+ message_t serialMsg;
+
+ while (tempinsize > 0) {
+ if (tempinsize > TOSH_DATA_LENGTH) {
+ sendSize = TOSH_DATA_LENGTH;
+ } else {
+ sendSize = tempinsize;
+ }
+
+ serialMsg_payload = serialGetPayload(&serialMsg, sendSize);
+ memcpy(serialMsg_payload, &(in[entry.srcNodeId][sendIndex]), sendSize);
+ while( amSerialSend(AM_BROADCAST_ADDR, &serialMsg, sendSize, 0) != SUCCESS );
+ sendIndex += sendSize;
+ tempinsize -= sendSize;
+ }
+ }
+*/
+/*
+ {
+ int i;
+ for (i = 0; i < NUM_RECORDS_TO_COMPRESS; i++) {
+ message_t serialMsg;
+ void *serialMsg_payload = serialGetPayload(&serialMsg, sizeof(sensor_data_t));
+ memcpy(serialMsg_payload, &(out[i * sizeof(sensor_data_t)]), sizeof(sensor_data_t));
+ while( amSerialSend(AM_BROADCAST_ADDR, &serialMsg, sizeof(sensor_data_t), 0) != SUCCESS );
+ }
+ }
+*/
+ pktNum[entry.srcNodeId] = 0;
+ }
+ } else {
+ isComplete[entry.srcNodeId] = FALSE;
+ led0Toggle();
+ }
+ }
+ }
+ }
+}
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="262144" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="1048576" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+TOSTHREAD_MAIN=SenseStoreAndForward.c
+CFLAGS += -I..
+CFLAGS += -I$(TOSDIR)/lib/tosthreads/sensorboards/tmote_onboard
+
+ifneq ($(filter telosb tmote clean,$(MAKECMDGOALS)),)
+ include $(MAKERULES)
+else
+%:
+ @echo " Sorry, this application is only written to work with telos based motes equipped with onboard sensors.."
+cthreads:
+ @:
+dynthreads:
+ @:
+endif
--- /dev/null
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+#include "tosthread_logstorage.h"
+#include "tmote_onboard_sensors.h"
+#include "StorageVolumes.h"
+#include "lz.c"
+#include "lz.h"
+
+#define SAMPLING_PERIOD 100
+#define SENDING_PERIOD 50
+#define SENDING_INTERVAL 25
+#define AM_SENSOR_DATA_MSG 0x25
+#define NUM_RECORDS_TO_COMPRESS 50
+#define NUM_SENSORS 4
+#define TOTAL_NUM_RECORDS_TO_SEND 500
+
+//Data structure for storing sensor data
+typedef nx_struct sensor_data {
+ nx_uint32_t seq_no;
+ nx_uint16_t hum;
+ nx_uint16_t temp;
+ nx_uint16_t tsr;
+ nx_uint16_t par;
+} sensor_data_t;
+
+typedef nx_struct radio_data {
+ nx_uint8_t taskNum;
+ nx_uint16_t pktNum;
+ nx_uint8_t more;
+ nx_uint8_t data[0];
+} radio_data_t;
+
+//Initialize variables associated with each thread
+tosthread_t humidity;
+tosthread_t temperature;
+tosthread_t total_solar;
+tosthread_t photo_active;
+tosthread_t store_handler;
+tosthread_t send_handler;
+
+message_t send_msg;
+sensor_data_t storing_sensor_data;
+mutex_t data_mutex;
+mutex_t log_mutex;
+barrier_t send_barrier;
+barrier_t sense_barrier;
+
+sensor_data_t compressing_sensor_data[NUM_RECORDS_TO_COMPRESS];
+
+void humidity_thread(void* arg);
+void temperature_thread(void* arg);
+void total_solar_thread(void* arg);
+void photo_active_thread(void* arg);
+void store_thread(void* arg);
+void send_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ mutex_init(&data_mutex);
+ mutex_init(&log_mutex);
+ barrier_reset(&send_barrier, NUM_SENSORS+1);
+ barrier_reset(&sense_barrier, NUM_SENSORS+1);
+
+ __nesc_hton_uint32((unsigned char *)&storing_sensor_data.seq_no, (unsigned long )0);
+
+ amRadioStart();
+ led0Toggle();
+ volumeLogErase(VOLUME_SENSORLOG);
+ volumeLogSeek(VOLUME_SENSORLOG, SEEK_BEGINNING);
+ led0Toggle();
+ tosthread_create(&humidity, humidity_thread, NULL, 200);
+ tosthread_create(&temperature, temperature_thread, NULL, 200);
+ tosthread_create(&total_solar, total_solar_thread, NULL, 200);
+ tosthread_create(&photo_active, photo_active_thread, NULL, 200);
+ tosthread_create(&store_handler, store_thread, NULL, 200);
+ tosthread_create(&send_handler, send_thread, NULL, 5000);
+}
+
+void read_sensor(error_t (*read)(uint16_t*), nx_uint16_t* nx_val) {
+ uint16_t val;
+ for(;;) {
+ (*read)(&val);
+ mutex_lock(&data_mutex);
+ // *nx_val = val;
+ __nesc_hton_uint16((unsigned char *)&*nx_val, val);
+ mutex_unlock(&data_mutex);
+ barrier_block(&send_barrier);
+ barrier_block(&sense_barrier);
+ }
+}
+
+void humidity_thread(void* arg) {
+ read_sensor(sensirionSht11_humidity_read, &(storing_sensor_data.hum));
+}
+void temperature_thread(void* arg) {
+ read_sensor(sensirionSht11_temperature_read, &(storing_sensor_data.temp));
+}
+void total_solar_thread(void* arg) {
+ read_sensor(hamamatsuS10871_tsr_read, &(storing_sensor_data.tsr));
+}
+void photo_active_thread(void* arg) {
+ read_sensor(hamamatsuS1087_par_read, &(storing_sensor_data.par));
+}
+void store_thread(void* arg) {
+ storage_len_t sensor_data_len;
+ bool sensor_records_lost;
+
+ //Only needed for nesC magic.... I hate this hack.....
+ unsigned long __nesc_temp43;
+ unsigned char *__nesc_temp42;
+
+ for(;;) {
+ barrier_block(&send_barrier);
+ barrier_reset(&send_barrier, NUM_SENSORS + 1);
+
+ mutex_lock(&log_mutex);
+ sensor_data_len = sizeof(sensor_data_t);
+ while( volumeLogAppend(VOLUME_SENSORLOG, &storing_sensor_data, &sensor_data_len, &sensor_records_lost) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ //storing_sensor_data.seq_no++
+ (__nesc_temp42 = (unsigned char *)&storing_sensor_data.seq_no, __nesc_hton_uint32(__nesc_temp42, (__nesc_temp43 = __nesc_ntoh_uint32(__nesc_temp42)) + 1), __nesc_temp43);
+ led0Toggle();
+
+ //tosthread_sleep(SAMPLING_PERIOD);
+ barrier_block(&sense_barrier);
+ barrier_reset(&sense_barrier, NUM_SENSORS + 1);
+ }
+}
+
+uint8_t taskNum = 0;
+
+void send_thread(void* arg) {
+ storage_len_t sensor_data_len;
+ uint8_t numRecords = 0;
+ uint8_t out[((NUM_RECORDS_TO_COMPRESS * sizeof(sensor_data_t) * 257 - 1) / 256) + 1 + 1];
+
+ for(;;) {
+ tosthread_sleep(SENDING_PERIOD);
+
+ while( volumeLogCurrentReadOffset(VOLUME_SENSORLOG) != volumeLogCurrentWriteOffset(VOLUME_SENSORLOG) ) {
+ sensor_data_len = sizeof(sensor_data_t);
+ mutex_lock(&log_mutex);
+ while( volumeLogRead(VOLUME_SENSORLOG, &(compressing_sensor_data[numRecords]), &sensor_data_len) != SUCCESS );
+ numRecords++;
+ mutex_unlock(&log_mutex);
+
+ if (numRecords == NUM_RECORDS_TO_COMPRESS) {
+ uint8_t pktNum = 0;
+ uint16_t outsize = 0, sendsize = 0, sendindex = 0;
+ radio_data_t *payload = NULL;
+
+ outsize = LZ_Compress((void *)compressing_sensor_data, out, NUM_RECORDS_TO_COMPRESS * sizeof(sensor_data_t));
+
+ while (outsize > 0) {
+ if (outsize > (TOSH_DATA_LENGTH - sizeof(radio_data_t))) {
+ sendsize = TOSH_DATA_LENGTH - sizeof(radio_data_t);
+ } else {
+ sendsize = outsize;
+ }
+
+ payload = (radio_data_t *) radioGetPayload(&send_msg, sizeof(radio_data_t) + sendsize);
+ payload->taskNum = taskNum;
+ payload->pktNum = pktNum;
+ payload->more = ((outsize - sendsize) > 0) ? TRUE : FALSE;
+ memcpy(payload->data, &(out[sendindex]), sendsize);
+
+ while( amRadioSend(AM_BROADCAST_ADDR, &send_msg, sizeof(radio_data_t) + sendsize, AM_SENSOR_DATA_MSG) != SUCCESS );
+
+ outsize -= sendsize;
+ sendindex += sendsize;
+ pktNum++;
+ led1Toggle();
+ tosthread_sleep(SENDING_INTERVAL);
+ }
+
+ taskNum++;
+ pktNum = 0;
+ numRecords = 0;
+ }
+ }
+
+ //led2Toggle();
+ }
+}
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include "bcl-1.2.0/src/lz.h"
+#include "bcl-1.2.0/src/lz.c"
+
+int main(int argc, char *argv[])
+{
+ if (argc == 2) {
+ FILE *fp = fopen(argv[1], "rb");
+
+ if (fp == NULL) {
+ fprintf(stderr, "ERROR: Can't open input file, %s!\n", argv[1]);
+ } else {
+ fseek(fp, 0, SEEK_END);
+ {
+ long size = ftell(fp);
+ uint8_t in[size];
+ uint8_t out[size];
+ size_t in_size = 0;
+
+ rewind(fp);
+ in_size = fread(in, 1, size, fp);
+
+ printf("%d\n", in_size);
+
+ LZ_Uncompress(in, out, in_size);
+
+ {
+ int i = 0;
+ for (i = 0; i < 96; i++) {
+ printf("%d ", out[i]);
+ if ((i + 1) % 12 == 0) {
+ printf("\n");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ printf("Usage: %s\n <file name>", argv[0]);
+ }
+
+ return 0;
+}
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="262144" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="1048576" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+/*************************************************************************
+* Name: lz.c
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder implementation.
+* Reentrant: Yes
+*
+* The LZ77 compression scheme is a substitutional compression scheme
+* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in
+* its design, and uses no fancy bit level compression.
+*
+* This is my first attempt at an implementation of a LZ77 code/decoder.
+*
+* The principle of the LZ77 compression algorithm is to store repeated
+* occurrences of strings as references to previous occurrences of the same
+* string. The point is that the reference consumes less space than the
+* string itself, provided that the string is long enough (in this
+* implementation, the string has to be at least 4 bytes long, since the
+* minimum coded reference is 3 bytes long). Also note that the term
+* "string" refers to any kind of byte sequence (it does not have to be
+* an ASCII string, for instance).
+*
+* The coder uses a brute force approach to finding string matches in the
+* history buffer (or "sliding window", if you wish), which is very, very
+* slow. I recon the complexity is somewhere between O(n^2) and O(n^3),
+* depending on the input data.
+*
+* There is also a faster implementation that uses a large working buffer
+* in which a "jump table" is stored, which is used to quickly find
+* possible string matches (see the source code for LZ_CompressFast() for
+* more information). The faster method is an order of magnitude faster,
+* but still quite slow compared to other compression methods.
+*
+* The upside is that decompression is very fast, and the compression ratio
+* is often very good.
+*
+* The reference to a string is coded as a (length,offset) pair, where the
+* length indicates the length of the string, and the offset gives the
+* offset from the current data position. To distinguish between string
+* references and literal strings (uncompressed bytes), a string reference
+* is preceded by a marker byte, which is chosen as the least common byte
+* symbol in the input data stream (this marker byte is stored in the
+* output stream as the first byte).
+*
+* Occurrences of the marker byte in the stream are encoded as the marker
+* byte followed by a zero byte, which means that occurrences of the marker
+* byte have to be coded with two bytes.
+*
+* The lengths and offsets are coded in a variable length fashion, allowing
+* values of any magnitude (up to 4294967295 in this implementation).
+*
+* With this compression scheme, the worst case compression result is
+* (257/256)*insize + 1.
+*
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+
+/*************************************************************************
+* Constants used for LZ77 coding
+*************************************************************************/
+
+/* Maximum offset (can be any size < 2^31). Lower values give faster
+ compression, while higher values gives better compression. The default
+ value of 100000 is quite high. Experiment to see what works best for
+ you. */
+#define LZ_MAX_OFFSET 100000
+
+
+
+/*************************************************************************
+* INTERNAL FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* _LZ_StringCompare() - Return maximum length string match.
+*************************************************************************/
+
+static uint32_t _LZ_StringCompare( unsigned char * str1,
+ unsigned char * str2, uint32_t minlen, uint32_t maxlen )
+{
+ uint32_t len;
+
+ for( len = minlen; (len < maxlen) && (str1[len] == str2[len]); ++ len );
+
+ return len;
+}
+
+
+/*************************************************************************
+* _LZ_WriteVarSize() - Write uint32_teger with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_WriteVarSize( uint32_t x, unsigned char * buf )
+{
+ uint32_t y;
+ int num_bytes, i, b;
+
+ /* Determine number of bytes needed to store the number x */
+ y = x >> 3;
+ for( num_bytes = 5; num_bytes >= 2; -- num_bytes )
+ {
+ if( y & 0xfe000000 ) break;
+ y <<= 7;
+ }
+
+ /* Write all bytes, seven bits in each, with 8:th bit set for all */
+ /* but the last byte. */
+ for( i = num_bytes-1; i >= 0; -- i )
+ {
+ b = (x >> (i*7)) & 0x0000007f;
+ if( i > 0 )
+ {
+ b |= 0x00000080;
+ }
+ *buf ++ = (unsigned char) b;
+ }
+
+ /* Return number of bytes written */
+ return num_bytes;
+}
+
+
+/*************************************************************************
+* _LZ_ReadVarSize() - Read uint32_teger with variable number of
+* bytes depending on value.
+*************************************************************************/
+
+static int _LZ_ReadVarSize( uint32_t * x, unsigned char * buf )
+{
+ uint32_t y, b, num_bytes;
+
+ /* Read complete value (stop when byte contains zero in 8:th bit) */
+ y = 0;
+ num_bytes = 0;
+ do
+ {
+ b = (uint32_t) (*buf ++);
+ y = (y << 7) | (b & 0x0000007f);
+ ++ num_bytes;
+ }
+ while( b & 0x00000080 );
+
+ /* Store value in x */
+ *x = y;
+
+ /* Return number of bytes read */
+ return num_bytes;
+}
+
+
+
+/*************************************************************************
+* PUBLIC FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* LZ_Compress() - Compress a block of data using an LZ77 coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 0.4% larger
+* than the input buffer, plus one byte.
+* insize - Number of input bytes.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+int LZ_Compress( unsigned char *in, unsigned char *out,
+ uint32_t insize )
+{
+ unsigned char marker, symbol;
+ uint32_t inpos, outpos, bytesleft, i;
+ uint32_t maxoffset, offset, bestoffset;
+ uint32_t maxlength, length, bestlength;
+ uint32_t histogram[ 256 ];
+ unsigned char *ptr1, *ptr2;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Create histogram */
+ for( i = 0; i < 256; ++ i )
+ {
+ histogram[ i ] = 0;
+ }
+ for( i = 0; i < insize; ++ i )
+ {
+ ++ histogram[ in[ i ] ];
+ }
+
+ /* Find the least common byte, and use it as the marker symbol */
+ marker = 0;
+ for( i = 1; i < 256; ++ i )
+ {
+ if( histogram[ i ] < histogram[ marker ] )
+ {
+ marker = i;
+ }
+ }
+
+ /* Remember the marker symbol for the decoder */
+ out[ 0 ] = marker;
+
+ /* Start of compression */
+ inpos = 0;
+ outpos = 1;
+
+ /* Main compression loop */
+ bytesleft = insize;
+ do
+ {
+ /* Determine most distant position */
+ if( inpos > LZ_MAX_OFFSET ) {
+ maxoffset = LZ_MAX_OFFSET;
+ }
+ else {
+ maxoffset = inpos;
+ }
+
+ /* Get pointer to current position */
+ ptr1 = &in[ inpos ];
+
+ /* Search history window for maximum length string match */
+ bestlength = 3;
+ bestoffset = 0;
+ for( offset = 3; offset <= maxoffset; ++ offset )
+ {
+ /* Get pointer to candidate string */
+ ptr2 = &ptr1[ -(int)offset ];
+
+ /* Quickly determine if this is a candidate (for speed) */
+ if( (ptr1[ 0 ] == ptr2[ 0 ]) &&
+ (ptr1[ bestlength ] == ptr2[ bestlength ]) )
+ {
+ /* Determine maximum length for this offset */
+ maxlength = (bytesleft < offset ? bytesleft : offset);
+
+ /* Count maximum length match at this offset */
+ length = _LZ_StringCompare( ptr1, ptr2, 0, maxlength );
+
+ /* Better match than any previous match? */
+ if( length > bestlength )
+ {
+ bestlength = length;
+ bestoffset = offset;
+ }
+ }
+ }
+
+ /* Was there a good enough match? */
+ if( (bestlength >= 8) ||
+ ((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
+ ((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
+ ((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
+ ((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
+ {
+ out[ outpos ++ ] = (unsigned char) marker;
+ outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
+ outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
+ inpos += bestlength;
+ bytesleft -= bestlength;
+ }
+ else
+ {
+ /* Output single byte (or two bytes if marker byte) */
+ symbol = in[ inpos ++ ];
+ out[ outpos ++ ] = symbol;
+ if( symbol == marker )
+ {
+ out[ outpos ++ ] = 0;
+ }
+ -- bytesleft;
+ }
+ }
+ while( bytesleft > 3 );
+
+ /* Dump remaining bytes, if any */
+ while( inpos < insize )
+ {
+ if( in[ inpos ] == marker )
+ {
+ out[ outpos ++ ] = marker;
+ out[ outpos ++ ] = 0;
+ }
+ else
+ {
+ out[ outpos ++ ] = in[ inpos ];
+ }
+ ++ inpos;
+ }
+
+ return outpos;
+}
+
+
+/*************************************************************************
+* LZ_CompressFast() - Compress a block of data using an LZ77 coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 0.4% larger
+* than the input buffer, plus one byte.
+* insize - Number of input bytes.
+* work - Pointer to a temporary buffer (internal working buffer), which
+* must be able to hold (insize+65536) uint32_tegers.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+int LZ_CompressFast( unsigned char *in, unsigned char *out,
+ uint32_t insize, uint32_t *work )
+{
+ unsigned char marker, symbol;
+ uint32_t inpos, outpos, bytesleft, i, index, symbols;
+ uint32_t offset, bestoffset;
+ uint32_t maxlength, length, bestlength;
+ uint32_t histogram[ 256 ], *lastindex, *jumptable;
+ unsigned char *ptr1, *ptr2;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 )
+ {
+ return 0;
+ }
+
+ /* Assign arrays to the working area */
+ lastindex = work;
+ jumptable = &work[ 65536 ];
+
+ /* Build a "jump table". Here is how the jump table works:
+ jumptable[i] points to the nearest previous occurrence of the same
+ symbol pair as in[i]:in[i+1], so in[i] == in[jumptable[i]] and
+ in[i+1] == in[jumptable[i]+1], and so on... Following the jump table
+ gives a dramatic boost for the string search'n'match loop compared
+ to doing a brute force search. The jump table is built in O(n) time,
+ so it is a cheap operation in terms of time, but it is expensice in
+ terms of memory consumption. */
+ for( i = 0; i < 65536; ++ i )
+ {
+ lastindex[ i ] = 0xffffffff;
+ }
+ for( i = 0; i < insize-1; ++ i )
+ {
+ symbols = (((uint32_t)in[i]) << 8) | ((uint32_t)in[i+1]);
+ index = lastindex[ symbols ];
+ lastindex[ symbols ] = i;
+ jumptable[ i ] = index;
+ }
+ jumptable[ insize-1 ] = 0xffffffff;
+
+ /* Create histogram */
+ for( i = 0; i < 256; ++ i )
+ {
+ histogram[ i ] = 0;
+ }
+ for( i = 0; i < insize; ++ i )
+ {
+ ++ histogram[ in[ i ] ];
+ }
+
+ /* Find the least common byte, and use it as the marker symbol */
+ marker = 0;
+ for( i = 1; i < 256; ++ i )
+ {
+ if( histogram[ i ] < histogram[ marker ] )
+ {
+ marker = i;
+ }
+ }
+
+ /* Remember the marker symbol for the decoder */
+ out[ 0 ] = marker;
+
+ /* Start of compression */
+ inpos = 0;
+ outpos = 1;
+
+ /* Main compression loop */
+ bytesleft = insize;
+ do
+ {
+ /* Get pointer to current position */
+ ptr1 = &in[ inpos ];
+
+ /* Search history window for maximum length string match */
+ bestlength = 3;
+ bestoffset = 0;
+ index = jumptable[ inpos ];
+ while( (index != 0xffffffff) && ((inpos - index) < LZ_MAX_OFFSET) )
+ {
+ /* Get pointer to candidate string */
+ ptr2 = &in[ index ];
+
+ /* Quickly determine if this is a candidate (for speed) */
+ if( ptr2[ bestlength ] == ptr1[ bestlength ] )
+ {
+ /* Determine maximum length for this offset */
+ offset = inpos - index;
+ maxlength = (bytesleft < offset ? bytesleft : offset);
+
+ /* Count maximum length match at this offset */
+ length = _LZ_StringCompare( ptr1, ptr2, 2, maxlength );
+
+ /* Better match than any previous match? */
+ if( length > bestlength )
+ {
+ bestlength = length;
+ bestoffset = offset;
+ }
+ }
+
+ /* Get next possible index from jump table */
+ index = jumptable[ index ];
+ }
+
+ /* Was there a good enough match? */
+ if( (bestlength >= 8) ||
+ ((bestlength == 4) && (bestoffset <= 0x0000007f)) ||
+ ((bestlength == 5) && (bestoffset <= 0x00003fff)) ||
+ ((bestlength == 6) && (bestoffset <= 0x001fffff)) ||
+ ((bestlength == 7) && (bestoffset <= 0x0fffffff)) )
+ {
+ out[ outpos ++ ] = (unsigned char) marker;
+ outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] );
+ outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] );
+ inpos += bestlength;
+ bytesleft -= bestlength;
+ }
+ else
+ {
+ /* Output single byte (or two bytes if marker byte) */
+ symbol = in[ inpos ++ ];
+ out[ outpos ++ ] = symbol;
+ if( symbol == marker )
+ {
+ out[ outpos ++ ] = 0;
+ }
+ -- bytesleft;
+ }
+ }
+ while( bytesleft > 3 );
+
+ /* Dump remaining bytes, if any */
+ while( inpos < insize )
+ {
+ if( in[ inpos ] == marker )
+ {
+ out[ outpos ++ ] = marker;
+ out[ outpos ++ ] = 0;
+ }
+ else
+ {
+ out[ outpos ++ ] = in[ inpos ];
+ }
+ ++ inpos;
+ }
+
+ return outpos;
+}
+
+
+/*************************************************************************
+* LZ_Uncompress() - Uncompress a block of data using an LZ77 decoder.
+* in - Input (compressed) buffer.
+* out - Output (uncompressed) buffer. This buffer must be large
+* enough to hold the uncompressed data.
+* insize - Number of input bytes.
+*************************************************************************/
+
+void LZ_Uncompress( unsigned char *in, unsigned char *out,
+ uint32_t insize )
+{
+ unsigned char marker, symbol;
+ uint32_t i, inpos, outpos, length, offset;
+
+ /* Do we have anything to uncompress? */
+ if( insize < 1 )
+ {
+ return;
+ }
+
+ /* Get marker symbol from input stream */
+ marker = in[ 0 ];
+ inpos = 1;
+
+ /* Main decompression loop */
+ outpos = 0;
+ do
+ {
+ symbol = in[ inpos ++ ];
+ if( symbol == marker )
+ {
+ /* We had a marker byte */
+ if( in[ inpos ] == 0 )
+ {
+ /* It was a single occurrence of the marker byte */
+ out[ outpos ++ ] = marker;
+ ++ inpos;
+ }
+ else
+ {
+ /* Extract true length and offset */
+ inpos += _LZ_ReadVarSize( &length, &in[ inpos ] );
+ inpos += _LZ_ReadVarSize( &offset, &in[ inpos ] );
+
+ /* Copy corresponding data from history window */
+ for( i = 0; i < length; ++ i )
+ {
+ out[ outpos ] = out[ outpos - offset ];
+ ++ outpos;
+ }
+ }
+ }
+ else
+ {
+ /* No marker, plain copy */
+ out[ outpos ++ ] = symbol;
+ }
+ }
+ while( inpos < insize );
+}
--- /dev/null
+/*************************************************************************
+* Name: lz.h
+* Author: Marcus Geelnard
+* Description: LZ77 coder/decoder interface.
+* Reentrant: Yes
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+#ifndef _lz_h_
+#define _lz_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*************************************************************************
+* Function prototypes
+*************************************************************************/
+
+int LZ_Compress( unsigned char *in, unsigned char *out,
+ uint32_t insize );
+int LZ_CompressFast( unsigned char *in, unsigned char *out,
+ uint32_t insize, uint32_t *work );
+void LZ_Uncompress( unsigned char *in, unsigned char *out,
+ uint32_t insize );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _lz_h_ */
--- /dev/null
+TOSTHREAD_MAIN=SenseStoreAndForward.c
+CFLAGS += -I$(TOSDIR)/lib/tosthreads/sensorboards/tmote_onboard
+
+ifneq ($(filter telosb tmote clean,$(MAKECMDGOALS)),)
+ include $(MAKERULES)
+else
+%:
+ @echo " Sorry, this application is only written to work with telos based motes equipped with onboard sensors.."
+cthreads:
+ @:
+dynthreads:
+ @:
+endif
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#include "tosthread.h"
+#include "tosthread_amradio.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+#include "tosthread_logstorage.h"
+#include "tmote_onboard_sensors.h"
+#include "StorageVolumes.h"
+
+#define NUM_SENSORS 4
+#define SAMPLING_PERIOD 3000
+#define SENDING_PERIOD 10000
+#define AM_SENSOR_DATA_MSG 0x25
+
+//Data structure for storing sensor data
+typedef struct sensor_data {
+ nx_uint32_t seq_no;
+ nx_uint16_t hum;
+ nx_uint16_t temp;
+ nx_uint16_t tsr;
+ nx_uint16_t par;
+} sensor_data_t;
+
+//Initialize variables associated with each thread
+tosthread_t humidity;
+tosthread_t temperature;
+tosthread_t total_solar;
+tosthread_t photo_active;
+tosthread_t store_handler;
+tosthread_t send_handler;
+
+message_t send_msg;
+sensor_data_t storing_sensor_data;
+sensor_data_t* sending_sensor_data; //pointer into message structure
+mutex_t data_mutex;
+mutex_t log_mutex;
+barrier_t send_barrier;
+barrier_t sense_barrier;
+
+void humidity_thread(void* arg);
+void temperature_thread(void* arg);
+void total_solar_thread(void* arg);
+void photo_active_thread(void* arg);
+void store_thread(void* arg);
+void send_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ mutex_init(&data_mutex);
+ mutex_init(&log_mutex);
+ barrier_reset(&send_barrier, NUM_SENSORS+1);
+ barrier_reset(&sense_barrier, NUM_SENSORS+1);
+ sending_sensor_data = radioGetPayload(&send_msg, sizeof(sensor_data_t));
+ //storing_sensor_data->seq_no = 0;
+ __nesc_hton_uint32((unsigned char *)&storing_sensor_data.seq_no, (unsigned long )0);
+
+ amRadioStart();
+ led0Toggle();
+ volumeLogErase(VOLUME_SENSORLOG);
+ volumeLogSeek(VOLUME_SENSORLOG, SEEK_BEGINNING);
+ tosthread_create(&humidity, humidity_thread, NULL, 200);
+ tosthread_create(&temperature, temperature_thread, NULL, 200);
+ tosthread_create(&total_solar, total_solar_thread, NULL, 200);
+ tosthread_create(&photo_active, photo_active_thread, NULL, 200);
+ tosthread_create(&store_handler, store_thread, NULL, 200);
+ tosthread_create(&send_handler, send_thread, NULL, 200);
+}
+
+void read_sensor(error_t (*read)(uint16_t*), nx_uint16_t* nx_val) {
+ uint16_t val;
+ for(;;) {
+ (*read)(&val);
+ mutex_lock(&data_mutex);
+ // *nx_val = val;
+ __nesc_hton_uint16((unsigned char *)&*nx_val, val);
+ mutex_unlock(&data_mutex);
+ barrier_block(&send_barrier);
+ barrier_block(&sense_barrier);
+ }
+}
+
+void humidity_thread(void* arg) {
+ read_sensor(sensirionSht11_humidity_read, &(storing_sensor_data.hum));
+}
+void temperature_thread(void* arg) {
+ read_sensor(sensirionSht11_temperature_read, &(storing_sensor_data.temp));
+}
+void total_solar_thread(void* arg) {
+ read_sensor(hamamatsuS10871_tsr_read, &(storing_sensor_data.tsr));
+}
+void photo_active_thread(void* arg) {
+ read_sensor(hamamatsuS1087_par_read, &(storing_sensor_data.par));
+}
+void store_thread(void* arg) {
+ storage_len_t sensor_data_len;
+ bool sensor_records_lost;
+
+ //Only needed for nesC magic.... I hate this hack.....
+ unsigned long __nesc_temp43;
+ unsigned char *__nesc_temp42;
+
+ for(;;) {
+ barrier_block(&send_barrier);
+ barrier_reset(&send_barrier, NUM_SENSORS + 1);
+
+ mutex_lock(&log_mutex);
+ sensor_data_len = sizeof(sensor_data_t);
+ while( volumeLogAppend(VOLUME_SENSORLOG, &storing_sensor_data, &sensor_data_len, &sensor_records_lost) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ //storing_sensor_data.seq_no++
+ (__nesc_temp42 = (unsigned char *)&storing_sensor_data.seq_no, __nesc_hton_uint32(__nesc_temp42, (__nesc_temp43 = __nesc_ntoh_uint32(__nesc_temp42)) + 1), __nesc_temp43);
+ led0Toggle();
+
+ //tosthread_sleep(SAMPLING_PERIOD);
+ barrier_block(&sense_barrier);
+ barrier_reset(&sense_barrier, NUM_SENSORS + 1);
+ }
+}
+void send_thread(void* arg) {
+ storage_len_t sensor_data_len;
+
+ for(;;) {
+ tosthread_sleep(SENDING_PERIOD);
+
+ while( volumeLogCurrentReadOffset(VOLUME_SENSORLOG) != volumeLogCurrentWriteOffset(VOLUME_SENSORLOG) ) {
+ sensor_data_len = sizeof(sensor_data_t);
+ mutex_lock(&log_mutex);
+ while( volumeLogRead(VOLUME_SENSORLOG, sending_sensor_data, &sensor_data_len) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ while( amRadioSend(AM_BROADCAST_ADDR, &send_msg, sizeof(sensor_data_t), AM_SENSOR_DATA_MSG) != SUCCESS );
+ led1Toggle();
+ }
+ led2Toggle();
+ }
+}
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="262144" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="SENSORLOG" size="1048576" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+TOSTHREAD_MAIN=TestLogStorage.c
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues <klueska@cs.stanford.edu>
+ */
+
+#include "tosthread.h"
+#include "tosthread_amserial.h"
+#include "tosthread_leds.h"
+#include "tosthread_threadsync.h"
+#include "tosthread_logstorage.h"
+#include "StorageVolumes.h"
+
+#define NUM_SENSORS 1
+#define SAMPLING_PERIOD 3000
+#define SENDING_PERIOD 10000
+#define AM_SENSOR_DATA_MSG 0x25
+
+//Data structure for storing sensor data
+typedef struct sensor_data {
+ nx_uint32_t seq_no;
+ nx_uint16_t sample;
+} sensor_data_t;
+
+//Initialize variables associated with each thread
+tosthread_t dummy_sensor;
+tosthread_t store_handler;
+tosthread_t send_handler;
+
+message_t send_msg;
+sensor_data_t storing_sensor_data;
+sensor_data_t* sending_sensor_data; //pointer into message structure
+mutex_t data_mutex;
+mutex_t log_mutex;
+barrier_t send_barrier;
+barrier_t sense_barrier;
+
+void sensor_thread(void* arg);
+void store_thread(void* arg);
+void send_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ mutex_init(&data_mutex);
+ mutex_init(&log_mutex);
+ barrier_reset(&send_barrier, NUM_SENSORS+1);
+ barrier_reset(&sense_barrier, NUM_SENSORS+1);
+ sending_sensor_data = serialGetPayload(&send_msg, sizeof(sensor_data_t));
+ storing_sensor_data.seq_no = 0;
+
+ amSerialStart();
+ led0Toggle();
+ volumeLogErase(VOLUME_TESTLOGSTORAGE);
+ volumeLogSeek(VOLUME_TESTLOGSTORAGE, SEEK_BEGINNING);
+ tosthread_create(&dummy_sensor, sensor_thread, NULL, 200);
+ tosthread_create(&store_handler, store_thread, NULL, 200);
+ tosthread_create(&send_handler, send_thread, NULL, 200);
+}
+
+void read_sensor(error_t (*read)(uint16_t*), nx_uint16_t* nx_val) {
+
+}
+
+void sensor_thread(void* arg) {
+ //Dummy sensor just counts up on each iteration
+ uint16_t val = -1;
+ for(;;) {
+ val++;
+ mutex_lock(&data_mutex);
+ storing_sensor_data.sample = val;
+ mutex_unlock(&data_mutex);
+ barrier_block(&send_barrier);
+ barrier_block(&sense_barrier);
+ }
+}
+
+void store_thread(void* arg) {
+ storage_len_t sensor_data_len;
+ bool sensor_records_lost;
+
+ for(;;) {
+ barrier_block(&send_barrier);
+ barrier_reset(&send_barrier, NUM_SENSORS + 1);
+
+ mutex_lock(&log_mutex);
+ sensor_data_len = sizeof(sensor_data_t);
+ while( volumeLogAppend(VOLUME_TESTLOGSTORAGE, &storing_sensor_data, &sensor_data_len, &sensor_records_lost) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ storing_sensor_data.seq_no++;
+ led0Toggle();
+
+ tosthread_sleep(SAMPLING_PERIOD);
+ barrier_block(&sense_barrier);
+ barrier_reset(&sense_barrier, NUM_SENSORS + 1);
+ }
+}
+void send_thread(void* arg) {
+ storage_len_t sensor_data_len;
+
+ for(;;) {
+ tosthread_sleep(SENDING_PERIOD);
+
+ while( volumeLogCurrentReadOffset(VOLUME_TESTLOGSTORAGE) != volumeLogCurrentWriteOffset(VOLUME_TESTLOGSTORAGE) ) {
+ sensor_data_len = sizeof(sensor_data_t);
+ mutex_lock(&log_mutex);
+ while( volumeLogRead(VOLUME_TESTLOGSTORAGE, sending_sensor_data, &sensor_data_len) != SUCCESS );
+ mutex_unlock(&log_mutex);
+
+ while( amSerialSend(AM_BROADCAST_ADDR, &send_msg, sizeof(sensor_data_t), AM_SENSOR_DATA_MSG) != SUCCESS );
+ led1Toggle();
+ }
+ led2Toggle();
+ }
+}
--- /dev/null
+<volume_table>
+ <volume name="TESTLOGSTORAGE" size="262144" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="TESTLOGSTORAGE" size="2097152" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+<volume_table>
+ <volume name="TESTLOGSTORAGE" size="1048576" type="log" circular="true"/>
+</volume_table>
--- /dev/null
+TOSTHREAD_MAIN=TestPrintf.c
+CFLAGS += -I$(TOSDIR)/lib/tosthreads/lib/printf
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+#include "tosthread.h"
+#include "printf.h"
+
+//Initialize variables associated with each thread
+tosthread_t printf_thread;
+void thread_run(void* arg);
+
+void tosthread_main(void* arg) {
+ tosthread_create(&printf_thread, thread_run, NULL, 200);
+}
+
+void thread_run(void* arg) {
+ uint32_t counter = 0;
+ for(;;) {
+ printf("Counter: %lu\n", counter++);
+ }
+}
--- /dev/null
+TOSTHREAD_MAIN=ThreadStress.c
+PFLAGS += -I$(TOS_THREADS_DIR)/tos/csystem/Loader
+
+include $(MAKERULES)
--- /dev/null
+/*
+ * Copyright (c) 2008 Stanford University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Stanford University nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL STANFORD
+ * UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @author Kevin Klues (klueska@cs.stanford.edu)
+ */
+
+#include "tosthread.h"
+#include "tosthread_leds.h"
+
+//Initialize variables associated with each thread
+tosthread_t thread_handler;
+void blink0_thread(void* arg);
+void blink1_thread(void* arg);
+void blink2_thread(void* arg);
+
+void tosthread_main(void* arg) {
+ while(1) {
+ tosthread_create(&thread_handler, blink0_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink1_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink2_thread, NULL, 100);
+ }
+}
+
+uint8_t blink0_count = 0;
+void blink0_thread(void* arg) {
+ if(blink0_count++ == 0)
+ led0Toggle();
+ tosthread_create(&thread_handler, blink1_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink2_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink0_thread, NULL, 100);
+}
+
+uint8_t blink1_count = 0;
+void blink1_thread(void* arg) {
+ if(blink1_count++ == 85)
+ led1Toggle();
+ tosthread_create(&thread_handler, blink2_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink0_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink1_thread, NULL, 100);
+}
+
+uint8_t blink2_count = 0;
+void blink2_thread(void* arg) {
+ if(blink2_count++ == 170)
+ led2Toggle();
+ tosthread_create(&thread_handler, blink0_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink1_thread, NULL, 100);
+ tosthread_create(&thread_handler, blink2_thread, NULL, 100);
+}