Dependents:   rtest LeonardoMbos OS_test Labo_TRSE_Drone ... more

Committer:
AndrewL
Date:
Sat Dec 04 16:51:52 2010 +0000
Revision:
0:1dafafe7d505
Child:
4:e740e08cbea9
1.1a
changed name to mbos, simplified errors, updated doxygen comments, removed returncodes from resource management

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