EventFramework library allows the creation of an event-driven infrastructure in which small "threads" can handle events in a multithreaded execution context. The EventFramework can be configured to act as a cooperative or a fully-preemptive kernel with fixed-priority scheduling. Furthermore, this kernel matches run-to-completion semantics, and hence a single-stack configuration is enough to keep running this multithreaded execution environment. As running threads shares global stack, a huge quantity of RAM is saved in contrast with traditional RTOSes.
Revision 0:9d09acc8f9d9, committed 2012-10-01
- Comitter:
- raulMrello
- Date:
- Mon Oct 01 10:38:45 2012 +0000
- Child:
- 1:ec12f2e32faf
- Commit message:
- Release 1.00; EventFramework library allows the creation of an event-driven infrastructure for lightweight multithreaded applications with cooperative or fully-preemptive scheduling.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Event/Event.cpp Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,90 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "Event.h" + +Event::Event(uint16_t prio){ + this->prio = prio; + base = NULL; + data = NULL; + hlist = NULL; +} + +Event::~Event(void){ + prio = 0; + data = NULL; + base = NULL; + if(hlist){ + delete hlist; + } +} + +void Event::SetData(void* data){ + this->data = data; +} + +void Event::SetBase(Event* ev){ + base = ev; +} + +void* Event::GetData(void){ + return data; +} + +Event* Event::GetBase(void){ + return base; +} + +List* Event::GetList(void){ + return hlist; +} + +uint16_t Event::GetPrio(void){ + return prio; +} + +void Event::Subscribe(EventHandler * hnd){ + // if EventHandler list is not created yet, then creates and add handler + if(!hlist){ + hlist = new List(hnd); + return; + } + // else insert the handler according with its priority + Node* node = hlist->GetFirstNode(); + EventHandler* data = (EventHandler*)node->GetData(); + while(data->GetPrio() <= hnd->GetPrio()){ + Node* next = node->GetNext(); + if(!next){ + hlist->AddAfter(node, hnd); + return; + } + data = (EventHandler*)next->GetData(); + } + Node* newHead = hlist->AddBefore(node, hnd); + if(newHead){ + hlist->SetFirstNode(newHead); + } +} + +void Event::Unsubscribe(EventHandler* hnd){ + hlist->RemoveItem(hnd); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Event/Event.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,117 @@ +/* mbed EventFramework Library + * Copyright (c) 2012-2016 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _EVENT_H_ +#define _EVENT_H_ + +#include "../List/List.h" +#include "../EventHandler/EventHandler.h" + +/** Event class + * + * Events are the inter-process communication mechanism within the EventFramework. Each + * event registered in the framework stands for a type of signal, which can accept + * attached data to be processed by any processing entity; in this case by EventHandlers + * through its attached EventDispatchingRoutine. + * Each event has a fixed priority in the range: 0 (max) to 65535 (min) and can keep track + * of a list of installed EventHandlers to invoke when the event is published. Published + * events are queued into a PendingList managed by the EventFramework scheduler, who will + * dispatch them accordingly with their priority (from highest to lowest). + */ +class Event{ + public: + /** Creates an Event with a specified priority + * + * @param prio Event priority. Range 0[max] - 65535[min] + */ + Event(uint16_t prio); + + ~Event(); + + /** Gets the Event priority. + * + * @returns event priority + */ + uint16_t GetPrio(void); + + /** Gets the base event reference + * + * To explain the way in which a base reference is used, it is necessary to explain what + * happens on event publishing. Within the framework, only registered events can be published. + * while publishing an event of one type, a new event is allocated (by: new Event()) and it is referenced + * to the existing one by its private [base] property. This base reference allows the scheduler to invoke + * to all its listeners. + * + * @returns event reference to the base event. + */ + Event* GetBase(void); + + /** Sets the Event reference to which this is based from. + * + * @param ev event reference to link with. + */ + void SetBase(Event* ev); + + /** Sets attached data to the Event. + * + * Events can attach extra data to be processed by the listener. Through this interface, a data + * reference can be attached to the event. + * + * @param data data reference to be attached to the event for further processing. + */ + void SetData(void* data); + + /** Gets event's attached data. + * + * @returns reference to the attached data. + */ + void* GetData(void); + + /** Adds an EventHandler to process this kind of events. + * + * Each event manages an internal list of handlers. If an event of this kind is published + * all handlers in this list will be fired to process the event. + * + * @param hnd EventHandler reference to subscribe to this Event. + */ + void Subscribe(EventHandler* hnd); + + /** Erases an EventHandler to stop processing this kind of events. + * + * @param hnd EventHandler reference to unsubscribe from this Event. + */ + void Unsubscribe(EventHandler* hnd); + + /** Gets the list of subscribed EventHandlers + * + * @returns reference to the list of subscribed EventHandlers. + */ + List* GetList(void); + + private: + uint16_t prio; + void* data; + List* hlist; + Event* base; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EventFramework.cpp Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,238 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "EventFramework.h" +#include "../Node/Node.h" + +void EmptyFn(void){} + +EventFramework::EventFramework(uint32_t schpol, void (*cbEI)(void), void (*lock)(void), void (*unlock)(void)){ + currPrio = 0xFFFF; + nesting = 0; + cbLock = EmptyFn; + cbUnlock = EmptyFn; + cbEnableInterrupts = EmptyFn; + list = NULL; + queue = NULL; + event = NULL; + ctflags |= (EventFramework::SCHED_KEY & schpol); + if(cbEI){ + cbEnableInterrupts = cbEI; + } + if(lock){ + cbLock = lock; + } + if(unlock){ + cbUnlock = unlock; + } +} + +EventFramework::~EventFramework(){ + if(list) + delete list; + if(queue) + delete queue; +} + +void EventFramework::AddEvent(Event* ev){ + cbLock(); + if(!list){ + list = new List(ev); + return; + } + AddEventToList(ev,list); + cbUnlock(); +} + +void EventFramework::AddPendingEvent(Event* ev){ + cbLock(); + if(!queue){ + queue = new List(ev); + return; + } + AddEventToList(ev,queue); + cbUnlock(); +} + +void EventFramework::AddEventToList(Event* ev, List* plist){ + Node* node = plist->GetFirstNode(); + Event* data = (Event*)node->GetData(); + while(data->GetPrio() <= ev->GetPrio()){ + Node* next = node->GetNext(); + if(!next){ + plist->AddAfter(node, ev); + return; + } + data = (Event*)next->GetData(); + node = next; + } + Node* newHead = plist->AddBefore(node, ev); + if(newHead){ + plist->SetFirstNode(newHead); + } +} + +void EventFramework::RemoveEvent(Event* ev){ + cbLock(); + list->RemoveItem(ev); + cbUnlock(); +} + +void EventFramework::AddEventListener(Event* ev, EventHandler* hnd, EventDispatchingRoutine* func){ + if(func){ + hnd->Attach(func); + } + ev->Subscribe(hnd); +} + +void EventFramework::RemoveEventListener(Event* ev, EventHandler* hnd){ + ev->Unsubscribe(hnd); +} + +void EventFramework::RemovePendingEvent(Event* ev){ + cbLock(); + queue->RemoveItem(ev); + cbUnlock(); + delete ev; +} + +void EventFramework::PublishEvent(Event* evt, void* args){ + Event* raised = new Event(evt->GetPrio()); + raised->SetData(args); + raised->SetBase(evt); + cbLock(); + AddPendingEvent(raised); + if(nesting){ + cbUnlock(); + return; + } + cbUnlock(); + if(IsPreemptive()){ + Schedule(); + } +} + +void EventFramework::Configure(uint32_t key, uint32_t value){ + ctflags &= ~key; + ctflags |= (key & value); +} + +Event* EventFramework::GetEvent(void){ + return event; +} + +bool EventFramework::IsPreemptive(void){ + if((ctflags & SCHED_KEY) == SCHED_VALUE_PREEMPTIVE) + return true; + return false; +} + +void EventFramework::SaveContext(void){ + cbLock(); + nesting++; + cbUnlock(); +} + +void EventFramework::RestoreContext(void){ + cbLock(); + if(nesting > 1){ + cbUnlock(); + return; + } + nesting = 0; + cbUnlock(); + if(cbEnableInterrupts){ + cbEnableInterrupts(); + } + Schedule(); +} + +void EventFramework::Schedule(void){ + volatile static uint16_t curr = 0xFFFF; + volatile uint16_t prev; + volatile uint16_t next; + + for(;;){ + cbLock(); + // if no pending events, then quit + if(!queue){ + cbUnlock(); + return; + } + // extract most priority event + Node* firstNode = queue->GetFirstNode(); + Event* rdyEvent = (Event*)firstNode->GetData(); + next = rdyEvent->GetPrio(); + + // if worst then exit + if(next >= currPrio){ + cbUnlock(); + return; + } + + // else update context + prev = curr; + curr = next; + currPrio = curr; + + // extract event from queue, if no more events, the free queue + queue->Remove(firstNode); + if(!queue->GetFirstNode()){ + delete queue; + queue = NULL; + } + + // get event + Node* nodeHnd = rdyEvent->GetBase()->GetList()->GetFirstNode(); + while(nodeHnd){ + EventHandler* hnd = (EventHandler*)nodeHnd->GetData(); + cbUnlock(); + hnd->Execute(rdyEvent->GetData()); + cbLock(); + nodeHnd = nodeHnd->GetNext(); + } + delete rdyEvent; + curr = prev; + currPrio = curr; + cbUnlock(); + } +// // extract most priority event +// Node* firstNode = queue->GetFirstNode(); +// this->event = (Event*)firstNode->GetData(); +// queue->Remove(firstNode); +// // if no more events, then free queue +// if(!queue->GetFirstNode()){ +// delete queue; +// queue = NULL; +// } +// // get event +// Node* nodeHnd = this->event->GetBase()->GetList()->GetFirstNode(); +// while(nodeHnd){ +// EventHandler* hnd = (EventHandler*)nodeHnd->GetData(); +// hnd->Execute(); +// nodeHnd = nodeHnd->GetNext(); +// } + +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EventFramework.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,226 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _EVENT_FRAMEWORK_H_ +#define _EVENT_FRAMEWORK_H_ + +#include "../Types/Types.h" +#include "../Event/Event.h" +#include "../EventHandler/EventHandler.h" +#include "../List/List.h" + +/** EventFramework class + * + * EventFramework class allows the creation of an event-driven infrastructure in which small "threads" (EventHandler + * instances) can handle events in a multithreaded execution context. As other traditional RTOSes, the EventFramework + * can be configured to act as a cooperative or a fully-preemptive kernel with fixed-priority scheduling. + * Furthermore, this kernel matches run-to-completion semantics, and hence a single-stack configuration + * is enough to keep running this multithreaded execution environment. As all running tasks shares processor's + * stack, a huge quantity of RAM is saved in contrast with traditional RTOSes. + * This Framework has been designed to be extremely simple, but still powerful. Let's try it. Here comes an + * example of use: + * + * @code + * // Configuring and starting an EventFramework-based application formed by two threads who interchanges two events. + * #include "mbed.h" + * #include "EventFramework.h" + * + * // framework creation with fully-preemptive scheduling mechanism. + * EventFramework kernel(EventFramework::SCHED_VALUE_PREEMPTIVE); + * + * // Events creation with priorities 0(max) and 65535(min). + * Event ev1(65535); + * Event ev2(0); + * + * // EventHandlers creation with priorities 0(max) and 65535(min) + * EventHandler eh1(0); + * EventHandler eh2(65535); + * + * // declaration of event dispatching functions that will be attached to previous EventHandlers + * EventDispatchingRoutine ev1_handle_func; + * EventDispatchingRoutine ev2_handle_func; + * + * int main() { + * // events must be registered into the framework + * kernel.AddEvent(&ev1); + * kernel.AddEvent(&ev1); + * + * // handle [eh1] will process [ev1] events through [ev1_handle_func] routine. So it must attach that routine + * // handle [eh2] will process [ev2] events through [ev2_handle_func] routine. So it must attach that routine + * eh1.Attach(&ev1_handle_func); + * eh2.Attach(&ev2_handle_func); + * + * // handlers are registered into the kernel to listen to specific events. [eh1] listens to [ev1], [eh2] listens to [ev2]. + * kernel.AddEventListener(&ev1, &eh1); + * kernel.AddEventListener(&ev1, &eh2); + * + * // application starts. In this case task [eh1] is executed through the interface EventHandler::Execute. + * eh1.Execute(); + * + * // the event-driven kernel starts its operation. + * while(1) { + * kernel.Schedule(); + * } + * } + * + * // user's implementation of the event handlers + * uint32_t ev1_handle_func(void* me, void* args){ + * // add code here to process ev1 events and (optionally) publish ev2 events. + * // howto: publishing an ev2 event and attaching the value of a variable [time]. + * uint32_t time = 1000; + * kernel.PublishEvent(&ev2, (void*)time); + * } + * + * uint32_t ev2_handle_func(void* me, void* args){ + * // add code here to process ev2 events and (optionally) publish ev1 events. + * // howto: extracting the value of [time] variable attached to [ev1] event + * uint32_t time = (uint32_t)args; + * + * // howto: publishing an ev1 event without data attached. + * kernel.PublishEvent(&ev1, 0); + * } + * @endcode + * + */ + +class EventFramework{ + public: + /** Creates an EventFramework instance. This constructor accepts up to four arguments: + * + * @param schpol is the selected scheduling policy: EventFramework::SCHED_VALUE_COOPERATIVE or EventFramework::SCHED_VALUE_PREEMPTIVE + * @param cbEI is a (void (*)(void)) callback to enable all the interrupts of the processor. + * @param lock is a (void (*)(void)) callback to enter into a critial region. + * @param unlock is a (void (*)(void)) callback to exit from a critial region. + */ + EventFramework(uint32_t schpol, void (*cbEI)(void)=NULL, void (*lock)(void)=NULL, void (*unlock)(void)=NULL); + + /** Default destructor + * + * Deallocates reserved memory for an EventFramework instance. + */ + ~EventFramework(); + + /** Registers a new Event into the framework. + * + * @param ev Event to be registered into the framework + */ + void AddEvent(Event* ev); + + /** Unregisters an existing Event from the framework. + * + * @param ev Event to be unregistered from the framework + */ + void RemoveEvent(Event* ev); + + /** Registers a new EventHandler to listen Event notifications. It can accept up to three arguments: + * + * @param ev Event instance to listen to. + * @param hnd EventHandler who will listen to [ev] events. + * @param func Event dispatching function to attach to [hnd] for [ev] events processing. + */ + void AddEventListener(Event* ev, EventHandler* hnd, EventDispatchingRoutine* func=NULL); + + /** Unregister an existing EventHandler listener from the framework. + * + * @param ev Event instance to which [hnd] is listening to. + * @param hnd EventHandler to remove from the [ev] listener list. + */ + void RemoveEventListener(Event* ev, EventHandler* hnd); + + /** Publish an Event with (optionally) attached data. + * + * @param evt Event published to be processed. + * @param args (optional) attached data reference. If not used then set 0. + */ + void PublishEvent(Event* evt, void* args); + + /** Configure specific features of the EventFramework. + * + * @param key feature key to update + * @param value feature value to setup + */ + void Configure(uint32_t key, uint32_t value); + + /** Gets a reference of the Event in process. + * + * @returns Event reference of the Event in process. + */ + Event* GetEvent(void); + + /** Saves actual context on ISR entry. It allows ISR nesting in fully-preemptive scheduling. + * Must be the first instruction on ISR entry. + * Example: + * @code + * void ISR_Handler(void){ + * kernel.SaveContext(); + * // add here your isr code. + * .... + * kernel.RestoreContext(); + * } + * @endcode + * + */ + void SaveContext(void); + + /** Restores previous context on ISR exit. It must be the last instruction before ISR exit. + * Example: + * @code + * void ISR_Handler(void){ + * kernel.SaveContext(); + * // add here your isr code. + * .... + * kernel.RestoreContext(); + * } + * @endcode + * + */ + void RestoreContext(void); + + /** Executes the EventFramework according with the selected scheduling policy. + * + */ + void Schedule(void); + + /// Feature key to select the SCHEDULING execution model + const static uint32_t SCHED_KEY = 0x00000001; + /// Feature value to setup the SCHEDULING model as COOPERATIVE + const static uint32_t SCHED_VALUE_COOPERATIVE = 0; + /// Feature value to setup the SCHEDULING model as PREEMPTIVE + const static uint32_t SCHED_VALUE_PREEMPTIVE = 1; + + private: + bool IsPreemptive(void); + void AddEventToList(Event* ev, List* list); + void AddPendingEvent(Event* ev); + void RemovePendingEvent(Event* ev); + uint8_t nesting; + uint16_t currPrio; + void (*cbEnableInterrupts)(void); + void (*cbLock)(void); + void (*cbUnlock)(void); + List* list; + List* queue; + Event* event; + uint32_t ctflags; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EventHandler/EventHandler.cpp Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,49 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "EventHandler.h" + +EventHandler::EventHandler(uint16_t prio, EventDispatchingRoutine* func, void* data){ + this->func = func; + this->prio = prio; + this->data = data; +} + +EventHandler::~EventHandler(void){ + this->func = NULL; + this->prio = (uint16_t)-1; + this->data = NULL; +} + +uint16_t EventHandler::GetPrio(void){ + return prio; +} + +uint32_t EventHandler::Execute(void* args){ + return func(data, args); +} + +void EventHandler::Attach(EventDispatchingRoutine* funct){ + if(funct){ + this->func = funct; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EventHandler/EventHandler.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,75 @@ +/* mbed EventFramework Library + * Copyright (c) 2012-2016 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _EVENTHANDLER_H_ +#define _EVENTHANDLER_H_ + +#include "../Types/Types.h" + +/** EventHandler class + * + * EventHandler instances are the EventFramework entities which will process published + * events. Each handler has a fixed priority in the range: 0(max) to 65535(min) that the + * scheduler will use to fire its EventDispatchingRoutine when the event they are listening + * has been published. * Each EventHandler can listen to several events, through one or + * various EventDispatchingRoutines. + * + */ +class EventHandler{ + public: + /** Creates an EventHandler with up to two arguments: the event dispatching function + * and a fixed priority + * + * @param func Dispatching routine to be invoked to process a published event. + * @param data event handler attached data object reference + * @param prio EventHandler priority in the range: 0[max] - 65535[min]. + */ + EventHandler(uint16_t prio, EventDispatchingRoutine* func=NULL, void* data=NULL); + + ~EventHandler(); + + /** Gets the EventHandler priority. + * + * @returns EventHandler priority + */ + uint16_t GetPrio(); + + /** Executes its dispatching function to process a published event. + * + * @param args data reference to be notified about the event processing. + * @returns Error code in uint32_t format or 0 if success. + */ + uint32_t Execute(void * args); + + /** Attaches a dispatching function to this handler, if NULL is passed, then has no effect. + * + * @param func Dispatching function to be invoked for event processing. + */ + void Attach(EventDispatchingRoutine* func); + + protected: + uint32_t(*func)(void*, void*); + uint16_t prio; + void* data; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/List/List.cpp Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,102 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "List.h" + +List::List(void* item){ + head = new Node(item); +} + +List::~List(){ + RemoveAll(); + head = NULL; +} + +Node* List::AddBefore(Node* node, void* item){ + Node* me = new Node(item); + Node* prev = node->GetPrev(); + node->SetPrev(me); + me->SetNext(node); + if(prev){ + me->SetPrev(prev); + prev->SetNext(me); + return 0; + } + return me; +} + +void List::AddAfter(Node* node, void* item){ + Node* me = new Node(item); + Node* next = node->GetNext(); + node->SetNext(me); + me->SetPrev(node); + if(next){ + me->SetNext(next); + next->SetPrev(me); + } +} + +void List::Remove(Node* node){ + Node* prev = node->GetPrev(); + Node* next = node->GetNext(); + if(prev){ + prev->SetNext(next); + } + else{ + head = next; + } + if(next){ + next->SetPrev(prev); + } + delete node; +} + +void List::RemoveItem(void* item){ + Node* cursor = head; + while(cursor){ + void* data = cursor->GetData(); + if(data == item){ + Remove(cursor); + return; + } + cursor = cursor->GetNext(); + } +} + +void List::RemoveAll(void){ + Node* cursor = head; + while(cursor){ + Node* toRemove = cursor; + cursor = cursor->GetNext(); + delete toRemove; + } +} + +Node* List::GetFirstNode(void){ + return head; +} + +void List::SetFirstNode(Node* node){ + head = node; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/List/List.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,97 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _LIST_H_ +#define _LIST_H_ + +#include "../Node/Node.h" + +/** List class + * + * List objects, can manage dual linked lists of nodes. They allow the insertion, + * removal of nodes at different points of the list. It is a utiliy class for the + * framework to manage Event and EventHandler queues. + * + */ +class List{ + public: + + /** Creates a new List with a first node, in which is attached a new data + * item. + * + * @param item data object to attach to the first node. + */ + List(void* item); + + ~List(); + + /** Adds a new node with a new data item, after a specified node + * already present in the list. + * + * @param node exisiting node in the list, previous to the new one to create. + * @param item data reference to attach + */ + void AddAfter(Node* node, void* item); + + /** Adds a new node with a new data item, before a specified node + * already present in the list. + * + * @param node exisiting node in the list, next to the new one to create. + * @param item data object to attach + * @returns 0 if the first node in the list is unchange, or a node reference + * pointing to the new first node in the list. + */ + Node* AddBefore(Node* node, void* item); + + /** Removes a specified node from the list. + * + * @param node exisiting node in the list, to be removed. + */ + void Remove(Node* node); + + /** Removes a specified item in one or several nodes in the list. + * + * @param item attached data object reference to remove from the list. + */ + void RemoveItem(void* item); + + /** Removes all nodes of the list. Then frees memory allocated for the list. + * + */ + void RemoveAll(void); + + /** Gets a reference to the first node in the list. + * + * @returns a reference to the first node in the list. + */ + Node* GetFirstNode(void); + + /** Sets the first node of the list with a node reference + * + * @param node node reference to set as first node of the list. + */ + void SetFirstNode(Node* node); + private: + Node* head; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Node/Node.cpp Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,68 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "Node.h" + +Node::Node(){ + prev = NULL; + next = NULL; + data = NULL; + } + +Node::Node(void* item){ + prev = NULL; + next = NULL; + data = item; +} + +Node::~Node(void){ + prev = NULL; + next = NULL; + data = NULL; +} + +void Node::SetNext(Node* node){ + next = node; +}; + +void Node::SetPrev(Node* node){ + prev = node; +}; + +Node* Node::GetNext(void){ + return next; +}; + +Node* Node::GetPrev(void){ + return prev; +}; + +void* Node::GetData(void){ + return data; +} + +void Node::SetData(void* item){ + data = item; +} + + + \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Node/Node.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,88 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _NODE_H_ +#define _NODE_H_ + +#include "../Types/Types.h" + +/** Node class + * + * Node objects are elements contained in a List, and linked to the previous and + * next one. A Node can contain attached data as and object reference. It's a + * utility class in the Framework to create Queues. + * + */ +class Node{ + public: + + /** Creates a Node with a specified item attached. + * + * @param item data object reference to attach to this Node. + */ + Node(void* item); + Node(); + ~Node(); + + /** Sets the reference to the next Node in the list. + * + * @param node node reference to the next node. + */ + void SetNext(Node* node); + + /** Sets the reference to the previous Node in the list. + * + * @param node node reference to the previous node. + */ + void SetPrev(Node* node); + + /** Gets the reference to the next Node in the list. + * + * @returns node reference to the next node. + */ + Node* GetNext(void); + + /** Gets the reference to the previous Node in the list. + * + * @returns node reference to the previous node. + */ + Node* GetPrev(void); + + /** Sets the attached data object item in the Node + * + * @param item data object reference to attach to this Node. + */ + void SetData(void* item); + + /** Gets the reference to the attached data object + * + * @returns attached data object reference. + */ + void* GetData(void); + + private: + Node* prev; + Node* next; + void* data; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Types/Types.h Mon Oct 01 10:38:45 2012 +0000 @@ -0,0 +1,49 @@ +/* mbed EventFramework Library + * Copyright (c) 2012 raulMrello + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +/** Types required by the EventFramework + * + * These header file includes all common definitions required by the EventFramework + * library. + * + */ +#include <stdint.h> +#ifndef NULL +#define NULL 0 +#endif + +/** EventDispatchingRoutine typedef + * + * Event dispatching routines must follow this typedef. + * + * @param me attached data object to be notified about the event processing action. + * @param args event's attached data. + * + * @returns error code in uint32_t format, or 0 if success. + */ +typedef uint32_t EventDispatchingRoutine(void* me, void* args); + + +#endif