From 4815890e50169007831bdba1871ddee1f4773372 Mon Sep 17 00:00:00 2001 From: klueska Date: Thu, 12 Jun 2008 15:11:38 +0000 Subject: [PATCH] initial checkin of tosthreads related apps --- .../apps/BaseStation/BaseSendReceiveP.nc | 152 +++++ .../apps/BaseStation/BaseStationAppC.nc | 127 ++++ .../apps/BaseStation/BaseStationC.nc | 59 ++ apps/tosthreads/apps/BaseStation/Makefile | 9 + .../apps/BaseStation/base_station.h | 50 ++ apps/tosthreads/apps/BaseStation/stack.h | 47 ++ apps/tosthreads/apps/Blink/BlinkAppC.nc | 53 ++ apps/tosthreads/apps/Blink/BlinkC.nc | 77 +++ apps/tosthreads/apps/Blink/Makefile | 4 + .../apps/Bounce/BarrierBounceAppC.nc | 102 ++++ apps/tosthreads/apps/Bounce/BarrierBounceC.nc | 141 +++++ apps/tosthreads/apps/Bounce/Makefile | 3 + apps/tosthreads/apps/Bounce/barrier_bounce.h | 48 ++ apps/tosthreads/apps/Bounce/stack.h | 46 ++ apps/tosthreads/apps/Makefile | 57 ++ apps/tosthreads/apps/RadioStress/Makefile | 3 + .../apps/RadioStress/RadioStressAppC.nc | 74 +++ .../apps/RadioStress/RadioStressC.nc | 122 ++++ apps/tosthreads/apps/SerialCompress/Makefile | 5 + .../apps/SerialCompress/SerialCompressAppC.nc | 23 + .../apps/SerialCompress/SerialCompressP.nc | 151 +++++ apps/tosthreads/apps/SerialCompress/lz.c | 544 ++++++++++++++++++ apps/tosthreads/apps/SerialCompress/lz.h | 56 ++ .../apps/SerialCompress/volumes-at45db.xml | 3 + .../apps/SerialCompress/volumes-stm25p.xml | 3 + .../tosthreads/apps/TestBlockStorage/Makefile | 3 + apps/tosthreads/apps/TestBlockStorage/README | 2 + .../TestBlockStorage/TestBlockStorageAppC.nc | 45 ++ .../TestBlockStorage/TestBlockStorageP.nc | 85 +++ .../apps/TestBlockStorage/volumes-at45db.xml | 3 + .../apps/TestBlockStorage/volumes-stm25p.xml | 3 + apps/tosthreads/apps/TestLogStorage/Makefile | 3 + .../apps/TestLogStorage/TestLogStorageAppC.nc | 34 ++ .../apps/TestLogStorage/TestLogStorageP.nc | 40 ++ .../apps/TestLogStorage/volumes-at45db.xml | 3 + .../apps/TestLogStorage/volumes-stm25p.xml | 3 + apps/tosthreads/apps/TestPrintf/Makefile | 4 + .../apps/TestPrintf/TestPrintfAppC.nc | 51 ++ .../tosthreads/apps/TestPrintf/TestPrintfC.nc | 55 ++ .../capps/BaseStation/BaseStation.c | 194 +++++++ apps/tosthreads/capps/BaseStation/Makefile | 5 + apps/tosthreads/capps/Blink/Blink.c | 76 +++ apps/tosthreads/capps/Blink/Makefile | 3 + apps/tosthreads/capps/Blink/stack.h | 41 ++ apps/tosthreads/capps/Bounce/Bounce.c | 91 +++ apps/tosthreads/capps/Bounce/Makefile | 3 + apps/tosthreads/capps/Makefile | 57 ++ apps/tosthreads/capps/Null/Makefile | 3 + apps/tosthreads/capps/Null/Null.c | 29 + apps/tosthreads/capps/RadioStress/Makefile | 3 + .../capps/RadioStress/RadioStress.c | 126 ++++ apps/tosthreads/capps/SenseAndSend/Makefile | 13 + .../capps/SenseAndSend/SenseAndSend.c | 135 +++++ .../capps/SenseCompressForward/Base/Makefile | 13 + .../Base/ReceiveStoreDecompress.c | 189 ++++++ .../Base/volumes-at45db.xml | 3 + .../Base/volumes-stm25p.xml | 3 + .../SenseCompressForward/Sensor/Makefile | 14 + .../Sensor/SenseStoreAndForward.c | 186 ++++++ .../SenseCompressForward/Sensor/decompress.c | 45 ++ .../Sensor/volumes-at45db.xml | 3 + .../Sensor/volumes-stm25p.xml | 3 + .../capps/SenseCompressForward/lz.c | 544 ++++++++++++++++++ .../capps/SenseCompressForward/lz.h | 56 ++ .../capps/SenseStoreAndForward/Makefile | 13 + .../SenseStoreAndForward.c | 170 ++++++ .../SenseStoreAndForward/volumes-at45db.xml | 3 + .../SenseStoreAndForward/volumes-stm25p.xml | 3 + apps/tosthreads/capps/TestLogStorage/Makefile | 2 + .../capps/TestLogStorage/TestLogStorage.c | 143 +++++ .../capps/TestLogStorage/volumes-at45db.xml | 3 + .../TestLogStorage/volumes-pxa27xp30.xml | 3 + .../capps/TestLogStorage/volumes-stm25p.xml | 3 + apps/tosthreads/capps/TestPrintf/Makefile | 4 + apps/tosthreads/capps/TestPrintf/TestPrintf.c | 52 ++ apps/tosthreads/capps/ThreadStress/Makefile | 4 + .../capps/ThreadStress/ThreadStress.c | 78 +++ 77 files changed, 4612 insertions(+) create mode 100644 apps/tosthreads/apps/BaseStation/BaseSendReceiveP.nc create mode 100644 apps/tosthreads/apps/BaseStation/BaseStationAppC.nc create mode 100644 apps/tosthreads/apps/BaseStation/BaseStationC.nc create mode 100644 apps/tosthreads/apps/BaseStation/Makefile create mode 100644 apps/tosthreads/apps/BaseStation/base_station.h create mode 100644 apps/tosthreads/apps/BaseStation/stack.h create mode 100644 apps/tosthreads/apps/Blink/BlinkAppC.nc create mode 100644 apps/tosthreads/apps/Blink/BlinkC.nc create mode 100644 apps/tosthreads/apps/Blink/Makefile create mode 100644 apps/tosthreads/apps/Bounce/BarrierBounceAppC.nc create mode 100644 apps/tosthreads/apps/Bounce/BarrierBounceC.nc create mode 100644 apps/tosthreads/apps/Bounce/Makefile create mode 100644 apps/tosthreads/apps/Bounce/barrier_bounce.h create mode 100644 apps/tosthreads/apps/Bounce/stack.h create mode 100644 apps/tosthreads/apps/Makefile create mode 100644 apps/tosthreads/apps/RadioStress/Makefile create mode 100644 apps/tosthreads/apps/RadioStress/RadioStressAppC.nc create mode 100644 apps/tosthreads/apps/RadioStress/RadioStressC.nc create mode 100644 apps/tosthreads/apps/SerialCompress/Makefile create mode 100644 apps/tosthreads/apps/SerialCompress/SerialCompressAppC.nc create mode 100644 apps/tosthreads/apps/SerialCompress/SerialCompressP.nc create mode 100644 apps/tosthreads/apps/SerialCompress/lz.c create mode 100644 apps/tosthreads/apps/SerialCompress/lz.h create mode 100644 apps/tosthreads/apps/SerialCompress/volumes-at45db.xml create mode 100644 apps/tosthreads/apps/SerialCompress/volumes-stm25p.xml create mode 100644 apps/tosthreads/apps/TestBlockStorage/Makefile create mode 100644 apps/tosthreads/apps/TestBlockStorage/README create mode 100644 apps/tosthreads/apps/TestBlockStorage/TestBlockStorageAppC.nc create mode 100644 apps/tosthreads/apps/TestBlockStorage/TestBlockStorageP.nc create mode 100644 apps/tosthreads/apps/TestBlockStorage/volumes-at45db.xml create mode 100644 apps/tosthreads/apps/TestBlockStorage/volumes-stm25p.xml create mode 100644 apps/tosthreads/apps/TestLogStorage/Makefile create mode 100644 apps/tosthreads/apps/TestLogStorage/TestLogStorageAppC.nc create mode 100644 apps/tosthreads/apps/TestLogStorage/TestLogStorageP.nc create mode 100644 apps/tosthreads/apps/TestLogStorage/volumes-at45db.xml create mode 100644 apps/tosthreads/apps/TestLogStorage/volumes-stm25p.xml create mode 100644 apps/tosthreads/apps/TestPrintf/Makefile create mode 100644 apps/tosthreads/apps/TestPrintf/TestPrintfAppC.nc create mode 100644 apps/tosthreads/apps/TestPrintf/TestPrintfC.nc create mode 100644 apps/tosthreads/capps/BaseStation/BaseStation.c create mode 100644 apps/tosthreads/capps/BaseStation/Makefile create mode 100644 apps/tosthreads/capps/Blink/Blink.c create mode 100644 apps/tosthreads/capps/Blink/Makefile create mode 100644 apps/tosthreads/capps/Blink/stack.h create mode 100644 apps/tosthreads/capps/Bounce/Bounce.c create mode 100644 apps/tosthreads/capps/Bounce/Makefile create mode 100644 apps/tosthreads/capps/Makefile create mode 100644 apps/tosthreads/capps/Null/Makefile create mode 100644 apps/tosthreads/capps/Null/Null.c create mode 100644 apps/tosthreads/capps/RadioStress/Makefile create mode 100644 apps/tosthreads/capps/RadioStress/RadioStress.c create mode 100644 apps/tosthreads/capps/SenseAndSend/Makefile create mode 100644 apps/tosthreads/capps/SenseAndSend/SenseAndSend.c create mode 100644 apps/tosthreads/capps/SenseCompressForward/Base/Makefile create mode 100644 apps/tosthreads/capps/SenseCompressForward/Base/ReceiveStoreDecompress.c create mode 100644 apps/tosthreads/capps/SenseCompressForward/Base/volumes-at45db.xml create mode 100644 apps/tosthreads/capps/SenseCompressForward/Base/volumes-stm25p.xml create mode 100644 apps/tosthreads/capps/SenseCompressForward/Sensor/Makefile create mode 100644 apps/tosthreads/capps/SenseCompressForward/Sensor/SenseStoreAndForward.c create mode 100644 apps/tosthreads/capps/SenseCompressForward/Sensor/decompress.c create mode 100644 apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-at45db.xml create mode 100644 apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-stm25p.xml create mode 100644 apps/tosthreads/capps/SenseCompressForward/lz.c create mode 100644 apps/tosthreads/capps/SenseCompressForward/lz.h create mode 100644 apps/tosthreads/capps/SenseStoreAndForward/Makefile create mode 100644 apps/tosthreads/capps/SenseStoreAndForward/SenseStoreAndForward.c create mode 100644 apps/tosthreads/capps/SenseStoreAndForward/volumes-at45db.xml create mode 100644 apps/tosthreads/capps/SenseStoreAndForward/volumes-stm25p.xml create mode 100644 apps/tosthreads/capps/TestLogStorage/Makefile create mode 100644 apps/tosthreads/capps/TestLogStorage/TestLogStorage.c create mode 100644 apps/tosthreads/capps/TestLogStorage/volumes-at45db.xml create mode 100644 apps/tosthreads/capps/TestLogStorage/volumes-pxa27xp30.xml create mode 100644 apps/tosthreads/capps/TestLogStorage/volumes-stm25p.xml create mode 100644 apps/tosthreads/capps/TestPrintf/Makefile create mode 100644 apps/tosthreads/capps/TestPrintf/TestPrintf.c create mode 100644 apps/tosthreads/capps/ThreadStress/Makefile create mode 100644 apps/tosthreads/capps/ThreadStress/ThreadStress.c diff --git a/apps/tosthreads/apps/BaseStation/BaseSendReceiveP.nc b/apps/tosthreads/apps/BaseStation/BaseSendReceiveP.nc new file mode 100644 index 00000000..3caa02c7 --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/BaseSendReceiveP.nc @@ -0,0 +1,152 @@ +/* + * 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 + * @author Chieh-Jan Mike Liang + */ + +generic module BaseSendReceiveP() { + uses { + interface Boot; + interface Thread as ReceiveThread; + interface Thread as SendThread; + interface ConditionVariable; + interface Mutex; + interface Pool; + interface Queue; + 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); + } + } + } +} diff --git a/apps/tosthreads/apps/BaseStation/BaseStationAppC.nc b/apps/tosthreads/apps/BaseStation/BaseStationAppC.nc new file mode 100644 index 00000000..b3e6a868 --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/BaseStationAppC.nc @@ -0,0 +1,127 @@ +/* + * 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 + * @author Chieh-Jan Mike Liang + */ + +#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; +} diff --git a/apps/tosthreads/apps/BaseStation/BaseStationC.nc b/apps/tosthreads/apps/BaseStation/BaseStationC.nc new file mode 100644 index 00000000..db790507 --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/BaseStationC.nc @@ -0,0 +1,59 @@ +/* + * 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 + */ + +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(); + } +} diff --git a/apps/tosthreads/apps/BaseStation/Makefile b/apps/tosthreads/apps/BaseStation/Makefile new file mode 100644 index 00000000..b408b9b7 --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/Makefile @@ -0,0 +1,9 @@ +COMPONENT=BaseStationAppC + +CFLAGS+=-DCC2420_DEF_CHANNEL=26 + +CFLAGS+=-DCC2420_NO_ACKNOWLEDGEMENTS +CFLAGS+=-DCC2420_NO_ADDRESS_RECOGNITION +CFLAGS+=-DTOSH_DATA_LENGTH=115 + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/BaseStation/base_station.h b/apps/tosthreads/apps/BaseStation/base_station.h new file mode 100644 index 00000000..71aa6890 --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/base_station.h @@ -0,0 +1,50 @@ + /* + * 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 + */ + +#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 diff --git a/apps/tosthreads/apps/BaseStation/stack.h b/apps/tosthreads/apps/BaseStation/stack.h new file mode 100644 index 00000000..ad68cf4c --- /dev/null +++ b/apps/tosthreads/apps/BaseStation/stack.h @@ -0,0 +1,47 @@ +/* + * 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 + */ + +#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 diff --git a/apps/tosthreads/apps/Blink/BlinkAppC.nc b/apps/tosthreads/apps/Blink/BlinkAppC.nc new file mode 100644 index 00000000..7748e878 --- /dev/null +++ b/apps/tosthreads/apps/Blink/BlinkAppC.nc @@ -0,0 +1,53 @@ +/* + * 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; +} + diff --git a/apps/tosthreads/apps/Blink/BlinkC.nc b/apps/tosthreads/apps/Blink/BlinkC.nc new file mode 100644 index 00000000..e4027006 --- /dev/null +++ b/apps/tosthreads/apps/Blink/BlinkC.nc @@ -0,0 +1,77 @@ +/* + * 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); + } + } +} diff --git a/apps/tosthreads/apps/Blink/Makefile b/apps/tosthreads/apps/Blink/Makefile new file mode 100644 index 00000000..5a42cf1c --- /dev/null +++ b/apps/tosthreads/apps/Blink/Makefile @@ -0,0 +1,4 @@ +COMPONENT=BlinkAppC +CFLAGS += -I$(TOS_THREADS_DIR)/tos/sensorboards/tmote_onboard + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/Bounce/BarrierBounceAppC.nc b/apps/tosthreads/apps/Bounce/BarrierBounceAppC.nc new file mode 100644 index 00000000..62eff0f0 --- /dev/null +++ b/apps/tosthreads/apps/Bounce/BarrierBounceAppC.nc @@ -0,0 +1,102 @@ +/* + * 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 + */ + +#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; +} + diff --git a/apps/tosthreads/apps/Bounce/BarrierBounceC.nc b/apps/tosthreads/apps/Bounce/BarrierBounceC.nc new file mode 100644 index 00000000..5a860794 --- /dev/null +++ b/apps/tosthreads/apps/Bounce/BarrierBounceC.nc @@ -0,0 +1,141 @@ +/* + * 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 + */ + +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); + } + } +} diff --git a/apps/tosthreads/apps/Bounce/Makefile b/apps/tosthreads/apps/Bounce/Makefile new file mode 100644 index 00000000..7c304e4c --- /dev/null +++ b/apps/tosthreads/apps/Bounce/Makefile @@ -0,0 +1,3 @@ +COMPONENT=BarrierBounceAppC +PFLAGS += -DCC2420_HW_ACKNOWLEDGEMENTS +include $(MAKERULES) diff --git a/apps/tosthreads/apps/Bounce/barrier_bounce.h b/apps/tosthreads/apps/Bounce/barrier_bounce.h new file mode 100644 index 00000000..5433e57b --- /dev/null +++ b/apps/tosthreads/apps/Bounce/barrier_bounce.h @@ -0,0 +1,48 @@ + /* + * 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 + */ + +#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 diff --git a/apps/tosthreads/apps/Bounce/stack.h b/apps/tosthreads/apps/Bounce/stack.h new file mode 100644 index 00000000..ec529324 --- /dev/null +++ b/apps/tosthreads/apps/Bounce/stack.h @@ -0,0 +1,46 @@ +/* + * 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 + */ + +#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 diff --git a/apps/tosthreads/apps/Makefile b/apps/tosthreads/apps/Makefile new file mode 100644 index 00000000..90989c70 --- /dev/null +++ b/apps/tosthreads/apps/Makefile @@ -0,0 +1,57 @@ +#-*-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 diff --git a/apps/tosthreads/apps/RadioStress/Makefile b/apps/tosthreads/apps/RadioStress/Makefile new file mode 100644 index 00000000..e074e16c --- /dev/null +++ b/apps/tosthreads/apps/RadioStress/Makefile @@ -0,0 +1,3 @@ +COMPONENT=RadioStressAppC + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/RadioStress/RadioStressAppC.nc b/apps/tosthreads/apps/RadioStress/RadioStressAppC.nc new file mode 100644 index 00000000..c3d02022 --- /dev/null +++ b/apps/tosthreads/apps/RadioStress/RadioStressAppC.nc @@ -0,0 +1,74 @@ +/* + * 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 + */ + +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; +} + diff --git a/apps/tosthreads/apps/RadioStress/RadioStressC.nc b/apps/tosthreads/apps/RadioStress/RadioStressC.nc new file mode 100644 index 00000000..aca6f58c --- /dev/null +++ b/apps/tosthreads/apps/RadioStress/RadioStressC.nc @@ -0,0 +1,122 @@ +/* + * 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 + */ + +#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); + } + } + } +} diff --git a/apps/tosthreads/apps/SerialCompress/Makefile b/apps/tosthreads/apps/SerialCompress/Makefile new file mode 100644 index 00000000..2ad59bfb --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/Makefile @@ -0,0 +1,5 @@ +COMPONENT=SerialCompressAppC + +CFLAGS += -I../bcl-1.2.0/src + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/SerialCompress/SerialCompressAppC.nc b/apps/tosthreads/apps/SerialCompress/SerialCompressAppC.nc new file mode 100644 index 00000000..56e68d51 --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/SerialCompressAppC.nc @@ -0,0 +1,23 @@ +#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; +} diff --git a/apps/tosthreads/apps/SerialCompress/SerialCompressP.nc b/apps/tosthreads/apps/SerialCompress/SerialCompressP.nc new file mode 100644 index 00000000..dbc3a623 --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/SerialCompressP.nc @@ -0,0 +1,151 @@ +#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) {} +} diff --git a/apps/tosthreads/apps/SerialCompress/lz.c b/apps/tosthreads/apps/SerialCompress/lz.c new file mode 100644 index 00000000..d4726c76 --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/lz.c @@ -0,0 +1,544 @@ +/************************************************************************* +* 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 ); +} diff --git a/apps/tosthreads/apps/SerialCompress/lz.h b/apps/tosthreads/apps/SerialCompress/lz.h new file mode 100644 index 00000000..9ba1f685 --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/lz.h @@ -0,0 +1,56 @@ +/************************************************************************* +* 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_ */ diff --git a/apps/tosthreads/apps/SerialCompress/volumes-at45db.xml b/apps/tosthreads/apps/SerialCompress/volumes-at45db.xml new file mode 100644 index 00000000..635db4ee --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/SerialCompress/volumes-stm25p.xml b/apps/tosthreads/apps/SerialCompress/volumes-stm25p.xml new file mode 100644 index 00000000..51e665d0 --- /dev/null +++ b/apps/tosthreads/apps/SerialCompress/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/TestBlockStorage/Makefile b/apps/tosthreads/apps/TestBlockStorage/Makefile new file mode 100644 index 00000000..f4a0d1d3 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/Makefile @@ -0,0 +1,3 @@ +COMPONENT=TestBlockStorageAppC + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/TestBlockStorage/README b/apps/tosthreads/apps/TestBlockStorage/README new file mode 100644 index 00000000..dac5ad39 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/README @@ -0,0 +1,2 @@ +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. diff --git a/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageAppC.nc b/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageAppC.nc new file mode 100644 index 00000000..b2933857 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageAppC.nc @@ -0,0 +1,45 @@ +/* + * 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 + */ + +#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; +} diff --git a/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageP.nc b/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageP.nc new file mode 100644 index 00000000..75721279 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/TestBlockStorageP.nc @@ -0,0 +1,85 @@ +/* + * 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 + */ + +#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); + } +} diff --git a/apps/tosthreads/apps/TestBlockStorage/volumes-at45db.xml b/apps/tosthreads/apps/TestBlockStorage/volumes-at45db.xml new file mode 100644 index 00000000..83809ff9 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/TestBlockStorage/volumes-stm25p.xml b/apps/tosthreads/apps/TestBlockStorage/volumes-stm25p.xml new file mode 100644 index 00000000..6fed4204 --- /dev/null +++ b/apps/tosthreads/apps/TestBlockStorage/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/TestLogStorage/Makefile b/apps/tosthreads/apps/TestLogStorage/Makefile new file mode 100644 index 00000000..8d405695 --- /dev/null +++ b/apps/tosthreads/apps/TestLogStorage/Makefile @@ -0,0 +1,3 @@ +COMPONENT=TestLogStorageAppC + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/TestLogStorage/TestLogStorageAppC.nc b/apps/tosthreads/apps/TestLogStorage/TestLogStorageAppC.nc new file mode 100644 index 00000000..76def4b3 --- /dev/null +++ b/apps/tosthreads/apps/TestLogStorage/TestLogStorageAppC.nc @@ -0,0 +1,34 @@ +/* + * 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 + */ + +#include "StorageVolumes.h" + +configuration TestLogStorageAppC {} + +implementation +{ + components new BlockingLogStorageC(VOLUME_TESTLOGSTORAGE, TRUE); +} diff --git a/apps/tosthreads/apps/TestLogStorage/TestLogStorageP.nc b/apps/tosthreads/apps/TestLogStorage/TestLogStorageP.nc new file mode 100644 index 00000000..cd9d258d --- /dev/null +++ b/apps/tosthreads/apps/TestLogStorage/TestLogStorageP.nc @@ -0,0 +1,40 @@ +/* + * 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 + */ + +#include "Storage.h" + +module TestLogStorageP +{ + uses { + interface Boot; + } +} + +implementation +{ + event void Boot.booted() { + } +} diff --git a/apps/tosthreads/apps/TestLogStorage/volumes-at45db.xml b/apps/tosthreads/apps/TestLogStorage/volumes-at45db.xml new file mode 100644 index 00000000..49878996 --- /dev/null +++ b/apps/tosthreads/apps/TestLogStorage/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/TestLogStorage/volumes-stm25p.xml b/apps/tosthreads/apps/TestLogStorage/volumes-stm25p.xml new file mode 100644 index 00000000..4e0bdee6 --- /dev/null +++ b/apps/tosthreads/apps/TestLogStorage/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/apps/TestPrintf/Makefile b/apps/tosthreads/apps/TestPrintf/Makefile new file mode 100644 index 00000000..7f5ec68e --- /dev/null +++ b/apps/tosthreads/apps/TestPrintf/Makefile @@ -0,0 +1,4 @@ +COMPONENT=TestPrintfAppC +PFLAGS += -I$(TOSDIR)/lib/tosthreads/lib/printf + +include $(MAKERULES) diff --git a/apps/tosthreads/apps/TestPrintf/TestPrintfAppC.nc b/apps/tosthreads/apps/TestPrintf/TestPrintfAppC.nc new file mode 100644 index 00000000..e9d8d1ac --- /dev/null +++ b/apps/tosthreads/apps/TestPrintf/TestPrintfAppC.nc @@ -0,0 +1,51 @@ +/* + * 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; +} + diff --git a/apps/tosthreads/apps/TestPrintf/TestPrintfC.nc b/apps/tosthreads/apps/TestPrintf/TestPrintfC.nc new file mode 100644 index 00000000..904a3919 --- /dev/null +++ b/apps/tosthreads/apps/TestPrintf/TestPrintfC.nc @@ -0,0 +1,55 @@ +/* + * 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++); + } + } +} diff --git a/apps/tosthreads/capps/BaseStation/BaseStation.c b/apps/tosthreads/capps/BaseStation/BaseStation.c new file mode 100644 index 00000000..6aa49538 --- /dev/null +++ b/apps/tosthreads/capps/BaseStation/BaseStation.c @@ -0,0 +1,194 @@ +/* + * 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 + */ + +//#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); +} diff --git a/apps/tosthreads/capps/BaseStation/Makefile b/apps/tosthreads/capps/BaseStation/Makefile new file mode 100644 index 00000000..9c1d4a94 --- /dev/null +++ b/apps/tosthreads/capps/BaseStation/Makefile @@ -0,0 +1,5 @@ +TOSTHREAD_MAIN=BaseStation.c +CFLAGS += -DCC2420_NO_ACKNOWLEDGEMENTS +CFLAGS += -DCC2420_NO_ADDRESS_RECOGNITION + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/Blink/Blink.c b/apps/tosthreads/capps/Blink/Blink.c new file mode 100644 index 00000000..ca19ae8d --- /dev/null +++ b/apps/tosthreads/capps/Blink/Blink.c @@ -0,0 +1,76 @@ +/* + * 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); + } +} diff --git a/apps/tosthreads/capps/Blink/Makefile b/apps/tosthreads/capps/Blink/Makefile new file mode 100644 index 00000000..aecfc210 --- /dev/null +++ b/apps/tosthreads/capps/Blink/Makefile @@ -0,0 +1,3 @@ +TOSTHREAD_MAIN=Blink.c + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/Blink/stack.h b/apps/tosthreads/capps/Blink/stack.h new file mode 100644 index 00000000..fdaf48cb --- /dev/null +++ b/apps/tosthreads/capps/Blink/stack.h @@ -0,0 +1,41 @@ +/* + * 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 + */ + +enum { + NOTHING_STACK_SIZE = 500, + BLINK0_STACK_SIZE = 500, + BLINK1_STACK_SIZE = 500, + BLINK2_STACK_SIZE = 500, +}; diff --git a/apps/tosthreads/capps/Bounce/Bounce.c b/apps/tosthreads/capps/Bounce/Bounce.c new file mode 100644 index 00000000..2d2b34eb --- /dev/null +++ b/apps/tosthreads/capps/Bounce/Bounce.c @@ -0,0 +1,91 @@ +/* + * 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 + */ + +#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); + } +} diff --git a/apps/tosthreads/capps/Bounce/Makefile b/apps/tosthreads/capps/Bounce/Makefile new file mode 100644 index 00000000..0e7e0ae6 --- /dev/null +++ b/apps/tosthreads/capps/Bounce/Makefile @@ -0,0 +1,3 @@ +TOSTHREAD_MAIN=Bounce.c + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/Makefile b/apps/tosthreads/capps/Makefile new file mode 100644 index 00000000..90989c70 --- /dev/null +++ b/apps/tosthreads/capps/Makefile @@ -0,0 +1,57 @@ +#-*-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 diff --git a/apps/tosthreads/capps/Null/Makefile b/apps/tosthreads/capps/Null/Makefile new file mode 100644 index 00000000..549999b7 --- /dev/null +++ b/apps/tosthreads/capps/Null/Makefile @@ -0,0 +1,3 @@ +TOSTHREAD_MAIN=Null.c + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/Null/Null.c b/apps/tosthreads/capps/Null/Null.c new file mode 100644 index 00000000..889ffabe --- /dev/null +++ b/apps/tosthreads/capps/Null/Null.c @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#include "tosthread.h" + +void tosthread_main(void* arg) {} diff --git a/apps/tosthreads/capps/RadioStress/Makefile b/apps/tosthreads/capps/RadioStress/Makefile new file mode 100644 index 00000000..9fceb0a4 --- /dev/null +++ b/apps/tosthreads/capps/RadioStress/Makefile @@ -0,0 +1,3 @@ +TOSTHREAD_MAIN=RadioStress.c + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/RadioStress/RadioStress.c b/apps/tosthreads/capps/RadioStress/RadioStress.c new file mode 100644 index 00000000..067e08fd --- /dev/null +++ b/apps/tosthreads/capps/RadioStress/RadioStress.c @@ -0,0 +1,126 @@ +/* + * 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 + */ + +//#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(); + } + } + } +} diff --git a/apps/tosthreads/capps/SenseAndSend/Makefile b/apps/tosthreads/capps/SenseAndSend/Makefile new file mode 100644 index 00000000..911a0420 --- /dev/null +++ b/apps/tosthreads/capps/SenseAndSend/Makefile @@ -0,0 +1,13 @@ +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 diff --git a/apps/tosthreads/capps/SenseAndSend/SenseAndSend.c b/apps/tosthreads/capps/SenseAndSend/SenseAndSend.c new file mode 100644 index 00000000..9546781d --- /dev/null +++ b/apps/tosthreads/capps/SenseAndSend/SenseAndSend.c @@ -0,0 +1,135 @@ +/* + * 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 + */ + +#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); + } +} diff --git a/apps/tosthreads/capps/SenseCompressForward/Base/Makefile b/apps/tosthreads/capps/SenseCompressForward/Base/Makefile new file mode 100644 index 00000000..425ed21c --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Base/Makefile @@ -0,0 +1,13 @@ +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 diff --git a/apps/tosthreads/capps/SenseCompressForward/Base/ReceiveStoreDecompress.c b/apps/tosthreads/capps/SenseCompressForward/Base/ReceiveStoreDecompress.c new file mode 100644 index 00000000..996feb8d --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Base/ReceiveStoreDecompress.c @@ -0,0 +1,189 @@ +#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(); + } + } + } + } +} diff --git a/apps/tosthreads/capps/SenseCompressForward/Base/volumes-at45db.xml b/apps/tosthreads/capps/SenseCompressForward/Base/volumes-at45db.xml new file mode 100644 index 00000000..635db4ee --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Base/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/SenseCompressForward/Base/volumes-stm25p.xml b/apps/tosthreads/capps/SenseCompressForward/Base/volumes-stm25p.xml new file mode 100644 index 00000000..51e665d0 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Base/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/SenseCompressForward/Sensor/Makefile b/apps/tosthreads/capps/SenseCompressForward/Sensor/Makefile new file mode 100644 index 00000000..bca94d23 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Sensor/Makefile @@ -0,0 +1,14 @@ +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 diff --git a/apps/tosthreads/capps/SenseCompressForward/Sensor/SenseStoreAndForward.c b/apps/tosthreads/capps/SenseCompressForward/Sensor/SenseStoreAndForward.c new file mode 100644 index 00000000..7640490d --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Sensor/SenseStoreAndForward.c @@ -0,0 +1,186 @@ +#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(); + } +} diff --git a/apps/tosthreads/capps/SenseCompressForward/Sensor/decompress.c b/apps/tosthreads/capps/SenseCompressForward/Sensor/decompress.c new file mode 100644 index 00000000..af0d1248 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Sensor/decompress.c @@ -0,0 +1,45 @@ +#include +#include +#include +#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 ", argv[0]); + } + + return 0; +} diff --git a/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-at45db.xml b/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-at45db.xml new file mode 100644 index 00000000..635db4ee --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-stm25p.xml b/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-stm25p.xml new file mode 100644 index 00000000..51e665d0 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/Sensor/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/SenseCompressForward/lz.c b/apps/tosthreads/capps/SenseCompressForward/lz.c new file mode 100644 index 00000000..d4726c76 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/lz.c @@ -0,0 +1,544 @@ +/************************************************************************* +* 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 ); +} diff --git a/apps/tosthreads/capps/SenseCompressForward/lz.h b/apps/tosthreads/capps/SenseCompressForward/lz.h new file mode 100644 index 00000000..9ba1f685 --- /dev/null +++ b/apps/tosthreads/capps/SenseCompressForward/lz.h @@ -0,0 +1,56 @@ +/************************************************************************* +* 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_ */ diff --git a/apps/tosthreads/capps/SenseStoreAndForward/Makefile b/apps/tosthreads/capps/SenseStoreAndForward/Makefile new file mode 100644 index 00000000..f81126e1 --- /dev/null +++ b/apps/tosthreads/capps/SenseStoreAndForward/Makefile @@ -0,0 +1,13 @@ +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 diff --git a/apps/tosthreads/capps/SenseStoreAndForward/SenseStoreAndForward.c b/apps/tosthreads/capps/SenseStoreAndForward/SenseStoreAndForward.c new file mode 100644 index 00000000..2aa52d17 --- /dev/null +++ b/apps/tosthreads/capps/SenseStoreAndForward/SenseStoreAndForward.c @@ -0,0 +1,170 @@ +/* + * 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 + */ + +#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(); + } +} diff --git a/apps/tosthreads/capps/SenseStoreAndForward/volumes-at45db.xml b/apps/tosthreads/capps/SenseStoreAndForward/volumes-at45db.xml new file mode 100644 index 00000000..635db4ee --- /dev/null +++ b/apps/tosthreads/capps/SenseStoreAndForward/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/SenseStoreAndForward/volumes-stm25p.xml b/apps/tosthreads/capps/SenseStoreAndForward/volumes-stm25p.xml new file mode 100644 index 00000000..51e665d0 --- /dev/null +++ b/apps/tosthreads/capps/SenseStoreAndForward/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/TestLogStorage/Makefile b/apps/tosthreads/capps/TestLogStorage/Makefile new file mode 100644 index 00000000..957c9568 --- /dev/null +++ b/apps/tosthreads/capps/TestLogStorage/Makefile @@ -0,0 +1,2 @@ +TOSTHREAD_MAIN=TestLogStorage.c +include $(MAKERULES) diff --git a/apps/tosthreads/capps/TestLogStorage/TestLogStorage.c b/apps/tosthreads/capps/TestLogStorage/TestLogStorage.c new file mode 100644 index 00000000..b157228a --- /dev/null +++ b/apps/tosthreads/capps/TestLogStorage/TestLogStorage.c @@ -0,0 +1,143 @@ +/* + * 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 + */ + +#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(); + } +} diff --git a/apps/tosthreads/capps/TestLogStorage/volumes-at45db.xml b/apps/tosthreads/capps/TestLogStorage/volumes-at45db.xml new file mode 100644 index 00000000..d6a3bea7 --- /dev/null +++ b/apps/tosthreads/capps/TestLogStorage/volumes-at45db.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/TestLogStorage/volumes-pxa27xp30.xml b/apps/tosthreads/capps/TestLogStorage/volumes-pxa27xp30.xml new file mode 100644 index 00000000..9a90b908 --- /dev/null +++ b/apps/tosthreads/capps/TestLogStorage/volumes-pxa27xp30.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/TestLogStorage/volumes-stm25p.xml b/apps/tosthreads/capps/TestLogStorage/volumes-stm25p.xml new file mode 100644 index 00000000..d400fdbe --- /dev/null +++ b/apps/tosthreads/capps/TestLogStorage/volumes-stm25p.xml @@ -0,0 +1,3 @@ + + + diff --git a/apps/tosthreads/capps/TestPrintf/Makefile b/apps/tosthreads/capps/TestPrintf/Makefile new file mode 100644 index 00000000..11976e49 --- /dev/null +++ b/apps/tosthreads/capps/TestPrintf/Makefile @@ -0,0 +1,4 @@ +TOSTHREAD_MAIN=TestPrintf.c +CFLAGS += -I$(TOSDIR)/lib/tosthreads/lib/printf + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/TestPrintf/TestPrintf.c b/apps/tosthreads/capps/TestPrintf/TestPrintf.c new file mode 100644 index 00000000..28badaf7 --- /dev/null +++ b/apps/tosthreads/capps/TestPrintf/TestPrintf.c @@ -0,0 +1,52 @@ +/* + * 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++); + } +} diff --git a/apps/tosthreads/capps/ThreadStress/Makefile b/apps/tosthreads/capps/ThreadStress/Makefile new file mode 100644 index 00000000..720fe27b --- /dev/null +++ b/apps/tosthreads/capps/ThreadStress/Makefile @@ -0,0 +1,4 @@ +TOSTHREAD_MAIN=ThreadStress.c +PFLAGS += -I$(TOS_THREADS_DIR)/tos/csystem/Loader + +include $(MAKERULES) diff --git a/apps/tosthreads/capps/ThreadStress/ThreadStress.c b/apps/tosthreads/capps/ThreadStress/ThreadStress.c new file mode 100644 index 00000000..89497382 --- /dev/null +++ b/apps/tosthreads/capps/ThreadStress/ThreadStress.c @@ -0,0 +1,78 @@ +/* + * 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); +} -- 2.39.2