kasturi rangan raghavan / Mbed 2 deprecated QRS_cpp

Dependencies:   mbed

Committer:
kasturir
Date:
Mon Sep 27 22:51:19 2010 +0000
Revision:
0:906c21fbf97c

        

Who changed what in which revision?

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