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.

Dependents:   sensors_KL46Z_xmn

Files at this revision

API Documentation at this revision

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

Event/Event.cpp Show annotated file Show diff for this revision Revisions of this file
Event/Event.h Show annotated file Show diff for this revision Revisions of this file
EventFramework.cpp Show annotated file Show diff for this revision Revisions of this file
EventFramework.h Show annotated file Show diff for this revision Revisions of this file
EventHandler/EventHandler.cpp Show annotated file Show diff for this revision Revisions of this file
EventHandler/EventHandler.h Show annotated file Show diff for this revision Revisions of this file
List/List.cpp Show annotated file Show diff for this revision Revisions of this file
List/List.h Show annotated file Show diff for this revision Revisions of this file
Node/Node.cpp Show annotated file Show diff for this revision Revisions of this file
Node/Node.h Show annotated file Show diff for this revision Revisions of this file
Types/Types.h Show annotated file Show diff for this revision Revisions of this file
--- /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