Dependencies:   keypad SDHCFileSystem TextLCD mbed FPointer wave_player

Committer:
daryl2110
Date:
Mon Feb 20 07:32:56 2012 +0000
Revision:
0:57ece500234e

        

Who changed what in which revision?

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