Program to control an accelerometer, motors and a rangefinder using the ScmRTOS ported to mbed. (Work in progress and buggy)

Dependencies:   mbed

Committer:
jberry
Date:
Mon Nov 01 20:39:01 2010 +0000
Revision:
0:9b057566f9ee

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jberry 0:9b057566f9ee 1 //******************************************************************************
jberry 0:9b057566f9ee 2 //*
jberry 0:9b057566f9ee 3 //* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
jberry 0:9b057566f9ee 4 //*
jberry 0:9b057566f9ee 5 //* NICKNAME: scmRTOS
jberry 0:9b057566f9ee 6 //*
jberry 0:9b057566f9ee 7 //* PURPOSE: OS Services Source
jberry 0:9b057566f9ee 8 //*
jberry 0:9b057566f9ee 9 //* Version: 3.10
jberry 0:9b057566f9ee 10 //*
jberry 0:9b057566f9ee 11 //* $Revision: 256 $
jberry 0:9b057566f9ee 12 //* $Date:: 2010-01-22 #$
jberry 0:9b057566f9ee 13 //*
jberry 0:9b057566f9ee 14 //* Copyright (c) 2003-2010, Harry E. Zhurov
jberry 0:9b057566f9ee 15 //*
jberry 0:9b057566f9ee 16 //* Permission is hereby granted, free of charge, to any person
jberry 0:9b057566f9ee 17 //* obtaining a copy of this software and associated documentation
jberry 0:9b057566f9ee 18 //* files (the "Software"), to deal in the Software without restriction,
jberry 0:9b057566f9ee 19 //* including without limitation the rights to use, copy, modify, merge,
jberry 0:9b057566f9ee 20 //* publish, distribute, sublicense, and/or sell copies of the Software,
jberry 0:9b057566f9ee 21 //* and to permit persons to whom the Software is furnished to do so,
jberry 0:9b057566f9ee 22 //* subject to the following conditions:
jberry 0:9b057566f9ee 23 //*
jberry 0:9b057566f9ee 24 //* The above copyright notice and this permission notice shall be included
jberry 0:9b057566f9ee 25 //* in all copies or substantial portions of the Software.
jberry 0:9b057566f9ee 26 //*
jberry 0:9b057566f9ee 27 //* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
jberry 0:9b057566f9ee 28 //* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
jberry 0:9b057566f9ee 29 //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
jberry 0:9b057566f9ee 30 //* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
jberry 0:9b057566f9ee 31 //* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
jberry 0:9b057566f9ee 32 //* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
jberry 0:9b057566f9ee 33 //* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
jberry 0:9b057566f9ee 34 //*
jberry 0:9b057566f9ee 35 //* =================================================================
jberry 0:9b057566f9ee 36 //* See http://scmrtos.sourceforge.net for documentation, latest
jberry 0:9b057566f9ee 37 //* information, license and contact details.
jberry 0:9b057566f9ee 38 //* =================================================================
jberry 0:9b057566f9ee 39 //*
jberry 0:9b057566f9ee 40 //******************************************************************************
jberry 0:9b057566f9ee 41
jberry 0:9b057566f9ee 42 #include "scmRTOS.h"
jberry 0:9b057566f9ee 43
jberry 0:9b057566f9ee 44 using namespace OS;
jberry 0:9b057566f9ee 45
jberry 0:9b057566f9ee 46 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 47 //
jberry 0:9b057566f9ee 48 //
jberry 0:9b057566f9ee 49 // TEventFlag
jberry 0:9b057566f9ee 50 //
jberry 0:9b057566f9ee 51 //
jberry 0:9b057566f9ee 52 bool OS::TEventFlag::Wait(TTimeout timeout)
jberry 0:9b057566f9ee 53 {
jberry 0:9b057566f9ee 54 TCritSect cs;
jberry 0:9b057566f9ee 55
jberry 0:9b057566f9ee 56 if(Value) // if flag already signaled
jberry 0:9b057566f9ee 57 {
jberry 0:9b057566f9ee 58 Value = efOff; // clear flag
jberry 0:9b057566f9ee 59 return true;
jberry 0:9b057566f9ee 60 }
jberry 0:9b057566f9ee 61 else
jberry 0:9b057566f9ee 62 {
jberry 0:9b057566f9ee 63 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
jberry 0:9b057566f9ee 64 p->Timeout = timeout;
jberry 0:9b057566f9ee 65 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 66
jberry 0:9b057566f9ee 67 SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map
jberry 0:9b057566f9ee 68 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 69
jberry 0:9b057566f9ee 70 Kernel.Scheduler();
jberry 0:9b057566f9ee 71
jberry 0:9b057566f9ee 72 p->Timeout = 0;
jberry 0:9b057566f9ee 73
jberry 0:9b057566f9ee 74 if( !(ProcessMap & PrioTag) ) // if waked up by signal() or signal_ISR()
jberry 0:9b057566f9ee 75 return true;
jberry 0:9b057566f9ee 76
jberry 0:9b057566f9ee 77 ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by
jberry 0:9b057566f9ee 78 return false; // OS::ForceWakeUpProcess(), remove process from the wait map
jberry 0:9b057566f9ee 79 }
jberry 0:9b057566f9ee 80 }
jberry 0:9b057566f9ee 81 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 82 void OS::TEventFlag::Signal()
jberry 0:9b057566f9ee 83 {
jberry 0:9b057566f9ee 84 TCritSect cs;
jberry 0:9b057566f9ee 85 if(ProcessMap) // if any process waits for event
jberry 0:9b057566f9ee 86 {
jberry 0:9b057566f9ee 87 TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired
jberry 0:9b057566f9ee 88 // or it was waked up by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 89
jberry 0:9b057566f9ee 90 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
jberry 0:9b057566f9ee 91 {
jberry 0:9b057566f9ee 92 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
jberry 0:9b057566f9ee 93 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
jberry 0:9b057566f9ee 94 // Used to check that process waked up by signal() or signalISR()
jberry 0:9b057566f9ee 95 // and not by timeout or OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 96 Kernel.Scheduler();
jberry 0:9b057566f9ee 97 return;
jberry 0:9b057566f9ee 98 }
jberry 0:9b057566f9ee 99 }
jberry 0:9b057566f9ee 100 Value = efOn;
jberry 0:9b057566f9ee 101 }
jberry 0:9b057566f9ee 102 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 103
jberry 0:9b057566f9ee 104 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 105 //
jberry 0:9b057566f9ee 106 //
jberry 0:9b057566f9ee 107 // TMutex
jberry 0:9b057566f9ee 108 //
jberry 0:9b057566f9ee 109 //
jberry 0:9b057566f9ee 110 void OS::TMutex::Lock()
jberry 0:9b057566f9ee 111 {
jberry 0:9b057566f9ee 112 TCritSect cs;
jberry 0:9b057566f9ee 113
jberry 0:9b057566f9ee 114 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 115 while(ValueTag)
jberry 0:9b057566f9ee 116 {
jberry 0:9b057566f9ee 117 SetPrioTag(ProcessMap, PrioTag); // mutex already locked by another process, put current process to the wait map
jberry 0:9b057566f9ee 118 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 119
jberry 0:9b057566f9ee 120 Kernel.Scheduler();
jberry 0:9b057566f9ee 121 }
jberry 0:9b057566f9ee 122 ValueTag = PrioTag; // mutex has been successfully locked
jberry 0:9b057566f9ee 123 }
jberry 0:9b057566f9ee 124 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 125 void OS::TMutex::Unlock()
jberry 0:9b057566f9ee 126 {
jberry 0:9b057566f9ee 127 TCritSect cs;
jberry 0:9b057566f9ee 128
jberry 0:9b057566f9ee 129 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 130 if(ValueTag != PrioTag) return; // the only process that had locked mutex can unlock the mutex
jberry 0:9b057566f9ee 131 ValueTag = 0;
jberry 0:9b057566f9ee 132 if(ProcessMap)
jberry 0:9b057566f9ee 133 {
jberry 0:9b057566f9ee 134 byte pr = GetHighPriority(ProcessMap);
jberry 0:9b057566f9ee 135 PrioTag = GetPrioTag(pr);
jberry 0:9b057566f9ee 136 ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map
jberry 0:9b057566f9ee 137 SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
jberry 0:9b057566f9ee 138 Kernel.Scheduler();
jberry 0:9b057566f9ee 139 }
jberry 0:9b057566f9ee 140 }
jberry 0:9b057566f9ee 141 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 142 void OS::TMutex::UnlockISR()
jberry 0:9b057566f9ee 143 {
jberry 0:9b057566f9ee 144 TCritSect cs;
jberry 0:9b057566f9ee 145
jberry 0:9b057566f9ee 146 ValueTag = 0;
jberry 0:9b057566f9ee 147 if(ProcessMap)
jberry 0:9b057566f9ee 148 {
jberry 0:9b057566f9ee 149 byte pr = GetHighPriority(ProcessMap);
jberry 0:9b057566f9ee 150 TProcessMap PrioTag = GetPrioTag(pr);
jberry 0:9b057566f9ee 151 ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map
jberry 0:9b057566f9ee 152 SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
jberry 0:9b057566f9ee 153 }
jberry 0:9b057566f9ee 154 }
jberry 0:9b057566f9ee 155 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 156
jberry 0:9b057566f9ee 157
jberry 0:9b057566f9ee 158 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 159 //
jberry 0:9b057566f9ee 160 //
jberry 0:9b057566f9ee 161 // TChannel
jberry 0:9b057566f9ee 162 //
jberry 0:9b057566f9ee 163 //
jberry 0:9b057566f9ee 164 void OS::TChannel::CheckWaiters(TProcessMap& pm)
jberry 0:9b057566f9ee 165 {
jberry 0:9b057566f9ee 166 if(pm)
jberry 0:9b057566f9ee 167 {
jberry 0:9b057566f9ee 168 byte pr = GetHighPriority(pm);
jberry 0:9b057566f9ee 169 TProcessMap PrioTag = GetPrioTag(pr);
jberry 0:9b057566f9ee 170 ClrPrioTag(pm, PrioTag); // remove next ready process from the wait map
jberry 0:9b057566f9ee 171 SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
jberry 0:9b057566f9ee 172 Kernel.Scheduler();
jberry 0:9b057566f9ee 173 }
jberry 0:9b057566f9ee 174 }
jberry 0:9b057566f9ee 175 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 176 void OS::TChannel::Push(byte x)
jberry 0:9b057566f9ee 177 {
jberry 0:9b057566f9ee 178 TCritSect cs;
jberry 0:9b057566f9ee 179
jberry 0:9b057566f9ee 180 while (!Cbuf.get_free_size())
jberry 0:9b057566f9ee 181 {
jberry 0:9b057566f9ee 182 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 183 SetPrioTag (ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
jberry 0:9b057566f9ee 184 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 185 Kernel.Scheduler(); // wait until waked-up by Pop() or Read()
jberry 0:9b057566f9ee 186 }
jberry 0:9b057566f9ee 187
jberry 0:9b057566f9ee 188 Cbuf.put(x);
jberry 0:9b057566f9ee 189 CheckWaiters(ConsumersProcessMap);
jberry 0:9b057566f9ee 190 }
jberry 0:9b057566f9ee 191 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 192 byte OS::TChannel::Pop()
jberry 0:9b057566f9ee 193 {
jberry 0:9b057566f9ee 194 TCritSect cs;
jberry 0:9b057566f9ee 195 byte x;
jberry 0:9b057566f9ee 196
jberry 0:9b057566f9ee 197 while(!Cbuf.get_count())
jberry 0:9b057566f9ee 198 {
jberry 0:9b057566f9ee 199 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 200 SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
jberry 0:9b057566f9ee 201 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 202 Kernel.Scheduler(); // wait until waked up by Push() or Write()
jberry 0:9b057566f9ee 203 }
jberry 0:9b057566f9ee 204 x = Cbuf.get();
jberry 0:9b057566f9ee 205 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 206 return x;
jberry 0:9b057566f9ee 207 }
jberry 0:9b057566f9ee 208 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 209 void OS::TChannel::Write(const byte* data, const byte count)
jberry 0:9b057566f9ee 210 {
jberry 0:9b057566f9ee 211 TCritSect cs;
jberry 0:9b057566f9ee 212
jberry 0:9b057566f9ee 213 while(Cbuf.get_free_size() < count)
jberry 0:9b057566f9ee 214 {
jberry 0:9b057566f9ee 215 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 216 SetPrioTag(ProducersProcessMap, PrioTag); // channel has not enough space, put current process to the wait map
jberry 0:9b057566f9ee 217 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 218 Kernel.Scheduler(); // wait until waked up by Read() or Pop()
jberry 0:9b057566f9ee 219 }
jberry 0:9b057566f9ee 220
jberry 0:9b057566f9ee 221 Cbuf.write(data, count);
jberry 0:9b057566f9ee 222 CheckWaiters(ConsumersProcessMap);
jberry 0:9b057566f9ee 223 }
jberry 0:9b057566f9ee 224 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 225 void OS::TChannel::Read(byte* const data, const byte count)
jberry 0:9b057566f9ee 226 {
jberry 0:9b057566f9ee 227 TCritSect cs;
jberry 0:9b057566f9ee 228
jberry 0:9b057566f9ee 229 while(Cbuf.get_count() < count)
jberry 0:9b057566f9ee 230 {
jberry 0:9b057566f9ee 231 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 232 SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map
jberry 0:9b057566f9ee 233 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 234 Kernel.Scheduler(); // wait until waked up by Write() or Push()
jberry 0:9b057566f9ee 235 }
jberry 0:9b057566f9ee 236
jberry 0:9b057566f9ee 237 Cbuf.read(data, count);
jberry 0:9b057566f9ee 238 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 239 }
jberry 0:9b057566f9ee 240 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 241
jberry 0:9b057566f9ee 242 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 243 //
jberry 0:9b057566f9ee 244 // OS::message template
jberry 0:9b057566f9ee 245 //
jberry 0:9b057566f9ee 246 // Function-members implementation
jberry 0:9b057566f9ee 247 //
jberry 0:9b057566f9ee 248 //
jberry 0:9b057566f9ee 249 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 250 bool OS::TBaseMessage::wait(TTimeout timeout)
jberry 0:9b057566f9ee 251 {
jberry 0:9b057566f9ee 252 TCritSect cs;
jberry 0:9b057566f9ee 253
jberry 0:9b057566f9ee 254 if(NonEmpty) // message alredy send
jberry 0:9b057566f9ee 255 {
jberry 0:9b057566f9ee 256 NonEmpty = false;
jberry 0:9b057566f9ee 257 return true;
jberry 0:9b057566f9ee 258 }
jberry 0:9b057566f9ee 259 else
jberry 0:9b057566f9ee 260 {
jberry 0:9b057566f9ee 261 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
jberry 0:9b057566f9ee 262 p->Timeout = timeout;
jberry 0:9b057566f9ee 263 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 264
jberry 0:9b057566f9ee 265 SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map
jberry 0:9b057566f9ee 266 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 267 Kernel.Scheduler(); // wait until wake up
jberry 0:9b057566f9ee 268
jberry 0:9b057566f9ee 269 p->Timeout = 0;
jberry 0:9b057566f9ee 270 if( !(ProcessMap & PrioTag) ) // if waked up by send() or sendISR()
jberry 0:9b057566f9ee 271 return true;
jberry 0:9b057566f9ee 272
jberry 0:9b057566f9ee 273 ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by
jberry 0:9b057566f9ee 274 return false; // OS::ForceWakeUpProcess(), remove process from wait map
jberry 0:9b057566f9ee 275 }
jberry 0:9b057566f9ee 276 }
jberry 0:9b057566f9ee 277 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 278 void OS::TBaseMessage::send()
jberry 0:9b057566f9ee 279 {
jberry 0:9b057566f9ee 280 TCritSect cs;
jberry 0:9b057566f9ee 281
jberry 0:9b057566f9ee 282 if(ProcessMap)
jberry 0:9b057566f9ee 283 {
jberry 0:9b057566f9ee 284 TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired,
jberry 0:9b057566f9ee 285 // or it was waked up by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 286 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
jberry 0:9b057566f9ee 287 {
jberry 0:9b057566f9ee 288 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
jberry 0:9b057566f9ee 289 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
jberry 0:9b057566f9ee 290 Kernel.Scheduler();
jberry 0:9b057566f9ee 291 return;
jberry 0:9b057566f9ee 292 }
jberry 0:9b057566f9ee 293 }
jberry 0:9b057566f9ee 294
jberry 0:9b057566f9ee 295 NonEmpty = true;
jberry 0:9b057566f9ee 296 }
jberry 0:9b057566f9ee 297 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 298