Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Mon Jan 09 03:11:46 2012 +0000
Revision:
6:cf660b28b2a4
Parent:
5:6eef5e47e154
Fixed error relating to timer events posted to tasks that are not waiting

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 0:1dafafe7d505 162 for(i = 0; i < _numtimers; i++){
AndrewL 0:1dafafe7d505 163 if(_timers[i].timer){
AndrewL 0:1dafafe7d505 164 _timers[i].timer--;
AndrewL 0:1dafafe7d505 165 if(_timers[i].timer == 0){
AndrewL 5:6eef5e47e154 166 _timers[i].timer = _timers[i].reload;
AndrewL 5:6eef5e47e154 167 if( _tasks[_timers[i].task].priostate < READY){
AndrewL 5:6eef5e47e154 168 if(_tasks[_timers[i].task].eventmask & _timers[i].event){
AndrewL 5:6eef5e47e154 169 _tasks[_timers[i].task].eventlist |= _timers[i].event;
AndrewL 5:6eef5e47e154 170 _tasks[_timers[i].task].priostate += READY;
AndrewL 5:6eef5e47e154 171 }
AndrewL 5:6eef5e47e154 172 }
AndrewL 0:1dafafe7d505 173 }
AndrewL 0:1dafafe7d505 174 }
AndrewL 0:1dafafe7d505 175 }
AndrewL 0:1dafafe7d505 176 if((__return_address() & 0x08) == 0) { // called from Handler, so swap later
AndrewL 0:1dafafe7d505 177 __enable_irq();
AndrewL 0:1dafafe7d505 178 return;
AndrewL 0:1dafafe7d505 179 }
AndrewL 0:1dafafe7d505 180 _swap();
AndrewL 0:1dafafe7d505 181 __enable_irq();
AndrewL 0:1dafafe7d505 182 }
AndrewL 0:1dafafe7d505 183 // Get Task id Function -----------------------------------------------------------------
AndrewL 0:1dafafe7d505 184 uint mbos::GetTask(void)
AndrewL 0:1dafafe7d505 185 {
AndrewL 0:1dafafe7d505 186 return _tasklist[0]->id;
AndrewL 0:1dafafe7d505 187 }
AndrewL 0:1dafafe7d505 188 // Set Priority Function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 189 void mbos::SetPriority(uint priority)
AndrewL 0:1dafafe7d505 190 {
AndrewL 0:1dafafe7d505 191 if(_tasklist[0]->id == 0) return;
AndrewL 0:1dafafe7d505 192 if(priority > MAX_PRIO) error("mbos::SetPriority - %i is an invalid priority\n", priority);
AndrewL 0:1dafafe7d505 193 _tasklist[0]->priostate = priority + READY;
AndrewL 0:1dafafe7d505 194 }
AndrewL 0:1dafafe7d505 195 // Get Priority Function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 196 uint mbos::GetPriority(void)
AndrewL 0:1dafafe7d505 197 {
AndrewL 0:1dafafe7d505 198 return _tasklist[0]->priostate - READY;
AndrewL 0:1dafafe7d505 199 }
AndrewL 0:1dafafe7d505 200 // Wait Event Function ------------------------------------------------------------------
AndrewL 0:1dafafe7d505 201 void mbos::WaitEvent(uint event)
AndrewL 0:1dafafe7d505 202 {
AndrewL 0:1dafafe7d505 203 if(_tasklist[0]->id == 0) return;
AndrewL 0:1dafafe7d505 204 if(event == 0) return;
AndrewL 0:1dafafe7d505 205 __disable_irq();
AndrewL 0:1dafafe7d505 206 _tasklist[0]->eventlist = 0;
AndrewL 0:1dafafe7d505 207 _tasklist[0]->eventmask = event;
AndrewL 0:1dafafe7d505 208 _tasklist[0]->priostate -= READY;
AndrewL 0:1dafafe7d505 209 _swap();
AndrewL 0:1dafafe7d505 210 __enable_irq();
AndrewL 0:1dafafe7d505 211 }
AndrewL 0:1dafafe7d505 212 // Set Event Function --------------------------------------------------------------------
AndrewL 0:1dafafe7d505 213 void mbos::SetEvent(uint event, uint task)
AndrewL 0:1dafafe7d505 214 {
AndrewL 0:1dafafe7d505 215 // check bounds
AndrewL 0:1dafafe7d505 216 if(task >= _numtasks || (task < 1)) return;
AndrewL 0:1dafafe7d505 217
AndrewL 0:1dafafe7d505 218 __disable_irq();
AndrewL 0:1dafafe7d505 219 if(_tasks[task].eventmask & event){
AndrewL 0:1dafafe7d505 220 _tasks[task].eventlist |= event;
AndrewL 0:1dafafe7d505 221 _tasks[task].priostate += READY;
AndrewL 0:1dafafe7d505 222 }
AndrewL 0:1dafafe7d505 223 else{
AndrewL 0:1dafafe7d505 224 __enable_irq();
AndrewL 0:1dafafe7d505 225 return;
AndrewL 0:1dafafe7d505 226 }
AndrewL 0:1dafafe7d505 227 _swap();
AndrewL 0:1dafafe7d505 228 __enable_irq();
AndrewL 0:1dafafe7d505 229 }
AndrewL 0:1dafafe7d505 230 // Get event Function -----------------------------------------------------------------
AndrewL 0:1dafafe7d505 231 uint mbos::GetEvent(void)
AndrewL 0:1dafafe7d505 232 {
AndrewL 0:1dafafe7d505 233 return _tasklist[0]->eventlist;
AndrewL 0:1dafafe7d505 234 }
AndrewL 0:1dafafe7d505 235 // Create Timer Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 236 void mbos::CreateTimer(uint id, uint task, uint event)
AndrewL 0:1dafafe7d505 237 {
AndrewL 0:1dafafe7d505 238 // check bounds
AndrewL 0:1dafafe7d505 239 if(id >= _numtimers) error("mbos::CreateTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 240 if(task < 1|| task >= _numtasks) error("mbos::CreateTimer - %i is an invalid task id for Timer %i\n", task, id);
AndrewL 0:1dafafe7d505 241 if(event == 0) error("mbos::CreateTimer - Can't use null event for Timer %i\n", id);
AndrewL 0:1dafafe7d505 242
AndrewL 0:1dafafe7d505 243 // fill tcb
AndrewL 0:1dafafe7d505 244 _timers[id].timer = 0;
AndrewL 0:1dafafe7d505 245 _timers[id].reload = 0;
AndrewL 0:1dafafe7d505 246 _timers[id].task = task;
AndrewL 0:1dafafe7d505 247 _timers[id].event = event;
AndrewL 0:1dafafe7d505 248 }
AndrewL 0:1dafafe7d505 249 // Set Timer Function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 250 void mbos::SetTimer(uint id, uint time, uint reload)
AndrewL 0:1dafafe7d505 251 {
AndrewL 0:1dafafe7d505 252 // check bounds
AndrewL 0:1dafafe7d505 253 if(id >= _numtimers) error("mbos::SetTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 254
AndrewL 0:1dafafe7d505 255 __disable_irq();
AndrewL 0:1dafafe7d505 256 _timers[id].timer = time;
AndrewL 0:1dafafe7d505 257 _timers[id].reload = reload;
AndrewL 0:1dafafe7d505 258 __enable_irq();
AndrewL 4:e740e08cbea9 259 }
AndrewL 4:e740e08cbea9 260 // Redirect Timer Function -----------------------------------------------------------------
AndrewL 4:e740e08cbea9 261 void mbos::RedirectTimer(uint id, uint task, uint event)
AndrewL 4:e740e08cbea9 262 {
AndrewL 4:e740e08cbea9 263 // check bounds
AndrewL 4:e740e08cbea9 264 if(id >= _numtimers) error("mbos::RedirectTimer - %i is an invalid timer id\n", id);
AndrewL 4:e740e08cbea9 265 if(task < 1|| task >= _numtasks) error("mbos::RedirectTimer - %i is an invalid task id for Timer %i\n", task, id);
AndrewL 4:e740e08cbea9 266 if(event == 0) error("mbos::RedirectTimer - Can't use null event for Timer %i\n", id);
AndrewL 4:e740e08cbea9 267
AndrewL 4:e740e08cbea9 268 __disable_irq();
AndrewL 4:e740e08cbea9 269 if( _timers[id].timer == 0){
AndrewL 4:e740e08cbea9 270 _timers[id].task = task;
AndrewL 4:e740e08cbea9 271 _timers[id].event = event;
AndrewL 4:e740e08cbea9 272 }
AndrewL 4:e740e08cbea9 273 __enable_irq();
AndrewL 4:e740e08cbea9 274 }
AndrewL 0:1dafafe7d505 275 // Clear Timer Function -------------------------------------------------------------------
AndrewL 0:1dafafe7d505 276 void mbos::ClearTimer(uint id)
AndrewL 0:1dafafe7d505 277 {
AndrewL 0:1dafafe7d505 278 // check bounds
AndrewL 0:1dafafe7d505 279 if(id >= _numtimers) error("mbos::ClearTimer - %i is an invalid timer id\n", id);
AndrewL 0:1dafafe7d505 280
AndrewL 0:1dafafe7d505 281 __disable_irq();
AndrewL 0:1dafafe7d505 282 _timers[id].timer = 0;
AndrewL 0:1dafafe7d505 283 _timers[id].reload = 0;
AndrewL 0:1dafafe7d505 284 __enable_irq();
AndrewL 0:1dafafe7d505 285 }
AndrewL 0:1dafafe7d505 286 // Create resources Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 287 void mbos::CreateResource(uint id, uint priority)
AndrewL 0:1dafafe7d505 288 {
AndrewL 0:1dafafe7d505 289 // check bounds
AndrewL 0:1dafafe7d505 290 if(id >= _numresources) error("mbos::CreateResource - %i is an invalid resource id\n", id);
AndrewL 0:1dafafe7d505 291 if(priority > MAX_PRIO) error("mbos::CreateResource - %i is an invalid priority for Resource %i\n", priority, id);
AndrewL 0:1dafafe7d505 292
AndrewL 0:1dafafe7d505 293 // fill rcb
AndrewL 0:1dafafe7d505 294 _resources[id].priority = priority;
AndrewL 0:1dafafe7d505 295 _resources[id].lock = 0;
AndrewL 0:1dafafe7d505 296 }
AndrewL 0:1dafafe7d505 297 // Lock Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 298 uint mbos::LockResource(uint id)
AndrewL 0:1dafafe7d505 299 {
AndrewL 0:1dafafe7d505 300 // check bounds
AndrewL 0:1dafafe7d505 301 if(id >= _numresources) error("mbos::LockResource - %i is an invalid resource id\n", id);
AndrewL 4:e740e08cbea9 302 if(_tasklist[0]->id == 0 ||_resources[id].lock != 0) return _resources[id].lock;
AndrewL 0:1dafafe7d505 303
AndrewL 0:1dafafe7d505 304 __disable_irq();
AndrewL 0:1dafafe7d505 305 _resources[id].lock = _tasklist[0]->id;
AndrewL 0:1dafafe7d505 306 _resources[id].taskprio = _tasklist[0]->priostate;
AndrewL 0:1dafafe7d505 307 _tasklist[0]->priostate = _resources[id].priority + READY;
AndrewL 0:1dafafe7d505 308 __enable_irq();
AndrewL 0:1dafafe7d505 309 return 0;
AndrewL 0:1dafafe7d505 310 }
AndrewL 0:1dafafe7d505 311 // Test Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 312 uint mbos::TestResource(uint id)
AndrewL 0:1dafafe7d505 313 {
AndrewL 0:1dafafe7d505 314 // check bounds
AndrewL 0:1dafafe7d505 315 if(id >= _numresources) error("mbos::TestResource - %i is an invalid resource id\n", id);
AndrewL 0:1dafafe7d505 316 return(_resources[id].lock);
AndrewL 0:1dafafe7d505 317 }
AndrewL 0:1dafafe7d505 318 // Free Resource Function --------------------------------------------------------------
AndrewL 0:1dafafe7d505 319 uint mbos::FreeResource(uint id)
AndrewL 0:1dafafe7d505 320 {
AndrewL 0:1dafafe7d505 321 // check bounds
AndrewL 0:1dafafe7d505 322 if(id >= _numresources) error("mbos::FreeResource - %i is an invalid resource id\n", id);
AndrewL 4:e740e08cbea9 323 if(_tasklist[0]->id == 0 || _tasklist[0]->id != _resources[id].lock) return _resources[id].lock;
AndrewL 0:1dafafe7d505 324
AndrewL 0:1dafafe7d505 325 __disable_irq();
AndrewL 0:1dafafe7d505 326 _resources[id].lock = 0;
AndrewL 0:1dafafe7d505 327 _tasklist[0]->priostate = _resources[id].taskprio;
AndrewL 0:1dafafe7d505 328 __enable_irq();
AndrewL 0:1dafafe7d505 329 return 0;
AndrewL 0:1dafafe7d505 330 }
AndrewL 0:1dafafe7d505 331 // Initialise stack function -----------------------------------------------------------
AndrewL 0:1dafafe7d505 332 uint* mbos::_initstack(uint *stack, void (*fun)())
AndrewL 0:1dafafe7d505 333 {
AndrewL 0:1dafafe7d505 334 stack -= 3; // leave a spare word
AndrewL 0:1dafafe7d505 335 *stack = 0x01000000; // Initial xPSR (reset value)
AndrewL 0:1dafafe7d505 336 stack--;
AndrewL 0:1dafafe7d505 337 *stack = (uint)fun - 1; // Start address of the task corrected
AndrewL 0:1dafafe7d505 338 stack--;
AndrewL 0:1dafafe7d505 339 *stack = 0; // LR
AndrewL 0:1dafafe7d505 340 stack -= 5; // R12, R3, R2, R1, R0
AndrewL 0:1dafafe7d505 341 stack -= 8; // R11, R10, R9, R8, R7, R6, R5, R4
AndrewL 0:1dafafe7d505 342 return stack;
AndrewL 0:1dafafe7d505 343 }
AndrewL 4:e740e08cbea9 344 // Stack Error function ----------------------------------------------------------------
AndrewL 0:1dafafe7d505 345 void _stackerror(uint task)
AndrewL 0:1dafafe7d505 346 {
AndrewL 0:1dafafe7d505 347 error("Stack Overflow on Task %i\n", task);
AndrewL 0:1dafafe7d505 348 }