From 9c96fa015ee8c80e9ab48154c4ecc4fbcfe13087 Mon Sep 17 00:00:00 2001 From: Brad Luyster Date: Fri, 11 May 2012 19:21:30 -0400 Subject: Initial Commit --- Arduino/Queue.cpp | 147 ++++++++++++++++++++++++++++++++ Arduino/Queue.h | 39 +++++++++ Arduino/Tests/arduinoTests.ino | 185 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+) create mode 100644 Arduino/Queue.cpp create mode 100644 Arduino/Queue.h create mode 100644 Arduino/Tests/arduinoTests.ino (limited to 'Arduino') diff --git a/Arduino/Queue.cpp b/Arduino/Queue.cpp new file mode 100644 index 0000000..f428228 --- /dev/null +++ b/Arduino/Queue.cpp @@ -0,0 +1,147 @@ +#include "Queue.h" + +Queue::Queue() +{ + _itemsInQueue = 0; + _queueStart = 0; + _queueEnd = 0; +} + +int Queue::scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur) +{ + int rv = 0; + + if(strlen(id) > 7) + { + rv = -1; + } else { + + queueItem newItem; + newItem.fPtr = func; + memset(newItem.itemName, 0, 8); + memcpy(newItem.itemName, id, strlen(id)); + newItem.recur = recur; + newItem.next = initialRun; + + rv = _addToQueue(newItem); + } + + return rv; +} + +int Queue::scheduleRemoveFunction(const char * id) +{ + queueItem target; + int rv = -1; + for (int i = 0; i < _itemsInQueue; ++i) + { + if(_queueGetTop(target) == 0) + { + if(strcmp(target.itemName, id) == 0) + { + rv = 0; + } else { + _addToQueue(target); + } + } else { + rv = -1; + break; + } + } + + return rv; +} + +int Queue::scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur) +{ + queueItem target; + int rv = -1; + for (int i = 0; i < _itemsInQueue; ++i) + { + if(_queueGetTop(target) == 0) + { + if(strcmp(target.itemName, id) == 0) + { + target.next = nextRunTime; + target.recur = newRecur; + rv = 0; + } + _addToQueue(target); + } else { + rv = -1; + break; + } + } + + return rv; +} + +int Queue::Run(unsigned long now) +{ + queueItem target; + int rv = 0; + if(_itemsInQueue == 0) + { + rv = -1; + } + for (int i = 0; i < _itemsInQueue; ++i) + { + if(_queueGetTop(target)==0) + { + if(target.next <= now) + { + int tRv; + tRv = (target.fPtr)(now); + if(tRv == 0) + { + rv++; + } + if(target.recur != 0) + { + target.next = now + target.recur; + _addToQueue(target); + } + } else { + _addToQueue(target); + } + } else { + rv = -1; + break; + } + } + + return rv; +} + +int Queue::_queueGetTop(queueItem &item) +{ + int rv = 0; + //Remove the top item, stuff it into item + if (_queueEnd != _queueStart) { + queueItem tempQueueItem = _schedule[_queueStart]; + //This Algorithm also from Wikipedia. + _queueStart = (_queueStart + 1) % QueueScheduleSize; + item = tempQueueItem; + _itemsInQueue--; + } else { + //if the buffer is empty, return an error code + rv = -1; + } + + return rv; +} + +int Queue::_addToQueue(queueItem item) +{ + //This is just a circular buffer, and this algorithm is stolen from wikipedia + int rv = 0; + if ((_queueEnd + 1) % QueueScheduleSize != _queueStart) { + _schedule[_queueEnd] = item; + _queueEnd = (_queueEnd + 1) % QueueScheduleSize; + _itemsInQueue++; + } else { + //if buffer is full, error + rv = -1; + } + return rv; +} \ No newline at end of file diff --git a/Arduino/Queue.h b/Arduino/Queue.h new file mode 100644 index 0000000..d23afb3 --- /dev/null +++ b/Arduino/Queue.h @@ -0,0 +1,39 @@ +#ifndef QUEUE_H +#define QUEUE_H + +#include "Arduino.h" + +typedef int (*queuedFunction)(unsigned long); + +#define QueueScheduleSize 11 + +struct queueItem { + queuedFunction fPtr; + unsigned long next; + unsigned long recur; + char itemName[8]; +}; + +class Queue +{ +private: + unsigned int _queueStart; + unsigned int _queueEnd; + unsigned int _itemsInQueue; + queueItem _schedule[QueueScheduleSize]; + + int _queueGetTop(queueItem &item); + int _addToQueue(queueItem item); + +public: + Queue(); + + int scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur); + int scheduleRemoveFunction(const char * id); + int scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur); + + int Run(unsigned long now); + /* data */ +}; + +#endif \ No newline at end of file diff --git a/Arduino/Tests/arduinoTests.ino b/Arduino/Tests/arduinoTests.ino new file mode 100644 index 0000000..653ae5f --- /dev/null +++ b/Arduino/Tests/arduinoTests.ino @@ -0,0 +1,185 @@ +#include + +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(13, OUTPUT); + Serial.begin(9600); + Serial.println("Alive"); + + int testStatus = 0; + testStatus |= test_addTooMany(); + testStatus |= test_removeNonExistent(); + testStatus |= test_tooManyCharacters(); + testStatus |= test_changeNonExistent(); + testStatus |= test_runEmpty(); + + if(testStatus == 0) + { + Serial.println("All tests passed."); + } else { + Serial.println("Something Failed."); + } + +} + +void loop() { + delay(1000); +} + +int testFunction(unsigned long now) +{ + Serial.print("Hello: "); + Serial.print(now); + Serial.println(); +} + +int test_addTooMany(void) +{ + Queue testQueue; + int rv; + int testStatus = 0; + rv = testQueue.scheduleFunction(testFunction, "Test1", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test2", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test3", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test4", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test5", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test6", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test7", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test8", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test9", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test10", 5000, 1000); + if(rv != 0) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + rv = testQueue.scheduleFunction(testFunction, "Test11", 5000, 1000); + if(rv != -1) + { + Serial.println("test_addTooMany failed."); + testStatus = -1; + } + + return testStatus; +} + +int test_removeNonExistent(void) +{ + Queue testQueue; + int rv; + int testStatus = 0; + rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000); + if(rv != 0) + { + Serial.println("test_removeNonExistent failed."); + testStatus = -1; + } + rv = testQueue.scheduleRemoveFunction("Fail"); + if(rv != -1) + { + Serial.println("test_removeNonExistent failed."); + testStatus = -1; + } + return testStatus; +} + +int test_tooManyCharacters(void) +{ + Queue testQueue; + int rv; + int testStatus = 0; + rv = testQueue.scheduleFunction(testFunction, "ReallyLongName", 5000, 1000); + if(rv != -1) + { + Serial.println("test_tooManyCharacters failed."); + testStatus = -1; + } + return testStatus; +} + +int test_changeNonExistent(void) +{ + Queue testQueue; + int rv; + int testStatus = 0; + rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000); + if(rv != 0) + { + Serial.println("test_changeNonExistent failed."); + testStatus = -1; + } + rv = testQueue.scheduleChangeFunction("Fail", 1000, 1000); + if(rv != -1) + { + Serial.println("test_changeNonExistent failed."); + testStatus = -1; + } + return testStatus; +} + +int test_runEmpty(void) +{ + Queue myQueue; + int rv = 0; + int testStatus = 0; + rv = myQueue.Run(10); + if (rv != -1) + { + Serial.println("test_runEmpty failed."); + testStatus = -1; + } + return testStatus; +} \ No newline at end of file -- cgit v1.2.3