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