Program to control an accelerometer, motors and a rangefinder using the ScmRTOS ported to mbed. (Work in progress and buggy)

Dependencies:   mbed

Committer:
jberry
Date:
Mon Nov 01 20:39:01 2010 +0000
Revision:
0:9b057566f9ee

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jberry 0:9b057566f9ee 1 //******************************************************************************
jberry 0:9b057566f9ee 2 //*
jberry 0:9b057566f9ee 3 //* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
jberry 0:9b057566f9ee 4 //*
jberry 0:9b057566f9ee 5 //* NICKNAME: scmRTOS
jberry 0:9b057566f9ee 6 //*
jberry 0:9b057566f9ee 7 //* PURPOSE: OS Services Header. Declarations And Definitions
jberry 0:9b057566f9ee 8 //*
jberry 0:9b057566f9ee 9 //* Version: 3.10
jberry 0:9b057566f9ee 10 //*
jberry 0:9b057566f9ee 11 //* $Revision: 256 $
jberry 0:9b057566f9ee 12 //* $Date:: 2010-01-22 #$
jberry 0:9b057566f9ee 13 //*
jberry 0:9b057566f9ee 14 //* Copyright (c) 2003-2010, Harry E. Zhurov
jberry 0:9b057566f9ee 15 //*
jberry 0:9b057566f9ee 16 //* Permission is hereby granted, free of charge, to any person
jberry 0:9b057566f9ee 17 //* obtaining a copy of this software and associated documentation
jberry 0:9b057566f9ee 18 //* files (the "Software"), to deal in the Software without restriction,
jberry 0:9b057566f9ee 19 //* including without limitation the rights to use, copy, modify, merge,
jberry 0:9b057566f9ee 20 //* publish, distribute, sublicense, and/or sell copies of the Software,
jberry 0:9b057566f9ee 21 //* and to permit persons to whom the Software is furnished to do so,
jberry 0:9b057566f9ee 22 //* subject to the following conditions:
jberry 0:9b057566f9ee 23 //*
jberry 0:9b057566f9ee 24 //* The above copyright notice and this permission notice shall be included
jberry 0:9b057566f9ee 25 //* in all copies or substantial portions of the Software.
jberry 0:9b057566f9ee 26 //*
jberry 0:9b057566f9ee 27 //* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
jberry 0:9b057566f9ee 28 //* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
jberry 0:9b057566f9ee 29 //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
jberry 0:9b057566f9ee 30 //* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
jberry 0:9b057566f9ee 31 //* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
jberry 0:9b057566f9ee 32 //* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
jberry 0:9b057566f9ee 33 //* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
jberry 0:9b057566f9ee 34 //*
jberry 0:9b057566f9ee 35 //* =================================================================
jberry 0:9b057566f9ee 36 //* See http://scmrtos.sourceforge.net for documentation, latest
jberry 0:9b057566f9ee 37 //* information, license and contact details.
jberry 0:9b057566f9ee 38 //* =================================================================
jberry 0:9b057566f9ee 39 //*
jberry 0:9b057566f9ee 40 //******************************************************************************
jberry 0:9b057566f9ee 41
jberry 0:9b057566f9ee 42 #ifndef OS_SERVICES_H
jberry 0:9b057566f9ee 43 #define OS_SERVICES_H
jberry 0:9b057566f9ee 44
jberry 0:9b057566f9ee 45 namespace OS
jberry 0:9b057566f9ee 46 {
jberry 0:9b057566f9ee 47 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 48 //
jberry 0:9b057566f9ee 49 // NAME : Mutex
jberry 0:9b057566f9ee 50 //
jberry 0:9b057566f9ee 51 /// Binary semaphore for support of mutual exclusion
jberry 0:9b057566f9ee 52 //
jberry 0:9b057566f9ee 53 // DESCRIPTION:
jberry 0:9b057566f9ee 54 //
jberry 0:9b057566f9ee 55 //
jberry 0:9b057566f9ee 56 class TMutex
jberry 0:9b057566f9ee 57 {
jberry 0:9b057566f9ee 58 public:
jberry 0:9b057566f9ee 59 INLINE TMutex() : ProcessMap(0), ValueTag(0) { }
jberry 0:9b057566f9ee 60 void Lock();
jberry 0:9b057566f9ee 61 void Unlock();
jberry 0:9b057566f9ee 62 void UnlockISR();
jberry 0:9b057566f9ee 63
jberry 0:9b057566f9ee 64 INLINE bool LockSoftly() { TCritSect cs; if(ValueTag) return false; else Lock(); return true; }
jberry 0:9b057566f9ee 65 INLINE bool IsLocked() const { TCritSect cs; if(ValueTag) return true; else return false; }
jberry 0:9b057566f9ee 66
jberry 0:9b057566f9ee 67 private:
jberry 0:9b057566f9ee 68 TProcessMap ProcessMap;
jberry 0:9b057566f9ee 69 TProcessMap ValueTag;
jberry 0:9b057566f9ee 70
jberry 0:9b057566f9ee 71 };
jberry 0:9b057566f9ee 72 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 73
jberry 0:9b057566f9ee 74 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 75 //
jberry 0:9b057566f9ee 76 /// Event Flag
jberry 0:9b057566f9ee 77 ///
jberry 0:9b057566f9ee 78 /// Intended for processes synchronization and
jberry 0:9b057566f9ee 79 /// event notification one (or more) process by another
jberry 0:9b057566f9ee 80 //
jberry 0:9b057566f9ee 81 // DESCRIPTION:
jberry 0:9b057566f9ee 82 //
jberry 0:9b057566f9ee 83 //
jberry 0:9b057566f9ee 84 class TEventFlag
jberry 0:9b057566f9ee 85 {
jberry 0:9b057566f9ee 86 public:
jberry 0:9b057566f9ee 87 enum TValue { efOn = 1, efOff= 0 }; // prefix 'ef' means: "Event Flag"
jberry 0:9b057566f9ee 88
jberry 0:9b057566f9ee 89 public:
jberry 0:9b057566f9ee 90 INLINE TEventFlag(TValue init_val = efOff) : ProcessMap(0), Value(init_val) { }
jberry 0:9b057566f9ee 91
jberry 0:9b057566f9ee 92 bool Wait(TTimeout timeout = 0);
jberry 0:9b057566f9ee 93 void Signal();
jberry 0:9b057566f9ee 94 INLINE void Clear() { TCritSect cs; Value = efOff; }
jberry 0:9b057566f9ee 95 INLINE inline void SignalISR();
jberry 0:9b057566f9ee 96 INLINE bool IsSignaled() { TCritSect cs; if(Value == efOn) return true; else return false; }
jberry 0:9b057566f9ee 97
jberry 0:9b057566f9ee 98 private:
jberry 0:9b057566f9ee 99 TProcessMap ProcessMap;
jberry 0:9b057566f9ee 100 TValue Value;
jberry 0:9b057566f9ee 101 };
jberry 0:9b057566f9ee 102 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 103
jberry 0:9b057566f9ee 104 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 105 //
jberry 0:9b057566f9ee 106 /// TChannel
jberry 0:9b057566f9ee 107 ///
jberry 0:9b057566f9ee 108 /// Byte-wide data channel for transferring "raw" data
jberry 0:9b057566f9ee 109 //
jberry 0:9b057566f9ee 110 // DESCRIPTION:
jberry 0:9b057566f9ee 111 //
jberry 0:9b057566f9ee 112 //
jberry 0:9b057566f9ee 113 class TChannel
jberry 0:9b057566f9ee 114 {
jberry 0:9b057566f9ee 115 public:
jberry 0:9b057566f9ee 116 INLINE TChannel(byte* buf, byte size) : Cbuf(buf, size) { }
jberry 0:9b057566f9ee 117 void Push(byte x);
jberry 0:9b057566f9ee 118 byte Pop();
jberry 0:9b057566f9ee 119 void Write(const byte* data, const byte count);
jberry 0:9b057566f9ee 120 void Read(byte* const data, const byte count);
jberry 0:9b057566f9ee 121
jberry 0:9b057566f9ee 122 INLINE byte GetCount() const { TCritSect cs; return Cbuf.get_count(); }
jberry 0:9b057566f9ee 123
jberry 0:9b057566f9ee 124 private:
jberry 0:9b057566f9ee 125 TProcessMap ProducersProcessMap;
jberry 0:9b057566f9ee 126 TProcessMap ConsumersProcessMap;
jberry 0:9b057566f9ee 127 usr::TCbuf Cbuf;
jberry 0:9b057566f9ee 128
jberry 0:9b057566f9ee 129 private:
jberry 0:9b057566f9ee 130 void CheckWaiters(TProcessMap& pm);
jberry 0:9b057566f9ee 131 };
jberry 0:9b057566f9ee 132 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 133
jberry 0:9b057566f9ee 134
jberry 0:9b057566f9ee 135 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 136 //
jberry 0:9b057566f9ee 137 // NAME : channel
jberry 0:9b057566f9ee 138 //
jberry 0:9b057566f9ee 139 // PURPOSE : Data channel for transferring data
jberry 0:9b057566f9ee 140 // objects of arbitrary type
jberry 0:9b057566f9ee 141 //
jberry 0:9b057566f9ee 142 // DESCRIPTION:
jberry 0:9b057566f9ee 143 //
jberry 0:9b057566f9ee 144 //
jberry 0:9b057566f9ee 145 template<typename T, word Size, typename S = byte>
jberry 0:9b057566f9ee 146 /// channel
jberry 0:9b057566f9ee 147 ///
jberry 0:9b057566f9ee 148 /// Data channel for transferring data objects of arbitrary type
jberry 0:9b057566f9ee 149 class channel
jberry 0:9b057566f9ee 150 {
jberry 0:9b057566f9ee 151 public:
jberry 0:9b057566f9ee 152 INLINE channel() : ProducersProcessMap(0)
jberry 0:9b057566f9ee 153 , ConsumersProcessMap(0)
jberry 0:9b057566f9ee 154 , pool()
jberry 0:9b057566f9ee 155 {
jberry 0:9b057566f9ee 156 }
jberry 0:9b057566f9ee 157
jberry 0:9b057566f9ee 158 //----------------------------------------------------------------
jberry 0:9b057566f9ee 159 //
jberry 0:9b057566f9ee 160 // Data transfer functions
jberry 0:9b057566f9ee 161 //
jberry 0:9b057566f9ee 162 void write(const T* data, const S cnt);
jberry 0:9b057566f9ee 163 bool read (T* const data, const S cnt, TTimeout timeout = 0);
jberry 0:9b057566f9ee 164
jberry 0:9b057566f9ee 165 void push (const T& item);
jberry 0:9b057566f9ee 166 void push_front(const T& item);
jberry 0:9b057566f9ee 167
jberry 0:9b057566f9ee 168 bool pop (T& item, TTimeout timeout = 0);
jberry 0:9b057566f9ee 169 bool pop_back(T& item, TTimeout timeout = 0);
jberry 0:9b057566f9ee 170
jberry 0:9b057566f9ee 171
jberry 0:9b057566f9ee 172 //----------------------------------------------------------------
jberry 0:9b057566f9ee 173 //
jberry 0:9b057566f9ee 174 // Service functions
jberry 0:9b057566f9ee 175 //
jberry 0:9b057566f9ee 176 INLINE S get_count() const { TCritSect cs; return pool.get_count(); }
jberry 0:9b057566f9ee 177 INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); }
jberry 0:9b057566f9ee 178 void flush();
jberry 0:9b057566f9ee 179 //const T& operator[](const S index) { TCritSect cs; return pool[index]; }
jberry 0:9b057566f9ee 180
jberry 0:9b057566f9ee 181
jberry 0:9b057566f9ee 182 private:
jberry 0:9b057566f9ee 183 TProcessMap ProducersProcessMap;
jberry 0:9b057566f9ee 184 TProcessMap ConsumersProcessMap;
jberry 0:9b057566f9ee 185 usr::ring_buffer<T, Size, S> pool;
jberry 0:9b057566f9ee 186
jberry 0:9b057566f9ee 187 private:
jberry 0:9b057566f9ee 188 void CheckWaiters(TProcessMap& pm);
jberry 0:9b057566f9ee 189 };
jberry 0:9b057566f9ee 190
jberry 0:9b057566f9ee 191 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 192
jberry 0:9b057566f9ee 193 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 194 //
jberry 0:9b057566f9ee 195 /// message
jberry 0:9b057566f9ee 196 ///
jberry 0:9b057566f9ee 197 /// Template for messages
jberry 0:9b057566f9ee 198 //
jberry 0:9b057566f9ee 199 // DESCRIPTION:
jberry 0:9b057566f9ee 200 //
jberry 0:9b057566f9ee 201 //
jberry 0:9b057566f9ee 202 class TBaseMessage
jberry 0:9b057566f9ee 203 {
jberry 0:9b057566f9ee 204 public:
jberry 0:9b057566f9ee 205 INLINE TBaseMessage() : ProcessMap(0), NonEmpty(false) { }
jberry 0:9b057566f9ee 206
jberry 0:9b057566f9ee 207 bool wait (TTimeout timeout = 0);
jberry 0:9b057566f9ee 208 void send();
jberry 0:9b057566f9ee 209 INLINE inline void sendISR();
jberry 0:9b057566f9ee 210 INLINE bool is_non_empty() const { TCritSect cs; return NonEmpty; }
jberry 0:9b057566f9ee 211 INLINE void reset () { TCritSect cs; NonEmpty = false; }
jberry 0:9b057566f9ee 212
jberry 0:9b057566f9ee 213 private:
jberry 0:9b057566f9ee 214 TProcessMap ProcessMap;
jberry 0:9b057566f9ee 215 bool NonEmpty;
jberry 0:9b057566f9ee 216 };
jberry 0:9b057566f9ee 217 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 218 template<typename T>
jberry 0:9b057566f9ee 219 class message : public TBaseMessage
jberry 0:9b057566f9ee 220 {
jberry 0:9b057566f9ee 221 public:
jberry 0:9b057566f9ee 222 INLINE message() : TBaseMessage() { }
jberry 0:9b057566f9ee 223 INLINE const T& operator=(const T& msg) { TCritSect cs; Msg = msg; return Msg; }
jberry 0:9b057566f9ee 224 INLINE operator T() const { TCritSect cs; return Msg; }
jberry 0:9b057566f9ee 225
jberry 0:9b057566f9ee 226 private:
jberry 0:9b057566f9ee 227 T Msg;
jberry 0:9b057566f9ee 228 };
jberry 0:9b057566f9ee 229 //--------------------------------------------------------------------------
jberry 0:9b057566f9ee 230 }
jberry 0:9b057566f9ee 231 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 232 //
jberry 0:9b057566f9ee 233 // Function-members implementation
jberry 0:9b057566f9ee 234 //
jberry 0:9b057566f9ee 235 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 236 void OS::TEventFlag::SignalISR()
jberry 0:9b057566f9ee 237 {
jberry 0:9b057566f9ee 238 TCritSect cs;
jberry 0:9b057566f9ee 239 if(ProcessMap) // if any process waits for event
jberry 0:9b057566f9ee 240 {
jberry 0:9b057566f9ee 241 TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout
jberry 0:9b057566f9ee 242 // expired, or it was waked up by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 243 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
jberry 0:9b057566f9ee 244 {
jberry 0:9b057566f9ee 245 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
jberry 0:9b057566f9ee 246 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
jberry 0:9b057566f9ee 247 return;
jberry 0:9b057566f9ee 248 }
jberry 0:9b057566f9ee 249 }
jberry 0:9b057566f9ee 250 Value = efOn;
jberry 0:9b057566f9ee 251 }
jberry 0:9b057566f9ee 252 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 253 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 254 void OS::channel<T, Size, S>::CheckWaiters(TProcessMap& pm)
jberry 0:9b057566f9ee 255 {
jberry 0:9b057566f9ee 256 if(pm)
jberry 0:9b057566f9ee 257 {
jberry 0:9b057566f9ee 258 TProcessMap Timeouted = Kernel.ReadyProcessMap;
jberry 0:9b057566f9ee 259
jberry 0:9b057566f9ee 260 SetPrioTag(Kernel.ReadyProcessMap, pm); // place all waiting processes to the ready map
jberry 0:9b057566f9ee 261 ClrPrioTag(pm, ~Timeouted); // remove waiting processes from the wait map
jberry 0:9b057566f9ee 262 Kernel.Scheduler();
jberry 0:9b057566f9ee 263 }
jberry 0:9b057566f9ee 264 }
jberry 0:9b057566f9ee 265 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 266 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 267 void OS::channel<T, Size, S>::push(const T& item)
jberry 0:9b057566f9ee 268 {
jberry 0:9b057566f9ee 269 TCritSect cs;
jberry 0:9b057566f9ee 270
jberry 0:9b057566f9ee 271 while(!pool.get_free_size())
jberry 0:9b057566f9ee 272 {
jberry 0:9b057566f9ee 273 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 274 SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
jberry 0:9b057566f9ee 275 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 276 Kernel.Scheduler();
jberry 0:9b057566f9ee 277 }
jberry 0:9b057566f9ee 278
jberry 0:9b057566f9ee 279 pool.push_back(item);
jberry 0:9b057566f9ee 280 CheckWaiters(ConsumersProcessMap);
jberry 0:9b057566f9ee 281 }
jberry 0:9b057566f9ee 282 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 283 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 284 void OS::channel<T, Size, S>::push_front(const T& item)
jberry 0:9b057566f9ee 285 {
jberry 0:9b057566f9ee 286 TCritSect cs;
jberry 0:9b057566f9ee 287
jberry 0:9b057566f9ee 288 while(!pool.get_free_size())
jberry 0:9b057566f9ee 289 {
jberry 0:9b057566f9ee 290 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 291 SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map
jberry 0:9b057566f9ee 292 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 293 Kernel.Scheduler();
jberry 0:9b057566f9ee 294 }
jberry 0:9b057566f9ee 295
jberry 0:9b057566f9ee 296 pool.push_front(item);
jberry 0:9b057566f9ee 297 CheckWaiters(ConsumersProcessMap);
jberry 0:9b057566f9ee 298 }
jberry 0:9b057566f9ee 299 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 300 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 301 bool OS::channel<T, Size, S>::pop(T& item, TTimeout timeout)
jberry 0:9b057566f9ee 302 {
jberry 0:9b057566f9ee 303 TCritSect cs;
jberry 0:9b057566f9ee 304
jberry 0:9b057566f9ee 305 if(pool.get_count())
jberry 0:9b057566f9ee 306 {
jberry 0:9b057566f9ee 307 item = pool.pop();
jberry 0:9b057566f9ee 308 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 309 return true;
jberry 0:9b057566f9ee 310 }
jberry 0:9b057566f9ee 311 else
jberry 0:9b057566f9ee 312 {
jberry 0:9b057566f9ee 313 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
jberry 0:9b057566f9ee 314 p->Timeout = timeout;
jberry 0:9b057566f9ee 315
jberry 0:9b057566f9ee 316 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 317 for(;;)
jberry 0:9b057566f9ee 318 {
jberry 0:9b057566f9ee 319 SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
jberry 0:9b057566f9ee 320 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 321 Kernel.Scheduler();
jberry 0:9b057566f9ee 322
jberry 0:9b057566f9ee 323 if(pool.get_count())
jberry 0:9b057566f9ee 324 {
jberry 0:9b057566f9ee 325 p->Timeout = 0;
jberry 0:9b057566f9ee 326 item = pool.pop();
jberry 0:9b057566f9ee 327 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 328 return true;
jberry 0:9b057566f9ee 329 }
jberry 0:9b057566f9ee 330
jberry 0:9b057566f9ee 331 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
jberry 0:9b057566f9ee 332 { // or by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 333
jberry 0:9b057566f9ee 334 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
jberry 0:9b057566f9ee 335 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
jberry 0:9b057566f9ee 336 return false;
jberry 0:9b057566f9ee 337 }
jberry 0:9b057566f9ee 338 }
jberry 0:9b057566f9ee 339 }
jberry 0:9b057566f9ee 340 }
jberry 0:9b057566f9ee 341 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 342 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 343 bool OS::channel<T, Size, S>::pop_back(T& item, TTimeout timeout)
jberry 0:9b057566f9ee 344 {
jberry 0:9b057566f9ee 345 TCritSect cs;
jberry 0:9b057566f9ee 346
jberry 0:9b057566f9ee 347 if(pool.get_count())
jberry 0:9b057566f9ee 348 {
jberry 0:9b057566f9ee 349 item = pool.pop_back();
jberry 0:9b057566f9ee 350 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 351 return true;
jberry 0:9b057566f9ee 352 }
jberry 0:9b057566f9ee 353 else
jberry 0:9b057566f9ee 354 {
jberry 0:9b057566f9ee 355 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
jberry 0:9b057566f9ee 356 p->Timeout = timeout;
jberry 0:9b057566f9ee 357
jberry 0:9b057566f9ee 358 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 359 for(;;)
jberry 0:9b057566f9ee 360 {
jberry 0:9b057566f9ee 361 SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map
jberry 0:9b057566f9ee 362 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 363 Kernel.Scheduler();
jberry 0:9b057566f9ee 364
jberry 0:9b057566f9ee 365 if(pool.get_count())
jberry 0:9b057566f9ee 366 {
jberry 0:9b057566f9ee 367 p->Timeout = 0;
jberry 0:9b057566f9ee 368 item = pool.pop_back();
jberry 0:9b057566f9ee 369 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 370 return true;
jberry 0:9b057566f9ee 371 }
jberry 0:9b057566f9ee 372
jberry 0:9b057566f9ee 373 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
jberry 0:9b057566f9ee 374 { // or by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 375
jberry 0:9b057566f9ee 376 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
jberry 0:9b057566f9ee 377 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
jberry 0:9b057566f9ee 378 return false;
jberry 0:9b057566f9ee 379 }
jberry 0:9b057566f9ee 380 }
jberry 0:9b057566f9ee 381 }
jberry 0:9b057566f9ee 382 }
jberry 0:9b057566f9ee 383 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 384 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 385 void OS::channel<T, Size, S>::flush()
jberry 0:9b057566f9ee 386 {
jberry 0:9b057566f9ee 387 TCritSect cs;
jberry 0:9b057566f9ee 388 pool.flush();
jberry 0:9b057566f9ee 389 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 390 }
jberry 0:9b057566f9ee 391 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 392 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 393 void OS::channel<T, Size, S>::write(const T* data, const S count)
jberry 0:9b057566f9ee 394 {
jberry 0:9b057566f9ee 395 TCritSect cs;
jberry 0:9b057566f9ee 396
jberry 0:9b057566f9ee 397 while(pool.get_free_size() < count)
jberry 0:9b057566f9ee 398 {
jberry 0:9b057566f9ee 399 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 400 SetPrioTag(ProducersProcessMap, PrioTag); // channel does not have enough space, put current process to the wait map
jberry 0:9b057566f9ee 401 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 402 Kernel.Scheduler();
jberry 0:9b057566f9ee 403 }
jberry 0:9b057566f9ee 404
jberry 0:9b057566f9ee 405 pool.write(data, count);
jberry 0:9b057566f9ee 406 CheckWaiters(ConsumersProcessMap);
jberry 0:9b057566f9ee 407 }
jberry 0:9b057566f9ee 408 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 409 template<typename T, word Size, typename S>
jberry 0:9b057566f9ee 410 bool OS::channel<T, Size, S>::read(T* const data, const S count, TTimeout timeout)
jberry 0:9b057566f9ee 411 {
jberry 0:9b057566f9ee 412 TCritSect cs;
jberry 0:9b057566f9ee 413
jberry 0:9b057566f9ee 414 TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
jberry 0:9b057566f9ee 415 p->Timeout = timeout;
jberry 0:9b057566f9ee 416
jberry 0:9b057566f9ee 417 TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
jberry 0:9b057566f9ee 418 while(pool.get_count() < count)
jberry 0:9b057566f9ee 419 {
jberry 0:9b057566f9ee 420 SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map
jberry 0:9b057566f9ee 421 ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
jberry 0:9b057566f9ee 422 Kernel.Scheduler();
jberry 0:9b057566f9ee 423
jberry 0:9b057566f9ee 424 if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired
jberry 0:9b057566f9ee 425 { // or by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 426
jberry 0:9b057566f9ee 427 p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess()
jberry 0:9b057566f9ee 428 ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
jberry 0:9b057566f9ee 429 return false;
jberry 0:9b057566f9ee 430 }
jberry 0:9b057566f9ee 431 }
jberry 0:9b057566f9ee 432
jberry 0:9b057566f9ee 433 p->Timeout = 0;
jberry 0:9b057566f9ee 434 pool.read(data, count);
jberry 0:9b057566f9ee 435 CheckWaiters(ProducersProcessMap);
jberry 0:9b057566f9ee 436
jberry 0:9b057566f9ee 437 return true;
jberry 0:9b057566f9ee 438 }
jberry 0:9b057566f9ee 439 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 440
jberry 0:9b057566f9ee 441 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 442 //
jberry 0:9b057566f9ee 443 // OS::message template
jberry 0:9b057566f9ee 444 //
jberry 0:9b057566f9ee 445 // Function-members implementation
jberry 0:9b057566f9ee 446 //
jberry 0:9b057566f9ee 447 //
jberry 0:9b057566f9ee 448 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 449 void OS::TBaseMessage::sendISR()
jberry 0:9b057566f9ee 450 {
jberry 0:9b057566f9ee 451 TCritSect cs;
jberry 0:9b057566f9ee 452
jberry 0:9b057566f9ee 453 if(ProcessMap)
jberry 0:9b057566f9ee 454 {
jberry 0:9b057566f9ee 455 TProcessMap Timeouted = OS::Kernel.ReadyProcessMap; // Process has it's tag set in ReadyProcessMap if timeout
jberry 0:9b057566f9ee 456 // expired, or it was waked up by OS::ForceWakeUpProcess()
jberry 0:9b057566f9ee 457 if( ProcessMap & ~Timeouted ) // if any process has to be waked up
jberry 0:9b057566f9ee 458 {
jberry 0:9b057566f9ee 459 SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
jberry 0:9b057566f9ee 460 ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map.
jberry 0:9b057566f9ee 461 return;
jberry 0:9b057566f9ee 462 }
jberry 0:9b057566f9ee 463 }
jberry 0:9b057566f9ee 464 NonEmpty = true;
jberry 0:9b057566f9ee 465 }
jberry 0:9b057566f9ee 466 //------------------------------------------------------------------------------
jberry 0:9b057566f9ee 467 #endif // OS_SERVICES_H