Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Mon Jan 09 02:38:07 2012 +0000
Revision:
5:6eef5e47e154
Parent:
4:e740e08cbea9
Child:
6:cf660b28b2a4
Fixed minor error which caused problems when a timer posts an event to a task that is not waiting for it

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndrewL 0:1dafafe7d505 1 /***********************************************************************************
AndrewL 0:1dafafe7d505 2 * m b o s R T O S F O R m b e d (ARM CORTEX M3)
AndrewL 0:1dafafe7d505 3 *
AndrewL 0:1dafafe7d505 4 * Copyright (c) 2010 - 2011 Andrew Levido
AndrewL 0:1dafafe7d505 5 *
AndrewL 0:1dafafe7d505 6 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
AndrewL 0:1dafafe7d505 7 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
AndrewL 0:1dafafe7d505 8 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
AndrewL 0:1dafafe7d505 9 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
AndrewL 0:1dafafe7d505 10 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
AndrewL 0:1dafafe7d505 11 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
AndrewL 0:1dafafe7d505 12 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
AndrewL 0:1dafafe7d505 13 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
AndrewL 0:1dafafe7d505 14 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AndrewL 0:1dafafe7d505 15 */
AndrewL 0:1dafafe7d505 16 #include "mbos.h"
AndrewL 0:1dafafe7d505 17 #include "mbed.h"
AndrewL 0:1dafafe7d505 18
AndrewL 0:1dafafe7d505 19 #define MAX_PRIO 99 // maximum priority
AndrewL 0:1dafafe7d505 20 #define READY MAX_PRIO + 1 // always > MAX_PRIO
AndrewL 0:1dafafe7d505 21 #define WAITING 0 // aways 0
AndrewL 0:1dafafe7d505 22 #define DEFAULT_IDLE_STACK_SZ 32 // in words
AndrewL 0:1dafafe7d505 23 #define MAX_TASKS 99 // tasks 0.. 99 including idle
AndrewL 0:1dafafe7d505 24 #define MAX_TIMERS 99 // timers 0..99
AndrewL 0:1dafafe7d505 25 #define MAX_RESOURCES 99 // resources 0..99
AndrewL 0:1dafafe7d505 26 #define MIN_STACKSZ 32 // enough to run an empty function
AndrewL 0:1dafafe7d505 27 #define TICKS_PER_SECOND 1000 // 1ms Ticks
AndrewL 0:1dafafe7d505 28
AndrewL 0:1dafafe7d505 29 typedef struct _tcb{ // task control block
AndrewL 0:1dafafe7d505 30 uint id;
AndrewL 0:1dafafe7d505 31 uint *stack;
AndrewL 0:1dafafe7d505 32 uint priostate;
AndrewL 0:1dafafe7d505 33 uint eventlist;
AndrewL 0:1dafafe7d505 34 uint eventmask;
AndrewL 0:1dafafe7d505 35 uint *stacklimit;
AndrewL 0:1dafafe7d505 36 }_tcb_t;
AndrewL 0:1dafafe7d505 37
AndrewL 0:1dafafe7d505 38 typedef struct _timer{ // timer cotrol block
AndrewL 0:1dafafe7d505 39 uint timer;
AndrewL 0:1dafafe7d505 40 uint reload;
AndrewL 0:1dafafe7d505 41 uint event;
AndrewL 0:1dafafe7d505 42 uint task;
AndrewL 0:1dafafe7d505 43 }_timer_t;
AndrewL 0:1dafafe7d505 44
AndrewL 0:1dafafe7d505 45 typedef struct _rcb{ // resource control block
AndrewL 0:1dafafe7d505 46 uint lock;
AndrewL 0:1dafafe7d505 47 uint priority;
AndrewL 0:1dafafe7d505 48 uint taskprio;
AndrewL 0:1dafafe7d505 49 }_resource_t;
AndrewL 0:1dafafe7d505 50
AndrewL 0:1dafafe7d505 51 extern "C" void _startos(void); // Assembly routine to start the scheduler
AndrewL 0:1dafafe7d505 52 extern "C" void _swap(void); // Assembly routine to set PendSV exception
AndrewL 0:1dafafe7d505 53 extern "C" void SysTick_Handler(void); // Override weak declaration in startup file
AndrewL 0:1dafafe7d505 54 extern "C" void _stackerror(uint task); // Stack error function called by assembler
AndrewL 0:1dafafe7d505 55
AndrewL 0:1dafafe7d505 56 extern void __attribute__((__weak__)) mbosIdleTask(void); // Allow user to write their own idle task
AndrewL 0:1dafafe7d505 57
AndrewL 0:1dafafe7d505 58 // Static Variables
AndrewL 0:1dafafe7d505 59 uint _hardstacklimit; // stack limit
AndrewL 0:1dafafe7d505 60 _tcb_t **_tasklist; // pointer to task list
AndrewL 0:1dafafe7d505 61 _tcb_t *_tasks; // pointer to task control block 0
AndrewL 0:1dafafe7d505 62 _timer_t *_timers; // pointer to timer control block 0
AndrewL 0:1dafafe7d505 63 _resource_t *_resources; // pointer to resource control block 0
AndrewL 0:1dafafe7d505 64 uint _numtasks; // number of tasks (including idle)
AndrewL 0:1dafafe7d505 65 uint _numtimers; // number of timers
AndrewL 0:1dafafe7d505 66 uint _numresources; // number of resources
AndrewL 0:1dafafe7d505 67 uint _tasklistsize; // task list length in bytes
AndrewL 0:1dafafe7d505 68
AndrewL 0:1dafafe7d505 69 // Default Idle Task -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 70 void _idletask(void) { while(1); } // Default idle task
AndrewL 0:1dafafe7d505 71
AndrewL 0:1dafafe7d505 72 // Constructor -------------------------------------------------------------------------
AndrewL 0:1dafafe7d505 73 mbos::mbos(uint ntasks, uint ntimers, uint nresources)
AndrewL 0:1dafafe7d505 74 {
AndrewL 0:1dafafe7d505 75 uint i;
AndrewL 0:1dafafe7d505 76
AndrewL 0:1dafafe7d505 77 ntasks += 1;
AndrewL 0:1dafafe7d505 78 // Create the tcblist, zero initialised
AndrewL 0:1dafafe7d505 79 if(ntasks > MAX_TASKS || ntasks < 1) error("mbos::mbos - %i is an invalid number of tasks\n", ntasks);
AndrewL 0:1dafafe7d505 80 _tasklist = (_tcb_t**)calloc(sizeof(_tcb_t*), ntasks);
AndrewL 0:1dafafe7d505 81 if(_tasklist == 0) error("mbos::mbos - Insufficient memory to create Tasklist\n");
AndrewL 0:1dafafe7d505 82
AndrewL 0:1dafafe7d505 83 // Create the tcbs
AndrewL 0:1dafafe7d505 84 _tasklist[0] = (_tcb_t*)calloc(sizeof(_tcb_t), ntasks);
AndrewL 0:1dafafe7d505 85 if(_tasklist[0] == 0) error("mbos::mbos - Insufficient memory to create TCBs\n");
AndrewL 0:1dafafe7d505 86 for(i = 1; i < ntasks; i++){
AndrewL 0:1dafafe7d505 87 _tasklist[i] = _tasklist[i - 1] + 1;
AndrewL 0:1dafafe7d505 88 }
AndrewL 0:1dafafe7d505 89 // Create the timers and clear them
AndrewL 0:1dafafe7d505 90 if(ntimers > MAX_TIMERS + 1) error("mbos::mbos - %i is an invalid number of Timers\n", ntimers);
AndrewL 0:1dafafe7d505 91 _timers = (_timer_t*)calloc(sizeof(_timer_t), ntimers);
AndrewL 0:1dafafe7d505 92 if(_timers == 0) error("mbos::mbos - Insufficient memory to create Timers");
AndrewL 0:1dafafe7d505 93
AndrewL 0:1dafafe7d505 94 // create the resources & clear them
AndrewL 0:1dafafe7d505 95 if(nresources > MAX_RESOURCES + 1) error("mbos::mbos - %i is an invalid number of Resources\n", nresources);
AndrewL 0:1dafafe7d505 96 _resources = (_resource_t*)calloc(sizeof(_resource_t), nresources);
AndrewL 0:1dafafe7d505 97 if(_resources == 0) error("mbos::mbos - Insufficient memory to create Resources");
AndrewL 0:1dafafe7d505 98 _hardstacklimit = (uint)malloc(1);
AndrewL 0:1dafafe7d505 99 if(_hardstacklimit == 0) error("mbos::mbos - Insufficient memory to create HardStackLimit");
AndrewL 0:1dafafe7d505 100 _numtasks = ntasks;
AndrewL 0:1dafafe7d505 101 _numtimers = ntimers;
AndrewL 0:1dafafe7d505 102 _numresources = nresources;
AndrewL 0:1dafafe7d505 103 _tasks = _tasklist[0];
AndrewL 0:1dafafe7d505 104 }
AndrewL 0:1dafafe7d505 105 // Create Tasks Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 106 void mbos::CreateTask(uint id, uint priority, uint stacksz, void (*fun)(void))
AndrewL 0:1dafafe7d505 107 {
AndrewL 0:1dafafe7d505 108 uint* stackbase;
AndrewL 0:1dafafe7d505 109
AndrewL 0:1dafafe7d505 110 // check bounds
AndrewL 0:1dafafe7d505 111 if(id >= _numtasks || id < 1) error("mbos::CreateTask - %i is an invalid task id\n", id);
AndrewL 0:1dafafe7d505 112 if(priority > MAX_PRIO) error("mbos::CreateTask - %i is an invalid priority for Task %i\n", priority, id);
AndrewL 4:e740e08cbea9 113 if(stacksz < MIN_STACKSZ) stacksz = MIN_STACKSZ;
AndrewL 0:1dafafe7d505 114
AndrewL 0:1dafafe7d505 115 // fill tcb
AndrewL 0:1dafafe7d505 116 if(_tasks[id].id == 0) _tasks[id].id = id;
AndrewL 0:1dafafe7d505 117 else error("mbos::CreateTask - Task %i already created\n", id);
AndrewL 0:1dafafe7d505 118 _tasks[id].priostate = READY + priority;
AndrewL 0:1dafafe7d505 119 _tasks[id].eventlist = 0;
AndrewL 0:1dafafe7d505 120 _tasks[id].eventmask = 0;
AndrewL 0:1dafafe7d505 121 stackbase = (uint*)malloc(stacksz * 4);
AndrewL 0:1dafafe7d505 122 if(stackbase == 0) error("mbos::CreateTask - Insufficient memory to create Task %i\n", id);
AndrewL 0:1dafafe7d505 123 _tasks[id].stacklimit = stackbase;
AndrewL 0:1dafafe7d505 124 _tasks[id].stack = _initstack(stackbase + stacksz, fun);
AndrewL 0:1dafafe7d505 125 }
AndrewL 0:1dafafe7d505 126 // Start OS function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 127 void mbos::Start(uint stacksize)
AndrewL 0:1dafafe7d505 128 {
AndrewL 0:1dafafe7d505 129 uint * stackbase;
AndrewL 0:1dafafe7d505 130
AndrewL 0:1dafafe7d505 131 // Fill idle tcb and initialise idle stack
AndrewL 0:1dafafe7d505 132 _tasks[0].priostate = READY;
AndrewL 0:1dafafe7d505 133 _tasks[0].id = 0;
AndrewL 0:1dafafe7d505 134 _tasks[0].eventlist = 0;
AndrewL 0:1dafafe7d505 135 _tasks[0].eventmask = 0;
AndrewL 0:1dafafe7d505 136 if(mbosIdleTask){
AndrewL 4:e740e08cbea9 137 if(stacksize < MIN_STACKSZ) stacksize = MIN_STACKSZ;
AndrewL 0:1dafafe7d505 138 stackbase = (uint*)malloc(stacksize * 4);
AndrewL 0:1dafafe7d505 139 if(stackbase == 0) error("mbos::Start - Insufficient memory to create idle task\n");
AndrewL 0:1dafafe7d505 140 _tasks[0].stacklimit = stackbase;
AndrewL 0:1dafafe7d505 141 _tasks[0].stack = _initstack(stackbase + stacksize, mbosIdleTask);
AndrewL 0:1dafafe7d505 142 }
AndrewL 0:1dafafe7d505 143 else {
AndrewL 0:1dafafe7d505 144 stackbase = (uint*)malloc(DEFAULT_IDLE_STACK_SZ * 4);
AndrewL 0:1dafafe7d505 145 if(stackbase == 0) error("mbos::Start - Insufficient memory to create idle task\n");
AndrewL 0:1dafafe7d505 146 _tasks[0].stacklimit = stackbase;
AndrewL 0:1dafafe7d505 147 _tasks[0].stack = _initstack(stackbase + DEFAULT_IDLE_STACK_SZ, _idletask);
AndrewL 0:1dafafe7d505 148 }
AndrewL 0:1dafafe7d505 149 _tasklistsize = 4 * (_numtasks - 1);
AndrewL 0:1dafafe7d505 150 SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);
AndrewL 0:1dafafe7d505 151 NVIC_SetPriority(SysTick_IRQn, 0);
AndrewL 0:1dafafe7d505 152 _startos();
AndrewL 0:1dafafe7d505 153
AndrewL 0:1dafafe7d505 154 while(1);
AndrewL 0:1dafafe7d505 155 }
AndrewL 0:1dafafe7d505 156 // OS Tick Function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 157 void SysTick_Handler(void)
AndrewL 0:1dafafe7d505 158 {
AndrewL 0:1dafafe7d505 159 uint i;
AndrewL 0:1dafafe7d505 160
AndrewL 0:1dafafe7d505 161 __disable_irq();
AndrewL 5:6eef5e47e154 162 led3 =1;
AndrewL 0:1dafafe7d505 163 for(i = 0; i < _numtimers; i++){
AndrewL 0:1dafafe7d505 164 if(_timers[i].timer){
AndrewL 0:1dafafe7d505 165 _timers[i].timer--;
AndrewL 0:1dafafe7d505 166 if(_timers[i].timer == 0){
AndrewL 5:6eef5e47e154 167 _timers[i].timer = _timers[i].reload;
AndrewL 5:6eef5e47e154 168 if( _tasks[_timers[i].task].priostate < READY){
AndrewL 5:6eef5e47e154 169 if(_tasks[_timers[i].task].eventmask & _timers[i].event){
AndrewL 5:6eef5e47e154 170 _tasks[_timers[i].task].eventlist |= _timers[i].event;
AndrewL 5:6eef5e47e154 171 _tasks[_timers[i].task].priostate += READY;
AndrewL 5:6eef5e47e154 172 }
AndrewL 5:6eef5e47e154 173 }
AndrewL 0:1dafafe7d505 174 }
AndrewL 0:1dafafe7d505 175 }
AndrewL 0:1dafafe7d505 176 }
AndrewL 0:1dafafe7d505 177 if((__return_address() & 0x08) == 0) { // called from Handler, so swap later
AndrewL 0:1dafafe7d505 178 __enable_irq();
AndrewL 0:1dafafe7d505 179 return;
AndrewL 0:1dafafe7d505 180 }
AndrewL 5:6eef5e47e154 181 led3 = 0;
AndrewL 0:1dafafe7d505 182 _swap();
AndrewL 0:1dafafe7d505 183 __enable_irq();
AndrewL 0:1dafafe7d505 184 }
AndrewL 0:1dafafe7d505 185 // Get Task id Function -----------------------------------------------------------------
AndrewL 0:1dafafe7d505 186 uint mbos::GetTask(void)
AndrewL 0:1dafafe7d505 187 {
AndrewL 0:1dafafe7d505 188 return _tasklist[0]->id;
AndrewL 0:1dafafe7d505 189 }
AndrewL 0:1dafafe7d505 190 // Set Priority Function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 191 void mbos::SetPriority(uint priority)
AndrewL 0:1dafafe7d505 192 {
AndrewL 0:1dafafe7d505 193 if(_tasklist[0]->id == 0) return;
AndrewL 0:1dafafe7d505 194 if(priority > MAX_PRIO) error("mbos::SetPriority - %i is an invalid priority\n", priority);
AndrewL 0:1dafafe7d505 195 _tasklist[0]->priostate = priority + READY;
AndrewL 0:1dafafe7d505 196 }
AndrewL 0:1dafafe7d505 197 // Get Priority Function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 198 uint mbos::GetPriority(void)
AndrewL 0:1dafafe7d505 199 {
AndrewL 0:1dafafe7d505 200 return _tasklist[0]->priostate - READY;
AndrewL 0:1dafafe7d505 201 }
AndrewL 0:1dafafe7d505 202 // Wait Event Function ------------------------------------------------------------------
AndrewL 0:1dafafe7d505 203 void mbos::WaitEvent(uint event)
AndrewL 0:1dafafe7d505 204 {
AndrewL 0:1dafafe7d505 205 if(_tasklist[0]->id == 0) return;
AndrewL 0:1dafafe7d505 206 if(event == 0) return;
AndrewL 0:1dafafe7d505 207 __disable_irq();
AndrewL 0:1dafafe7d505 208 _tasklist[0]->eventlist = 0;
AndrewL 0:1dafafe7d505 209 _tasklist[0]->eventmask = event;
AndrewL 0:1dafafe7d505 210 _tasklist[0]->priostate -= READY;
AndrewL 0:1dafafe7d505 211 _swap();
AndrewL 0:1dafafe7d505 212 __enable_irq();
AndrewL 0:1dafafe7d505 213 }
AndrewL 0:1dafafe7d505 214 // Set Event Function --------------------------------------------------------------------
AndrewL 0:1dafafe7d505 215 void mbos::SetEvent(uint event, uint task)
AndrewL 0:1dafafe7d505 216 {
AndrewL 0:1dafafe7d505 217 // check bounds
AndrewL 0:1dafafe7d505 218 if(task >= _numtasks || (task < 1)) return;
AndrewL 0:1dafafe7d505 219
AndrewL 0:1dafafe7d505 220 __disable_irq();
AndrewL 0:1dafafe7d505 221 if(_tasks[task].eventmask & event){
AndrewL 0:1dafafe7d505 222 _tasks[task].eventlist |= event;
AndrewL 0:1dafafe7d505 223 _tasks[task].priostate += READY;
AndrewL 0:1dafafe7d505 224 }
AndrewL 0:1dafafe7d505 225 else{
AndrewL 0:1dafafe7d505 226 __enable_irq();
AndrewL 0:1dafafe7d505 227 return;
AndrewL 0:1dafafe7d505 228 }
AndrewL 0:1dafafe7d505 229 _swap();
AndrewL 0:1dafafe7d505 230 __enable_irq();
AndrewL 0:1dafafe7d505 231 }
AndrewL 0:1dafafe7d505 232 // Get event Function -----------------------------------------------------------------
AndrewL 0:1dafafe7d505 233 uint mbos::GetEvent(void)
AndrewL 0:1dafafe7d505 234 {
AndrewL 0:1dafafe7d505 235 return _tasklist[0]->eventlist;
AndrewL 0:1dafafe7d505 236 }
AndrewL 0:1dafafe7d505 237 // Create Timer Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 238 void mbos::CreateTimer(uint id, uint task, uint event)
AndrewL 0:1dafafe7d505 239 {
AndrewL 0:1dafafe7d505 240 // check bounds
AndrewL 0:1dafafe7d505 241 if(id >= _numtimers) error("mbos::CreateTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 242 if(task < 1|| task >= _numtasks) error("mbos::CreateTimer - %i is an invalid task id for Timer %i\n", task, id);
AndrewL 0:1dafafe7d505 243 if(event == 0) error("mbos::CreateTimer - Can't use null event for Timer %i\n", id);
AndrewL 0:1dafafe7d505 244
AndrewL 0:1dafafe7d505 245 // fill tcb
AndrewL 0:1dafafe7d505 246 _timers[id].timer = 0;
AndrewL 0:1dafafe7d505 247 _timers[id].reload = 0;
AndrewL 0:1dafafe7d505 248 _timers[id].task = task;
AndrewL 0:1dafafe7d505 249 _timers[id].event = event;
AndrewL 0:1dafafe7d505 250 }
AndrewL 0:1dafafe7d505 251 // Set Timer Function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 252 void mbos::SetTimer(uint id, uint time, uint reload)
AndrewL 0:1dafafe7d505 253 {
AndrewL 0:1dafafe7d505 254 // check bounds
AndrewL 0:1dafafe7d505 255 if(id >= _numtimers) error("mbos::SetTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 256
AndrewL 0:1dafafe7d505 257 __disable_irq();
AndrewL 0:1dafafe7d505 258 _timers[id].timer = time;
AndrewL 0:1dafafe7d505 259 _timers[id].reload = reload;
AndrewL 0:1dafafe7d505 260 __enable_irq();
AndrewL 4:e740e08cbea9 261 }
AndrewL 4:e740e08cbea9 262 // Redirect Timer Function -----------------------------------------------------------------
AndrewL 4:e740e08cbea9 263 void mbos::RedirectTimer(uint id, uint task, uint event)
AndrewL 4:e740e08cbea9 264 {
AndrewL 4:e740e08cbea9 265 // check bounds
AndrewL 4:e740e08cbea9 266 if(id >= _numtimers) error("mbos::RedirectTimer - %i is an invalid timer id\n", id);
AndrewL 4:e740e08cbea9 267 if(task < 1|| task >= _numtasks) error("mbos::RedirectTimer - %i is an invalid task id for Timer %i\n", task, id);
AndrewL 4:e740e08cbea9 268 if(event == 0) error("mbos::RedirectTimer - Can't use null event for Timer %i\n", id);
AndrewL 4:e740e08cbea9 269
AndrewL 4:e740e08cbea9 270 __disable_irq();
AndrewL 4:e740e08cbea9 271 if( _timers[id].timer == 0){
AndrewL 4:e740e08cbea9 272 _timers[id].task = task;
AndrewL 4:e740e08cbea9 273 _timers[id].event = event;
AndrewL 4:e740e08cbea9 274 }
AndrewL 4:e740e08cbea9 275 __enable_irq();
AndrewL 4:e740e08cbea9 276 }
AndrewL 0:1dafafe7d505 277 // Clear Timer Function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 278 void mbos::ClearTimer(uint id)
AndrewL 0:1dafafe7d505 279 {
AndrewL 0:1dafafe7d505 280 // check bounds
AndrewL 0:1dafafe7d505 281 if(id >= _numtimers) error("mbos::ClearTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 282
AndrewL 0:1dafafe7d505 283 __disable_irq();
AndrewL 0:1dafafe7d505 284 _timers[id].timer = 0;
AndrewL 0:1dafafe7d505 285 _timers[id].reload = 0;
AndrewL 0:1dafafe7d505 286 __enable_irq();
AndrewL 0:1dafafe7d505 287 }
AndrewL 0:1dafafe7d505 288 // Create resources Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 289 void mbos::CreateResource(uint id, uint priority)
AndrewL 0:1dafafe7d505 290 {
AndrewL 0:1dafafe7d505 291 // check bounds
AndrewL 0:1dafafe7d505 292 if(id >= _numresources) error("mbos::CreateResource - %i is an invalid resource id\n", id);
AndrewL 0:1dafafe7d505 293 if(priority > MAX_PRIO) error("mbos::CreateResource - %i is an invalid priority for Resource %i\n", priority, id);
AndrewL 0:1dafafe7d505 294
AndrewL 0:1dafafe7d505 295 // fill rcb
AndrewL 0:1dafafe7d505 296 _resources[id].priority = priority;
AndrewL 0:1dafafe7d505 297 _resources[id].lock = 0;
AndrewL 0:1dafafe7d505 298 }
AndrewL 0:1dafafe7d505 299 // Lock Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 300 uint mbos::LockResource(uint id)
AndrewL 0:1dafafe7d505 301 {
AndrewL 0:1dafafe7d505 302 // check bounds
AndrewL 0:1dafafe7d505 303 if(id >= _numresources) error("mbos::LockResource - %i is an invalid resource id\n", id);
AndrewL 4:e740e08cbea9 304 if(_tasklist[0]->id == 0 ||_resources[id].lock != 0) return _resources[id].lock;
AndrewL 0:1dafafe7d505 305
AndrewL 0:1dafafe7d505 306 __disable_irq();
AndrewL 0:1dafafe7d505 307 _resources[id].lock = _tasklist[0]->id;
AndrewL 0:1dafafe7d505 308 _resources[id].taskprio = _tasklist[0]->priostate;
AndrewL 0:1dafafe7d505 309 _tasklist[0]->priostate = _resources[id].priority + READY;
AndrewL 0:1dafafe7d505 310 __enable_irq();
AndrewL 0:1dafafe7d505 311 return 0;
AndrewL 0:1dafafe7d505 312 }
AndrewL 0:1dafafe7d505 313 // Test Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 314 uint mbos::TestResource(uint id)
AndrewL 0:1dafafe7d505 315 {
AndrewL 0:1dafafe7d505 316 // check bounds
AndrewL 0:1dafafe7d505 317 if(id >= _numresources) error("mbos::TestResource - %i is an invalid resource id\n", id);
AndrewL 0:1dafafe7d505 318 return(_resources[id].lock);
AndrewL 0:1dafafe7d505 319 }
AndrewL 0:1dafafe7d505 320 // Free Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 321 uint mbos::FreeResource(uint id)
AndrewL 0:1dafafe7d505 322 {
AndrewL 0:1dafafe7d505 323 // check bounds
AndrewL 0:1dafafe7d505 324 if(id >= _numresources) error("mbos::FreeResource - %i is an invalid resource id\n", id);
AndrewL 4:e740e08cbea9 325 if(_tasklist[0]->id == 0 || _tasklist[0]->id != _resources[id].lock) return _resources[id].lock;
AndrewL 0:1dafafe7d505 326
AndrewL 0:1dafafe7d505 327 __disable_irq();
AndrewL 0:1dafafe7d505 328 _resources[id].lock = 0;
AndrewL 0:1dafafe7d505 329 _tasklist[0]->priostate = _resources[id].taskprio;
AndrewL 0:1dafafe7d505 330 __enable_irq();
AndrewL 0:1dafafe7d505 331 return 0;
AndrewL 0:1dafafe7d505 332 }
AndrewL 0:1dafafe7d505 333 // Initialise stack function -----------------------------------------------------------
AndrewL 0:1dafafe7d505 334 uint* mbos::_initstack(uint *stack, void (*fun)())
AndrewL 0:1dafafe7d505 335 {
AndrewL 0:1dafafe7d505 336 stack -= 3; // leave a spare word
AndrewL 0:1dafafe7d505 337 *stack = 0x01000000; // Initial xPSR (reset value)
AndrewL 0:1dafafe7d505 338 stack--;
AndrewL 0:1dafafe7d505 339 *stack = (uint)fun - 1; // Start address of the task corrected
AndrewL 0:1dafafe7d505 340 stack--;
AndrewL 0:1dafafe7d505 341 *stack = 0; // LR
AndrewL 0:1dafafe7d505 342 stack -= 5; // R12, R3, R2, R1, R0
AndrewL 0:1dafafe7d505 343 stack -= 8; // R11, R10, R9, R8, R7, R6, R5, R4
AndrewL 0:1dafafe7d505 344 return stack;
AndrewL 0:1dafafe7d505 345 }
AndrewL 4:e740e08cbea9 346 // Stack Error function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 347 void _stackerror(uint task)
AndrewL 0:1dafafe7d505 348 {
AndrewL 0:1dafafe7d505 349 error("Stack Overflow on Task %i\n", task);
AndrewL 0:1dafafe7d505 350 }