Dependencies:   keypad SDHCFileSystem mbed FPointer wave_player

Committer:
daryl2110
Date:
Mon Feb 20 07:36:06 2012 +0000
Revision:
0:879af6e11219

        

Who changed what in which revision?

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