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 Header. Declarations And Definitions
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 #ifndef OS_SERVICES_H
daryl2110 0:57ece500234e 43 #define OS_SERVICES_H
daryl2110 0:57ece500234e 44
daryl2110 0:57ece500234e 45 namespace OS
daryl2110 0:57ece500234e 46 {
daryl2110 0:57ece500234e 47 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 48 //
daryl2110 0:57ece500234e 49 // NAME : Mutex
daryl2110 0:57ece500234e 50 //
daryl2110 0:57ece500234e 51 /// Binary semaphore for support of mutual exclusion
daryl2110 0:57ece500234e 52 //
daryl2110 0:57ece500234e 53 // DESCRIPTION:
daryl2110 0:57ece500234e 54 //
daryl2110 0:57ece500234e 55 //
daryl2110 0:57ece500234e 56 class TMutex
daryl2110 0:57ece500234e 57 {
daryl2110 0:57ece500234e 58 public:
daryl2110 0:57ece500234e 59 INLINE TMutex() : ProcessMap(0), ValueTag(0) { }
daryl2110 0:57ece500234e 60 void Lock();
daryl2110 0:57ece500234e 61 void Unlock();
daryl2110 0:57ece500234e 62 void UnlockISR();
daryl2110 0:57ece500234e 63
daryl2110 0:57ece500234e 64 INLINE bool LockSoftly() { TCritSect cs; if(ValueTag) return false; else Lock(); return true; }
daryl2110 0:57ece500234e 65 INLINE bool IsLocked() const { TCritSect cs; if(ValueTag) return true; else return false; }
daryl2110 0:57ece500234e 66
daryl2110 0:57ece500234e 67 private:
daryl2110 0:57ece500234e 68 TProcessMap ProcessMap;
daryl2110 0:57ece500234e 69 TProcessMap ValueTag;
daryl2110 0:57ece500234e 70
daryl2110 0:57ece500234e 71 };
daryl2110 0:57ece500234e 72 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 73
daryl2110 0:57ece500234e 74 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 75 //
daryl2110 0:57ece500234e 76 /// Event Flag
daryl2110 0:57ece500234e 77 ///
daryl2110 0:57ece500234e 78 /// Intended for processes synchronization and
daryl2110 0:57ece500234e 79 /// event notification one (or more) process by another
daryl2110 0:57ece500234e 80 //
daryl2110 0:57ece500234e 81 // DESCRIPTION:
daryl2110 0:57ece500234e 82 //
daryl2110 0:57ece500234e 83 //
daryl2110 0:57ece500234e 84 class TEventFlag
daryl2110 0:57ece500234e 85 {
daryl2110 0:57ece500234e 86 public:
daryl2110 0:57ece500234e 87 enum TValue { efOn = 1, efOff= 0 }; // prefix 'ef' means: "Event Flag"
daryl2110 0:57ece500234e 88
daryl2110 0:57ece500234e 89 public:
daryl2110 0:57ece500234e 90 INLINE TEventFlag(TValue init_val = efOff) : ProcessMap(0), Value(init_val) { }
daryl2110 0:57ece500234e 91
daryl2110 0:57ece500234e 92 bool Wait(TTimeout timeout = 0);
daryl2110 0:57ece500234e 93 void Signal();
daryl2110 0:57ece500234e 94 INLINE void Clear() { TCritSect cs; Value = efOff; }
daryl2110 0:57ece500234e 95 INLINE inline void SignalISR();
daryl2110 0:57ece500234e 96 INLINE bool IsSignaled() { TCritSect cs; if(Value == efOn) return true; else return false; }
daryl2110 0:57ece500234e 97
daryl2110 0:57ece500234e 98 private:
daryl2110 0:57ece500234e 99 TProcessMap ProcessMap;
daryl2110 0:57ece500234e 100 TValue Value;
daryl2110 0:57ece500234e 101 };
daryl2110 0:57ece500234e 102 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 103
daryl2110 0:57ece500234e 104 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 105 //
daryl2110 0:57ece500234e 106 /// TChannel
daryl2110 0:57ece500234e 107 ///
daryl2110 0:57ece500234e 108 /// Byte-wide data channel for transferring "raw" data
daryl2110 0:57ece500234e 109 //
daryl2110 0:57ece500234e 110 // DESCRIPTION:
daryl2110 0:57ece500234e 111 //
daryl2110 0:57ece500234e 112 //
daryl2110 0:57ece500234e 113 class TChannel
daryl2110 0:57ece500234e 114 {
daryl2110 0:57ece500234e 115 public:
daryl2110 0:57ece500234e 116 INLINE TChannel(byte* buf, byte size) : Cbuf(buf, size) { }
daryl2110 0:57ece500234e 117 void Push(byte x);
daryl2110 0:57ece500234e 118 byte Pop();
daryl2110 0:57ece500234e 119 void Write(const byte* data, const byte count);
daryl2110 0:57ece500234e 120 void Read(byte* const data, const byte count);
daryl2110 0:57ece500234e 121
daryl2110 0:57ece500234e 122 INLINE byte GetCount() const { TCritSect cs; return Cbuf.get_count(); }
daryl2110 0:57ece500234e 123
daryl2110 0:57ece500234e 124 private:
daryl2110 0:57ece500234e 125 TProcessMap ProducersProcessMap;
daryl2110 0:57ece500234e 126 TProcessMap ConsumersProcessMap;
daryl2110 0:57ece500234e 127 usr::TCbuf Cbuf;
daryl2110 0:57ece500234e 128
daryl2110 0:57ece500234e 129 private:
daryl2110 0:57ece500234e 130 void CheckWaiters(TProcessMap& pm);
daryl2110 0:57ece500234e 131 };
daryl2110 0:57ece500234e 132 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 133
daryl2110 0:57ece500234e 134
daryl2110 0:57ece500234e 135 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 136 //
daryl2110 0:57ece500234e 137 // NAME : channel
daryl2110 0:57ece500234e 138 //
daryl2110 0:57ece500234e 139 // PURPOSE : Data channel for transferring data
daryl2110 0:57ece500234e 140 // objects of arbitrary type
daryl2110 0:57ece500234e 141 //
daryl2110 0:57ece500234e 142 // DESCRIPTION:
daryl2110 0:57ece500234e 143 //
daryl2110 0:57ece500234e 144 //
daryl2110 0:57ece500234e 145 template<typename T, word Size, typename S = byte>
daryl2110 0:57ece500234e 146 /// channel
daryl2110 0:57ece500234e 147 ///
daryl2110 0:57ece500234e 148 /// Data channel for transferring data objects of arbitrary type
daryl2110 0:57ece500234e 149 class channel
daryl2110 0:57ece500234e 150 {
daryl2110 0:57ece500234e 151 public:
daryl2110 0:57ece500234e 152 INLINE channel() : ProducersProcessMap(0)
daryl2110 0:57ece500234e 153 , ConsumersProcessMap(0)
daryl2110 0:57ece500234e 154 , pool()
daryl2110 0:57ece500234e 155 {
daryl2110 0:57ece500234e 156 }
daryl2110 0:57ece500234e 157
daryl2110 0:57ece500234e 158 //----------------------------------------------------------------
daryl2110 0:57ece500234e 159 //
daryl2110 0:57ece500234e 160 // Data transfer functions
daryl2110 0:57ece500234e 161 //
daryl2110 0:57ece500234e 162 void write(const T* data, const S cnt);
daryl2110 0:57ece500234e 163 bool read (T* const data, const S cnt, TTimeout timeout = 0);
daryl2110 0:57ece500234e 164
daryl2110 0:57ece500234e 165 void push (const T& item);
daryl2110 0:57ece500234e 166 void push_front(const T& item);
daryl2110 0:57ece500234e 167
daryl2110 0:57ece500234e 168 bool pop (T& item, TTimeout timeout = 0);
daryl2110 0:57ece500234e 169 bool pop_back(T& item, TTimeout timeout = 0);
daryl2110 0:57ece500234e 170
daryl2110 0:57ece500234e 171
daryl2110 0:57ece500234e 172 //----------------------------------------------------------------
daryl2110 0:57ece500234e 173 //
daryl2110 0:57ece500234e 174 // Service functions
daryl2110 0:57ece500234e 175 //
daryl2110 0:57ece500234e 176 INLINE S get_count() const { TCritSect cs; return pool.get_count(); }
daryl2110 0:57ece500234e 177 INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); }
daryl2110 0:57ece500234e 178 void flush();
daryl2110 0:57ece500234e 179 //const T& operator[](const S index) { TCritSect cs; return pool[index]; }
daryl2110 0:57ece500234e 180
daryl2110 0:57ece500234e 181
daryl2110 0:57ece500234e 182 private:
daryl2110 0:57ece500234e 183 TProcessMap ProducersProcessMap;
daryl2110 0:57ece500234e 184 TProcessMap ConsumersProcessMap;
daryl2110 0:57ece500234e 185 usr::ring_buffer<T, Size, S> pool;
daryl2110 0:57ece500234e 186
daryl2110 0:57ece500234e 187 private:
daryl2110 0:57ece500234e 188 void CheckWaiters(TProcessMap& pm);
daryl2110 0:57ece500234e 189 };
daryl2110 0:57ece500234e 190
daryl2110 0:57ece500234e 191 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 192
daryl2110 0:57ece500234e 193 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 194 //
daryl2110 0:57ece500234e 195 /// message
daryl2110 0:57ece500234e 196 ///
daryl2110 0:57ece500234e 197 /// Template for messages
daryl2110 0:57ece500234e 198 //
daryl2110 0:57ece500234e 199 // DESCRIPTION:
daryl2110 0:57ece500234e 200 //
daryl2110 0:57ece500234e 201 //
daryl2110 0:57ece500234e 202 class TBaseMessage
daryl2110 0:57ece500234e 203 {
daryl2110 0:57ece500234e 204 public:
daryl2110 0:57ece500234e 205 INLINE TBaseMessage() : ProcessMap(0), NonEmpty(false) { }
daryl2110 0:57ece500234e 206
daryl2110 0:57ece500234e 207 bool wait (TTimeout timeout = 0);
daryl2110 0:57ece500234e 208 void send();
daryl2110 0:57ece500234e 209 INLINE inline void sendISR();
daryl2110 0:57ece500234e 210 INLINE bool is_non_empty() const { TCritSect cs; return NonEmpty; }
daryl2110 0:57ece500234e 211 INLINE void reset () { TCritSect cs; NonEmpty = false; }
daryl2110 0:57ece500234e 212
daryl2110 0:57ece500234e 213 private:
daryl2110 0:57ece500234e 214 TProcessMap ProcessMap;
daryl2110 0:57ece500234e 215 bool NonEmpty;
daryl2110 0:57ece500234e 216 };
daryl2110 0:57ece500234e 217 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 218 template<typename T>
daryl2110 0:57ece500234e 219 class message : public TBaseMessage
daryl2110 0:57ece500234e 220 {
daryl2110 0:57ece500234e 221 public:
daryl2110 0:57ece500234e 222 INLINE message() : TBaseMessage() { }
daryl2110 0:57ece500234e 223 INLINE const T& operator=(const T& msg) { TCritSect cs; Msg = msg; return Msg; }
daryl2110 0:57ece500234e 224 INLINE operator T() const { TCritSect cs; return Msg; }
daryl2110 0:57ece500234e 225
daryl2110 0:57ece500234e 226 private:
daryl2110 0:57ece500234e 227 T Msg;
daryl2110 0:57ece500234e 228 };
daryl2110 0:57ece500234e 229 //--------------------------------------------------------------------------
daryl2110 0:57ece500234e 230 }
daryl2110 0:57ece500234e 231 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 232 //
daryl2110 0:57ece500234e 233 // Function-members implementation
daryl2110 0:57ece500234e 234 //
daryl2110 0:57ece500234e 235 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 236 void OS::TEventFlag::SignalISR()
daryl2110 0:57ece500234e 237 {
daryl2110 0:57ece500234e 238 TCritSect cs;
daryl2110 0:57ece500234e 239 if(ProcessMap) // if any process waits for event
daryl2110 0:57ece500234e 240 {
daryl2110 0:57ece500234e 241 TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout
daryl2110 0:57ece500234e 242 // expired, or it was waked up by OS::ForceWakeUpProcess()
daryl2110 0:57ece500234e 243 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
daryl2110 0:57ece500234e 244 {
daryl2110 0:57ece500234e 245 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
daryl2110 0:57ece500234e 246 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
daryl2110 0:57ece500234e 247 return;
daryl2110 0:57ece500234e 248 }
daryl2110 0:57ece500234e 249 }
daryl2110 0:57ece500234e 250 Value = efOn;
daryl2110 0:57ece500234e 251 }
daryl2110 0:57ece500234e 252 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 253 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 254 void OS::channel<T, Size, S>::CheckWaiters(TProcessMap& pm)
daryl2110 0:57ece500234e 255 {
daryl2110 0:57ece500234e 256 if(pm)
daryl2110 0:57ece500234e 257 {
daryl2110 0:57ece500234e 258 TProcessMap Timeouted = Kernel.ReadyProcessMap;
daryl2110 0:57ece500234e 259
daryl2110 0:57ece500234e 260 SetPrioTag(Kernel.ReadyProcessMap, pm); // place all waiting processes to the ready map
daryl2110 0:57ece500234e 261 ClrPrioTag(pm, ~Timeouted); // remove waiting processes from the wait map
daryl2110 0:57ece500234e 262 Kernel.Scheduler();
daryl2110 0:57ece500234e 263 }
daryl2110 0:57ece500234e 264 }
daryl2110 0:57ece500234e 265 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 266 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 267 void OS::channel<T, Size, S>::push(const T& item)
daryl2110 0:57ece500234e 268 {
daryl2110 0:57ece500234e 269 TCritSect cs;
daryl2110 0:57ece500234e 270
daryl2110 0:57ece500234e 271 while(!pool.get_free_size())
daryl2110 0:57ece500234e 272 {
daryl2110 0:57ece500234e 273 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 274 SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
daryl2110 0:57ece500234e 275 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 276 Kernel.Scheduler();
daryl2110 0:57ece500234e 277 }
daryl2110 0:57ece500234e 278
daryl2110 0:57ece500234e 279 pool.push_back(item);
daryl2110 0:57ece500234e 280 CheckWaiters(ConsumersProcessMap);
daryl2110 0:57ece500234e 281 }
daryl2110 0:57ece500234e 282 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 283 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 284 void OS::channel<T, Size, S>::push_front(const T& item)
daryl2110 0:57ece500234e 285 {
daryl2110 0:57ece500234e 286 TCritSect cs;
daryl2110 0:57ece500234e 287
daryl2110 0:57ece500234e 288 while(!pool.get_free_size())
daryl2110 0:57ece500234e 289 {
daryl2110 0:57ece500234e 290 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 291 SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
daryl2110 0:57ece500234e 292 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 293 Kernel.Scheduler();
daryl2110 0:57ece500234e 294 }
daryl2110 0:57ece500234e 295
daryl2110 0:57ece500234e 296 pool.push_front(item);
daryl2110 0:57ece500234e 297 CheckWaiters(ConsumersProcessMap);
daryl2110 0:57ece500234e 298 }
daryl2110 0:57ece500234e 299 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 300 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 301 bool OS::channel<T, Size, S>::pop(T& item, TTimeout timeout)
daryl2110 0:57ece500234e 302 {
daryl2110 0:57ece500234e 303 TCritSect cs;
daryl2110 0:57ece500234e 304
daryl2110 0:57ece500234e 305 if(pool.get_count())
daryl2110 0:57ece500234e 306 {
daryl2110 0:57ece500234e 307 item = pool.pop();
daryl2110 0:57ece500234e 308 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 309 return true;
daryl2110 0:57ece500234e 310 }
daryl2110 0:57ece500234e 311 else
daryl2110 0:57ece500234e 312 {
daryl2110 0:57ece500234e 313 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
daryl2110 0:57ece500234e 314 p->Timeout = timeout;
daryl2110 0:57ece500234e 315
daryl2110 0:57ece500234e 316 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 317 for(;;)
daryl2110 0:57ece500234e 318 {
daryl2110 0:57ece500234e 319 SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
daryl2110 0:57ece500234e 320 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 321 Kernel.Scheduler();
daryl2110 0:57ece500234e 322
daryl2110 0:57ece500234e 323 if(pool.get_count())
daryl2110 0:57ece500234e 324 {
daryl2110 0:57ece500234e 325 p->Timeout = 0;
daryl2110 0:57ece500234e 326 item = pool.pop();
daryl2110 0:57ece500234e 327 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 328 return true;
daryl2110 0:57ece500234e 329 }
daryl2110 0:57ece500234e 330
daryl2110 0:57ece500234e 331 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
daryl2110 0:57ece500234e 332 { // or by OS::ForceWakeUpProcess()
daryl2110 0:57ece500234e 333
daryl2110 0:57ece500234e 334 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
daryl2110 0:57ece500234e 335 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
daryl2110 0:57ece500234e 336 return false;
daryl2110 0:57ece500234e 337 }
daryl2110 0:57ece500234e 338 }
daryl2110 0:57ece500234e 339 }
daryl2110 0:57ece500234e 340 }
daryl2110 0:57ece500234e 341 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 342 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 343 bool OS::channel<T, Size, S>::pop_back(T& item, TTimeout timeout)
daryl2110 0:57ece500234e 344 {
daryl2110 0:57ece500234e 345 TCritSect cs;
daryl2110 0:57ece500234e 346
daryl2110 0:57ece500234e 347 if(pool.get_count())
daryl2110 0:57ece500234e 348 {
daryl2110 0:57ece500234e 349 item = pool.pop_back();
daryl2110 0:57ece500234e 350 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 351 return true;
daryl2110 0:57ece500234e 352 }
daryl2110 0:57ece500234e 353 else
daryl2110 0:57ece500234e 354 {
daryl2110 0:57ece500234e 355 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
daryl2110 0:57ece500234e 356 p->Timeout = timeout;
daryl2110 0:57ece500234e 357
daryl2110 0:57ece500234e 358 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 359 for(;;)
daryl2110 0:57ece500234e 360 {
daryl2110 0:57ece500234e 361 SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
daryl2110 0:57ece500234e 362 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 363 Kernel.Scheduler();
daryl2110 0:57ece500234e 364
daryl2110 0:57ece500234e 365 if(pool.get_count())
daryl2110 0:57ece500234e 366 {
daryl2110 0:57ece500234e 367 p->Timeout = 0;
daryl2110 0:57ece500234e 368 item = pool.pop_back();
daryl2110 0:57ece500234e 369 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 370 return true;
daryl2110 0:57ece500234e 371 }
daryl2110 0:57ece500234e 372
daryl2110 0:57ece500234e 373 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
daryl2110 0:57ece500234e 374 { // or by OS::ForceWakeUpProcess()
daryl2110 0:57ece500234e 375
daryl2110 0:57ece500234e 376 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
daryl2110 0:57ece500234e 377 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
daryl2110 0:57ece500234e 378 return false;
daryl2110 0:57ece500234e 379 }
daryl2110 0:57ece500234e 380 }
daryl2110 0:57ece500234e 381 }
daryl2110 0:57ece500234e 382 }
daryl2110 0:57ece500234e 383 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 384 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 385 void OS::channel<T, Size, S>::flush()
daryl2110 0:57ece500234e 386 {
daryl2110 0:57ece500234e 387 TCritSect cs;
daryl2110 0:57ece500234e 388 pool.flush();
daryl2110 0:57ece500234e 389 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 390 }
daryl2110 0:57ece500234e 391 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 392 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 393 void OS::channel<T, Size, S>::write(const T* data, const S count)
daryl2110 0:57ece500234e 394 {
daryl2110 0:57ece500234e 395 TCritSect cs;
daryl2110 0:57ece500234e 396
daryl2110 0:57ece500234e 397 while(pool.get_free_size() < count)
daryl2110 0:57ece500234e 398 {
daryl2110 0:57ece500234e 399 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 400 SetPrioTag(ProducersProcessMap, PrioTag); // channel does not have enough space, put current process to the wait map
daryl2110 0:57ece500234e 401 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 402 Kernel.Scheduler();
daryl2110 0:57ece500234e 403 }
daryl2110 0:57ece500234e 404
daryl2110 0:57ece500234e 405 pool.write(data, count);
daryl2110 0:57ece500234e 406 CheckWaiters(ConsumersProcessMap);
daryl2110 0:57ece500234e 407 }
daryl2110 0:57ece500234e 408 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 409 template<typename T, word Size, typename S>
daryl2110 0:57ece500234e 410 bool OS::channel<T, Size, S>::read(T* const data, const S count, TTimeout timeout)
daryl2110 0:57ece500234e 411 {
daryl2110 0:57ece500234e 412 TCritSect cs;
daryl2110 0:57ece500234e 413
daryl2110 0:57ece500234e 414 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
daryl2110 0:57ece500234e 415 p->Timeout = timeout;
daryl2110 0:57ece500234e 416
daryl2110 0:57ece500234e 417 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
daryl2110 0:57ece500234e 418 while(pool.get_count() < count)
daryl2110 0:57ece500234e 419 {
daryl2110 0:57ece500234e 420 SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map
daryl2110 0:57ece500234e 421 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
daryl2110 0:57ece500234e 422 Kernel.Scheduler();
daryl2110 0:57ece500234e 423
daryl2110 0:57ece500234e 424 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
daryl2110 0:57ece500234e 425 { // or by OS::ForceWakeUpProcess()
daryl2110 0:57ece500234e 426
daryl2110 0:57ece500234e 427 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
daryl2110 0:57ece500234e 428 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
daryl2110 0:57ece500234e 429 return false;
daryl2110 0:57ece500234e 430 }
daryl2110 0:57ece500234e 431 }
daryl2110 0:57ece500234e 432
daryl2110 0:57ece500234e 433 p->Timeout = 0;
daryl2110 0:57ece500234e 434 pool.read(data, count);
daryl2110 0:57ece500234e 435 CheckWaiters(ProducersProcessMap);
daryl2110 0:57ece500234e 436
daryl2110 0:57ece500234e 437 return true;
daryl2110 0:57ece500234e 438 }
daryl2110 0:57ece500234e 439 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 440
daryl2110 0:57ece500234e 441 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 442 //
daryl2110 0:57ece500234e 443 // OS::message template
daryl2110 0:57ece500234e 444 //
daryl2110 0:57ece500234e 445 // Function-members implementation
daryl2110 0:57ece500234e 446 //
daryl2110 0:57ece500234e 447 //
daryl2110 0:57ece500234e 448 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 449 void OS::TBaseMessage::sendISR()
daryl2110 0:57ece500234e 450 {
daryl2110 0:57ece500234e 451 TCritSect cs;
daryl2110 0:57ece500234e 452
daryl2110 0:57ece500234e 453 if(ProcessMap)
daryl2110 0:57ece500234e 454 {
daryl2110 0:57ece500234e 455 TProcessMap Timeouted = OS::Kernel.ReadyProcessMap; // Process has it's tag set in ReadyProcessMap if timeout
daryl2110 0:57ece500234e 456 // expired, or it was waked up by OS::ForceWakeUpProcess()
daryl2110 0:57ece500234e 457 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
daryl2110 0:57ece500234e 458 {
daryl2110 0:57ece500234e 459 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
daryl2110 0:57ece500234e 460 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
daryl2110 0:57ece500234e 461 return;
daryl2110 0:57ece500234e 462 }
daryl2110 0:57ece500234e 463 }
daryl2110 0:57ece500234e 464 NonEmpty = true;
daryl2110 0:57ece500234e 465 }
daryl2110 0:57ece500234e 466 //------------------------------------------------------------------------------
daryl2110 0:57ece500234e 467 #endif // OS_SERVICES_H