Dependencies:   PinDetect TextLCD mbed mRotaryEncoder

Committer:
cicklaus
Date:
Mon Feb 13 02:11:20 2012 +0000
Revision:
0:afb2650fb49a

        

Who changed what in which revision?

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