Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Files at this revision

API Documentation at this revision

Comitter:
AndrewL
Date:
Mon Jan 31 03:39:39 2011 +0000
Parent:
3:6cb5413f143f
Child:
5:6eef5e47e154
Commit message:
Submission

Changed in this revision

mbos.cpp Show annotated file Show diff for this revision Revisions of this file
mbos.h Show annotated file Show diff for this revision Revisions of this file
--- a/mbos.cpp	Sun Dec 05 13:36:15 2010 +0000
+++ b/mbos.cpp	Mon Jan 31 03:39:39 2011 +0000
@@ -15,7 +15,6 @@
  */
 #include "mbos.h" 
 #include "mbed.h"
-//#include <stdlib.h>
 
 #define MAX_PRIO                    99                  // maximum priority
 #define READY                       MAX_PRIO + 1        // always > MAX_PRIO
@@ -103,7 +102,6 @@
     _numresources = nresources;
     _tasks =  _tasklist[0];
 }
-
 // Create Tasks Function  --------------------------------------------------------------
 void mbos::CreateTask(uint id, uint priority, uint stacksz, void (*fun)(void))
 {
@@ -112,7 +110,7 @@
     // check bounds 
     if(id >= _numtasks || id < 1) error("mbos::CreateTask - %i is an invalid task id\n", id); 
     if(priority > MAX_PRIO) error("mbos::CreateTask - %i is an invalid priority for Task %i\n", priority, id);
-    if(stacksz < MIN_STACKSZ) error("mbos::CreateTask - %i words is too small a stack for Task %i\n", stacksz, id);
+    if(stacksz < MIN_STACKSZ) stacksz = MIN_STACKSZ;
         
     // fill tcb 
     if(_tasks[id].id == 0) _tasks[id].id = id;
@@ -125,7 +123,6 @@
     _tasks[id].stacklimit = stackbase;
     _tasks[id].stack = _initstack(stackbase + stacksz, fun);
 }
-
 // Start OS function  -------------------------------------------------------------------
 void mbos::Start(uint stacksize)
 {
@@ -137,7 +134,7 @@
     _tasks[0].eventlist = 0;
     _tasks[0].eventmask = 0;
     if(mbosIdleTask){
-        if(stacksize < MIN_STACKSZ) error("mbos::Start - %i words is too small for idle task stack\n", stacksize);
+        if(stacksize < MIN_STACKSZ) stacksize = MIN_STACKSZ;
         stackbase = (uint*)malloc(stacksize * 4);
         if(stackbase == 0) error("mbos::Start - Insufficient memory to create idle task\n");    
         _tasks[0].stacklimit = stackbase;
@@ -156,7 +153,6 @@
     
     while(1);                            
 }
-
 // OS Tick Function   -------------------------------------------------------------------
 void SysTick_Handler(void)
 {
@@ -200,7 +196,6 @@
 { 
     return _tasklist[0]->priostate - READY; 
 }
- 
 // Wait Event Function  ------------------------------------------------------------------
 void mbos::WaitEvent(uint event)
 {   
@@ -260,7 +255,22 @@
     _timers[id].timer = time;
     _timers[id].reload = reload;
     __enable_irq();
-}    
+} 
+// Redirect Timer Function -----------------------------------------------------------------
+void mbos::RedirectTimer(uint id, uint task, uint event)
+{
+    // check bounds 
+    if(id >= _numtimers) error("mbos::RedirectTimer - %i is an invalid timer id\n", id); 
+    if(task < 1|| task >= _numtasks) error("mbos::RedirectTimer - %i is an invalid task id for Timer %i\n", task, id); 
+    if(event == 0) error("mbos::RedirectTimer - Can't use null event for Timer %i\n", id); 
+    
+    __disable_irq();
+    if( _timers[id].timer == 0){
+        _timers[id].task = task;
+        _timers[id].event = event;
+    }
+    __enable_irq();
+}
 // Clear Timer Function  -------------------------------------------------------------------
 void mbos::ClearTimer(uint id)
 {
@@ -288,7 +298,7 @@
 {
     // check bounds
     if(id >= _numresources) error("mbos::LockResource - %i is an invalid resource id\n", id);
-	if(_tasklist[0]->id == 0 ||_resources[id].lock != 0) return _resources[id].lock;
+    if(_tasklist[0]->id == 0 ||_resources[id].lock != 0) return _resources[id].lock;
     
     __disable_irq();
     _resources[id].lock = _tasklist[0]->id;
@@ -309,7 +319,7 @@
 {
     // check bounds
     if(id >= _numresources) error("mbos::FreeResource - %i is an invalid resource id\n", id);
-	if(_tasklist[0]->id == 0 || _tasklist[0]->id != _resources[id].lock) return _resources[id].lock;
+    if(_tasklist[0]->id == 0 || _tasklist[0]->id != _resources[id].lock) return _resources[id].lock;
     
     __disable_irq();
     _resources[id].lock = 0;
@@ -317,8 +327,6 @@
     __enable_irq();
     return 0;
 }
-
-
 // Initialise stack function  -----------------------------------------------------------
 uint* mbos::_initstack(uint *stack, void (*fun)())
 {
@@ -332,10 +340,8 @@
     stack -= 8;                                // R11, R10, R9, R8, R7, R6, R5, R4
     return stack;    
 } 
+// Stack Error function  ----------------------------------------------------------------
 void _stackerror(uint task)
 {
     error("Stack Overflow on Task %i\n", task);
 }
-
-
-
--- a/mbos.h	Sun Dec 05 13:36:15 2010 +0000
+++ b/mbos.h	Mon Jan 31 03:39:39 2011 +0000
@@ -43,52 +43,59 @@
  *
  * A typical simple example with two tasks, and one timer, might look like this:
  * @code
- * #include "mbed.h"
+ * // mbos Blinky demonstration.
+ * // Task 1 toggles LED1 every second, under control of a timer. It then posts an event to
+ * // task 2 which flashed LED2 briefly.
+ * #include "mbed.h"                    
  * #include "mbos.h"
  *
- * #define TASK1_ID                1        // defines to make the code more readable
- * #define TASK1_PRIO            50
- * #define TASK1_STACK_SZ        32
- * #define TASK2_ID                2
- * #define TASK2_PRIO            60
- * #define TASK2_STACK_SZ        32
- * #define TIMER0_ID            0
- * #define TIMER0_PERIOD        1000
- * #define TIMER0_EVENT            1
- * #define T1_TO_T2_EVENT        2
+ * #define TASK1_ID                1       // Id for task 1 (idle task is 0)
+ * #define TASK1_PRIO              50      // priority for task 1
+ * #define TASK1_STACK_SZ          32      // stack size for task 1 in words 
+ * #define TASK2_ID                2       // Id for task 2 
+ * #define TASK2_PRIO              60      // priority for task 2
+ * #define TASK2_STACK_SZ          32      // stack size for task 2 in words 
+ * #define TIMER0_ID               0       // Id for timer 0
+ * #define TIMER0_PERIOD           1000    // Time period in milliseconds
+ * #define TIMER0_EVENT            1       // Event flag (1 << 0)
+ * #define T1_TO_T2_EVENT          2       // Event flag (1 << 1)
  *
- * void task1(void);                    // task function prototypes
+ * void task1(void);                       // task function prototypes
  * void task2(void);
  *
  * DigitalOut led1(LED1);
  * DigitalOut led2(LED2);
- * mbos os(2, 1);                        // 2 tasks, 1 timer
+ * mbos os(2, 1);                          // Instantiate mbos with 2 tasks & 1 timer    
  *
  * int main(void)
  * {
+ *     // Configure tasks and timers
  *     os.CreateTask(TASK1_ID, TASK1_PRIO, TASK1_STACK_SZ, task1);
  *     os.CreateTask(TASK2_ID, TASK2_PRIO, TASK2_STACK_SZ, task2);
  *     os.CreateTimer(TIMER0_ID, TIMER0_EVENT, TASK1_ID);
+ *     // Start mbos
  *     os.Start();
- *     // never get here!
+ *     // never  return!
  * }
+ *
  * void task1(void)
  * {
  *     os.SetTimer(TIMER0_ID, TIMER0_PERIOD, TIMER0_PERIOD);
  *     while(1){
- *             os.WaitEvent(TIMER0_EVENT);
- *             led1 = !led1;
- *             os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
- *       }
+ *         os.WaitEvent(TIMER0_EVENT);
+ *         led1 = !led1;
+ *         os.SetEvent(T1_TO_T2_EVENT, TASK2_ID);
+ *     }
  * }
+ *
  * void task2(void)
  * {
- *         while(1){
- *             os.WaitEvent(T1_TO_T2_EVENT);
- *             led2 = 1;
- *             wait_ms(100);
- *             led2 = 0;
- *         }
+ *     while(1){
+ *         os.WaitEvent(T1_TO_T2_EVENT);
+ *         led2 = 1;
+ *         wait_ms(100);
+ *         led2 = 0;
+ *     }
  * }
  * @endcode
  */
@@ -110,7 +117,7 @@
      * @param idlestacksize Size in words (>= 32) of the user-written idle task if present. 
      * @returns Never returns
      */
-    void Start(uint idlestacksize = 0);
+    void Start(uint idlestacksize = 32);
 
     /** Create an mbos task. Allocates and initialises data structures for the task.
      *
@@ -183,6 +190,16 @@
      * @param reload The optional time to reload into the timer when it times out.
      */
     void SetTimer(uint timerid, uint time, uint reload = 0);
+    
+    /** Redirects an mbos timer. Changes the task and event associated with a timer. If the timer
+     * is running, the fun ction has no effect.
+     *
+     * @param timerid The ID of the timer.
+     * @param taskid The ID of the task to which the timer will post events. May not be 
+     * the idle task.
+     * @param event The event flag(s) that the timer should post on timeout. May not be NULL.
+     */
+     void RedirectTimer(uint timerid, uint taskid, uint event); 
 
     /** Stops and clears an mbos timer.
      *