Committer:
segundo
Date:
Thu Nov 11 10:03:28 2010 +0000
Revision:
2:bf07aada100e
Parent:
1:172b45dde8dd
Child:
3:ffeede165329

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 2:bf07aada100e 1 /// @file
segundo 0:d7810ff946c1 2 //******************************************************************************
segundo 0:d7810ff946c1 3 //*
segundo 0:d7810ff946c1 4 //* FULLNAME: Single-Chip Microcontroller Real-Time Operating System
segundo 0:d7810ff946c1 5 //*
segundo 0:d7810ff946c1 6 //* NICKNAME: scmRTOS
segundo 0:d7810ff946c1 7 //*
segundo 0:d7810ff946c1 8 //* PURPOSE: OS Kernel Header. Declarations And Definitions
segundo 0:d7810ff946c1 9 //*
segundo 0:d7810ff946c1 10 //* Version: 3.10
segundo 0:d7810ff946c1 11 //*
segundo 0:d7810ff946c1 12 //* $Revision: 256 $
segundo 0:d7810ff946c1 13 //* $Date:: 2010-01-22 #$
segundo 0:d7810ff946c1 14 //*
segundo 0:d7810ff946c1 15 //* Copyright (c) 2003-2010, Harry E. Zhurov
segundo 0:d7810ff946c1 16 //*
segundo 0:d7810ff946c1 17 //* Permission is hereby granted, free of charge, to any person
segundo 0:d7810ff946c1 18 //* obtaining a copy of this software and associated documentation
segundo 0:d7810ff946c1 19 //* files (the "Software"), to deal in the Software without restriction,
segundo 0:d7810ff946c1 20 //* including without limitation the rights to use, copy, modify, merge,
segundo 0:d7810ff946c1 21 //* publish, distribute, sublicense, and/or sell copies of the Software,
segundo 0:d7810ff946c1 22 //* and to permit persons to whom the Software is furnished to do so,
segundo 0:d7810ff946c1 23 //* subject to the following conditions:
segundo 0:d7810ff946c1 24 //*
segundo 0:d7810ff946c1 25 //* The above copyright notice and this permission notice shall be included
segundo 0:d7810ff946c1 26 //* in all copies or substantial portions of the Software.
segundo 0:d7810ff946c1 27 //*
segundo 0:d7810ff946c1 28 //* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
segundo 0:d7810ff946c1 29 //* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
segundo 0:d7810ff946c1 30 //* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
segundo 0:d7810ff946c1 31 //* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
segundo 0:d7810ff946c1 32 //* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
segundo 0:d7810ff946c1 33 //* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
segundo 0:d7810ff946c1 34 //* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
segundo 0:d7810ff946c1 35 //*
segundo 0:d7810ff946c1 36 //* =================================================================
segundo 0:d7810ff946c1 37 //* See http://scmrtos.sourceforge.net for documentation, latest
segundo 0:d7810ff946c1 38 //* information, license and contact details.
segundo 0:d7810ff946c1 39 //* =================================================================
segundo 0:d7810ff946c1 40 //*
segundo 0:d7810ff946c1 41 //*****************************************************************************
segundo 0:d7810ff946c1 42
segundo 0:d7810ff946c1 43 #ifndef OS_KERNEL_H
segundo 0:d7810ff946c1 44 #define OS_KERNEL_H
segundo 0:d7810ff946c1 45
segundo 0:d7810ff946c1 46 #include <stddef.h>
segundo 0:d7810ff946c1 47 #include <commdefs.h>
segundo 0:d7810ff946c1 48 #include <usrlib.h>
segundo 0:d7810ff946c1 49
segundo 0:d7810ff946c1 50 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 51
segundo 0:d7810ff946c1 52 //==============================================================================
segundo 0:d7810ff946c1 53 extern "C" void OS_Start(TStackItem* sp);
segundo 0:d7810ff946c1 54
segundo 0:d7810ff946c1 55 #if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
segundo 0:d7810ff946c1 56 extern "C" void OS_ContextSwitcher(TStackItem** Curr_SP, TStackItem* Next_SP);
segundo 0:d7810ff946c1 57 #else
segundo 0:d7810ff946c1 58 extern "C" TStackItem* OS_ContextSwitchHook(TStackItem* sp);
segundo 0:d7810ff946c1 59 #endif
segundo 0:d7810ff946c1 60
segundo 0:d7810ff946c1 61 //==============================================================================
segundo 0:d7810ff946c1 62
segundo 0:d7810ff946c1 63 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 64 //
segundo 0:d7810ff946c1 65 //
segundo 0:d7810ff946c1 66 // NAME : OS
segundo 0:d7810ff946c1 67 //
segundo 2:bf07aada100e 68 /// PURPOSE : Namespace for all OS stuff
segundo 0:d7810ff946c1 69 //
segundo 0:d7810ff946c1 70 // DESCRIPTION: Includes: Kernel,
segundo 0:d7810ff946c1 71 // Processes,
segundo 0:d7810ff946c1 72 // Mutexes,
segundo 0:d7810ff946c1 73 // Event Flags,
segundo 0:d7810ff946c1 74 // Byte-wide Channels,
segundo 0:d7810ff946c1 75 // Arbitrary-type Channels,
segundo 0:d7810ff946c1 76 // Messages
segundo 0:d7810ff946c1 77 //
segundo 0:d7810ff946c1 78 namespace OS
segundo 0:d7810ff946c1 79 {
segundo 0:d7810ff946c1 80 class TBaseProcess;
segundo 0:d7810ff946c1 81
segundo 0:d7810ff946c1 82 INLINE inline void SetPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm |= PrioTag; }
segundo 0:d7810ff946c1 83 INLINE inline void ClrPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm &= ~PrioTag; }
segundo 0:d7810ff946c1 84
segundo 0:d7810ff946c1 85 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 86 //
segundo 0:d7810ff946c1 87 // NAME : TKernel
segundo 0:d7810ff946c1 88 //
segundo 0:d7810ff946c1 89 /// Implements kernel-level operations such as
segundo 0:d7810ff946c1 90 /// process management, process-level scheduling,
segundo 0:d7810ff946c1 91 /// ISR-level scheduling, system timing.
segundo 0:d7810ff946c1 92 //
segundo 0:d7810ff946c1 93 // DESCRIPTION:
segundo 0:d7810ff946c1 94 //
segundo 0:d7810ff946c1 95 //
segundo 0:d7810ff946c1 96 class TKernel
segundo 0:d7810ff946c1 97 {
segundo 0:d7810ff946c1 98 //-----------------------------------------------------------
segundo 0:d7810ff946c1 99 //
segundo 0:d7810ff946c1 100 // Declarations
segundo 0:d7810ff946c1 101 //
segundo 0:d7810ff946c1 102
segundo 0:d7810ff946c1 103
segundo 0:d7810ff946c1 104 friend class TISRW;
segundo 0:d7810ff946c1 105 friend class TISRW_SS;
segundo 0:d7810ff946c1 106 friend class TBaseProcess;
segundo 0:d7810ff946c1 107 friend class TMutex;
segundo 0:d7810ff946c1 108 friend class TEventFlag;
segundo 0:d7810ff946c1 109 friend class TChannel;
segundo 0:d7810ff946c1 110 friend class TBaseMessage;
segundo 0:d7810ff946c1 111
segundo 0:d7810ff946c1 112 template<typename T, word size, class S> friend class channel;
segundo 0:d7810ff946c1 113 template<typename T> friend class message;
segundo 0:d7810ff946c1 114
segundo 0:d7810ff946c1 115 friend void Run();
segundo 0:d7810ff946c1 116 friend void WakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 117 friend void ForceWakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 118 friend inline bool IsProcessSleeping(const TBaseProcess& p);
segundo 0:d7810ff946c1 119 friend inline bool IsProcessSuspended(const TBaseProcess& p);
segundo 0:d7810ff946c1 120 friend inline dword GetTickCount();
segundo 0:d7810ff946c1 121
segundo 0:d7810ff946c1 122 //-----------------------------------------------------------
segundo 0:d7810ff946c1 123 //
segundo 0:d7810ff946c1 124 // Data
segundo 0:d7810ff946c1 125 //
segundo 0:d7810ff946c1 126 private:
segundo 0:d7810ff946c1 127 byte CurProcPriority;
segundo 0:d7810ff946c1 128 TProcessMap ReadyProcessMap;
segundo 0:d7810ff946c1 129 TBaseProcess* ProcessTable[scmRTOS_PROCESS_COUNT+1];
segundo 0:d7810ff946c1 130 volatile byte ISR_NestCount;
segundo 0:d7810ff946c1 131
segundo 0:d7810ff946c1 132 #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
segundo 0:d7810ff946c1 133 byte SchedProcPriority;
segundo 0:d7810ff946c1 134 #endif
segundo 0:d7810ff946c1 135
segundo 0:d7810ff946c1 136 #if scmRTOS_SYSTEM_TICKS_ENABLE == 1
segundo 0:d7810ff946c1 137 volatile dword SysTickCount;
segundo 0:d7810ff946c1 138 #endif
segundo 0:d7810ff946c1 139
segundo 0:d7810ff946c1 140 //-----------------------------------------------------------
segundo 0:d7810ff946c1 141 //
segundo 0:d7810ff946c1 142 // Functions
segundo 0:d7810ff946c1 143 //
segundo 0:d7810ff946c1 144 public:
segundo 0:d7810ff946c1 145 INLINE TKernel()
segundo 0:d7810ff946c1 146 : CurProcPriority(pr0)
segundo 0:d7810ff946c1 147 , ReadyProcessMap( (1 << (scmRTOS_PROCESS_COUNT + 1)) - 1) // set all processes ready
segundo 0:d7810ff946c1 148 , ISR_NestCount(0)
segundo 0:d7810ff946c1 149 {
segundo 0:d7810ff946c1 150 }
segundo 0:d7810ff946c1 151
segundo 0:d7810ff946c1 152 private:
segundo 0:d7810ff946c1 153 INLINE inline void RegisterProcess(TBaseProcess* const p);
segundo 0:d7810ff946c1 154
segundo 0:d7810ff946c1 155 void Sched();
segundo 0:d7810ff946c1 156 INLINE void Scheduler() { if(ISR_NestCount) return; else Sched(); }
segundo 0:d7810ff946c1 157 INLINE inline void SchedISR();
segundo 0:d7810ff946c1 158
segundo 0:d7810ff946c1 159 #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
segundo 0:d7810ff946c1 160 INLINE inline bool IsContextSwitchDone() const volatile;
segundo 0:d7810ff946c1 161 #endif
segundo 0:d7810ff946c1 162 INLINE void SetProcessReady (const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); SetPrioTag( ReadyProcessMap, PrioTag); }
segundo 0:d7810ff946c1 163 INLINE void SetProcessUnready(const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); ClrPrioTag( ReadyProcessMap, PrioTag); }
segundo 0:d7810ff946c1 164
segundo 0:d7810ff946c1 165 public:
segundo 0:d7810ff946c1 166 INLINE inline void SystemTimer();
segundo 0:d7810ff946c1 167 #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
segundo 0:d7810ff946c1 168 INLINE inline TStackItem* ContextSwitchHook(TStackItem* sp);
segundo 0:d7810ff946c1 169 #endif
segundo 0:d7810ff946c1 170
segundo 0:d7810ff946c1 171 }; // End of TKernel class definition
segundo 0:d7810ff946c1 172 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 173 extern TKernel Kernel;
segundo 0:d7810ff946c1 174
segundo 0:d7810ff946c1 175 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 176 //
segundo 0:d7810ff946c1 177 /// BaseProcess
segundo 0:d7810ff946c1 178 ///
segundo 0:d7810ff946c1 179 /// Implements base class-type for application processes
segundo 0:d7810ff946c1 180 //
segundo 0:d7810ff946c1 181 // DESCRIPTION:
segundo 0:d7810ff946c1 182 //
segundo 0:d7810ff946c1 183 //
segundo 0:d7810ff946c1 184 class TBaseProcess
segundo 0:d7810ff946c1 185 {
segundo 0:d7810ff946c1 186 friend class TKernel;
segundo 0:d7810ff946c1 187 friend class TISRW;
segundo 0:d7810ff946c1 188 friend class TISRW_SS;
segundo 0:d7810ff946c1 189 friend class TEventFlag;
segundo 0:d7810ff946c1 190 friend class TMutex;
segundo 0:d7810ff946c1 191 friend class TBaseMessage;
segundo 0:d7810ff946c1 192
segundo 0:d7810ff946c1 193 template<typename T, word size, class S> friend class channel;
segundo 0:d7810ff946c1 194 template<typename T> friend class message;
segundo 0:d7810ff946c1 195
segundo 0:d7810ff946c1 196
segundo 0:d7810ff946c1 197 friend void Run();
segundo 0:d7810ff946c1 198 friend void WakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 199 friend void ForceWakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 200 friend bool IsProcessSleeping(const TBaseProcess& p);
segundo 0:d7810ff946c1 201 friend bool IsProcessSuspended(const TBaseProcess& p);
segundo 0:d7810ff946c1 202
segundo 0:d7810ff946c1 203 public:
segundo 0:d7810ff946c1 204 #if SEPARATE_RETURN_STACK == 0
segundo 0:d7810ff946c1 205 TBaseProcess( TStackItem* Stack, word stackSize, TPriority pr, void (*exec)() );
segundo 0:d7810ff946c1 206 #else
segundo 0:d7810ff946c1 207 TBaseProcess( TStackItem* Stack, TStackItem* RStack, TPriority pr, void (*exec)() );
segundo 0:d7810ff946c1 208 #endif
segundo 0:d7810ff946c1 209
segundo 0:d7810ff946c1 210 static void Sleep(TTimeout timeout = 0);
segundo 0:d7810ff946c1 211
segundo 0:d7810ff946c1 212 protected:
segundo 0:d7810ff946c1 213 TStackItem* StackPointer;
segundo 0:d7810ff946c1 214 word StackSize;
segundo 0:d7810ff946c1 215 TTimeout Timeout;
segundo 0:d7810ff946c1 216 TPriority Priority;
segundo 0:d7810ff946c1 217 };
segundo 0:d7810ff946c1 218 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 219
segundo 0:d7810ff946c1 220 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 221 //
segundo 0:d7810ff946c1 222 /// process
segundo 0:d7810ff946c1 223 ///
segundo 0:d7810ff946c1 224 /// Implements template for application processes instantiation
segundo 0:d7810ff946c1 225 //
segundo 0:d7810ff946c1 226 // DESCRIPTION:
segundo 0:d7810ff946c1 227 //
segundo 0:d7810ff946c1 228 //
segundo 0:d7810ff946c1 229 #if SEPARATE_RETURN_STACK == 0
segundo 0:d7810ff946c1 230
segundo 0:d7810ff946c1 231 template<TPriority pr, word stack_size>
segundo 0:d7810ff946c1 232 class process : public TBaseProcess
segundo 0:d7810ff946c1 233 {
segundo 0:d7810ff946c1 234 public:
segundo 0:d7810ff946c1 235 INLINE_PROCESS_CTOR process();
segundo 0:d7810ff946c1 236 #ifdef DEBUG_STACK
segundo 0:d7810ff946c1 237 word UsedStackSize();
segundo 0:d7810ff946c1 238 #endif //DEBUG_STACK
segundo 0:d7810ff946c1 239
segundo 0:d7810ff946c1 240 OS_PROCESS static void Exec();
segundo 0:d7810ff946c1 241
segundo 0:d7810ff946c1 242 private:
segundo 0:d7810ff946c1 243 TStackItem Stack[stack_size/sizeof(TStackItem)];
segundo 0:d7810ff946c1 244 };
segundo 0:d7810ff946c1 245
segundo 0:d7810ff946c1 246 template<TPriority pr, word stack_size>
segundo 0:d7810ff946c1 247 OS::process<pr, stack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)]
segundo 0:d7810ff946c1 248 , stack_size // for DEBUG_STACK
segundo 0:d7810ff946c1 249 , pr
segundo 0:d7810ff946c1 250 , reinterpret_cast<void (*)()>(Exec) )
segundo 0:d7810ff946c1 251 {
segundo 0:d7810ff946c1 252 }
segundo 0:d7810ff946c1 253 #ifdef DEBUG_STACK
segundo 1:172b45dde8dd 254 /** Determine stack usage by looking for change from fill constant
segundo 1:172b45dde8dd 255 * @return The stack size used so far
segundo 1:172b45dde8dd 256 */
segundo 0:d7810ff946c1 257 template<TPriority pr, word stack_size>
segundo 0:d7810ff946c1 258 word process<pr,stack_size>::UsedStackSize()
segundo 0:d7810ff946c1 259 {
segundo 0:d7810ff946c1 260 TStackItem* Idx = Stack;
segundo 0:d7810ff946c1 261 while(*(Idx++) == STACK_FILL_CONST);
segundo 0:d7810ff946c1 262 return ((Stack + (StackSize/sizeof(TStackItem))) - Idx)*sizeof(TStackItem);
segundo 0:d7810ff946c1 263 }
segundo 0:d7810ff946c1 264 #endif //DEBUG_STACK
segundo 0:d7810ff946c1 265
segundo 0:d7810ff946c1 266 #else
segundo 0:d7810ff946c1 267
segundo 0:d7810ff946c1 268 template<TPriority pr, word stack_size, word rstack_size>
segundo 0:d7810ff946c1 269 class process : public TBaseProcess
segundo 0:d7810ff946c1 270 {
segundo 0:d7810ff946c1 271 public:
segundo 0:d7810ff946c1 272 INLINE_PROCESS_CTOR process();
segundo 0:d7810ff946c1 273
segundo 0:d7810ff946c1 274 OS_PROCESS static void Exec();
segundo 0:d7810ff946c1 275
segundo 0:d7810ff946c1 276 private:
segundo 0:d7810ff946c1 277 TStackItem Stack [stack_size/sizeof(TStackItem)];
segundo 0:d7810ff946c1 278 TStackItem RStack[rstack_size/sizeof(TStackItem)];
segundo 0:d7810ff946c1 279 };
segundo 0:d7810ff946c1 280
segundo 0:d7810ff946c1 281 template<TPriority pr, word stack_size, word rstack_size>
segundo 0:d7810ff946c1 282 process<pr, stack_size, rstack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)]
segundo 0:d7810ff946c1 283 , &RStack[rstack_size/sizeof(TStackItem)]
segundo 0:d7810ff946c1 284 , pr
segundo 0:d7810ff946c1 285 , reinterpret_cast<void (*)()>(Exec))
segundo 0:d7810ff946c1 286 {
segundo 0:d7810ff946c1 287 }
segundo 0:d7810ff946c1 288
segundo 0:d7810ff946c1 289 #endif
segundo 0:d7810ff946c1 290 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 291
segundo 0:d7810ff946c1 292 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 293 //
segundo 0:d7810ff946c1 294 // Miscellaneous
segundo 0:d7810ff946c1 295 //
segundo 0:d7810ff946c1 296 //
segundo 0:d7810ff946c1 297 INLINE inline void Run();
segundo 0:d7810ff946c1 298 INLINE inline void LockSystemTimer() { TCritSect cs; LOCK_SYSTEM_TIMER(); }
segundo 0:d7810ff946c1 299 INLINE inline void UnlockSystemTimer() { TCritSect cs; UNLOCK_SYSTEM_TIMER(); }
segundo 0:d7810ff946c1 300 void WakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 301 void ForceWakeUpProcess(TBaseProcess& p);
segundo 0:d7810ff946c1 302 INLINE inline void Sleep(TTimeout t = 0) { TBaseProcess::Sleep(t); }
segundo 0:d7810ff946c1 303
segundo 0:d7810ff946c1 304 INLINE inline bool IsProcessSleeping(const TBaseProcess& p)
segundo 0:d7810ff946c1 305 {
segundo 0:d7810ff946c1 306 TCritSect cs;
segundo 0:d7810ff946c1 307 if(p.Timeout)
segundo 0:d7810ff946c1 308 return true;
segundo 0:d7810ff946c1 309 else
segundo 0:d7810ff946c1 310 return false;
segundo 0:d7810ff946c1 311 }
segundo 0:d7810ff946c1 312
segundo 0:d7810ff946c1 313 INLINE inline bool IsProcessSuspended(const TBaseProcess& p)
segundo 0:d7810ff946c1 314 {
segundo 0:d7810ff946c1 315 TCritSect cs;
segundo 0:d7810ff946c1 316 if(Kernel.ReadyProcessMap & GetPrioTag(p.Priority))
segundo 0:d7810ff946c1 317 return false;
segundo 0:d7810ff946c1 318 else
segundo 0:d7810ff946c1 319 return true;
segundo 0:d7810ff946c1 320 }
segundo 0:d7810ff946c1 321 //--------------------------------------------------------------------------
segundo 0:d7810ff946c1 322
segundo 0:d7810ff946c1 323 #if scmRTOS_SYSTEM_TICKS_ENABLE == 1
segundo 0:d7810ff946c1 324 INLINE inline dword GetTickCount() { TCritSect cs; return Kernel.SysTickCount; }
segundo 0:d7810ff946c1 325 #endif
segundo 0:d7810ff946c1 326
segundo 0:d7810ff946c1 327 #if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
segundo 0:d7810ff946c1 328 INLINE_SYS_TIMER_HOOK void SystemTimerUserHook();
segundo 0:d7810ff946c1 329 #endif
segundo 0:d7810ff946c1 330
segundo 0:d7810ff946c1 331 #if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
segundo 0:d7810ff946c1 332 INLINE_CONTEXT_SWITCH_HOOK void ContextSwitchUserHook();
segundo 0:d7810ff946c1 333 #endif
segundo 0:d7810ff946c1 334
segundo 0:d7810ff946c1 335 }
segundo 0:d7810ff946c1 336 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 337
segundo 0:d7810ff946c1 338 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 339 //
segundo 0:d7810ff946c1 340 /// Register Process
segundo 0:d7810ff946c1 341 ///
segundo 0:d7810ff946c1 342 /// Places pointer to process in kernel's process table
segundo 0:d7810ff946c1 343 //
segundo 0:d7810ff946c1 344 void OS::TKernel::RegisterProcess(OS::TBaseProcess* const p)
segundo 0:d7810ff946c1 345 {
segundo 0:d7810ff946c1 346 ProcessTable[p->Priority] = p;
segundo 0:d7810ff946c1 347 }
segundo 0:d7810ff946c1 348 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 349 //
segundo 0:d7810ff946c1 350 /// System Timer Implementation
segundo 0:d7810ff946c1 351 ///
segundo 0:d7810ff946c1 352 /// Performs process's timeouts checking and
segundo 0:d7810ff946c1 353 /// moving processes to ready-to-run state
segundo 0:d7810ff946c1 354 //
segundo 0:d7810ff946c1 355 void OS::TKernel::SystemTimer()
segundo 0:d7810ff946c1 356 {
segundo 0:d7810ff946c1 357 SYS_TIMER_CRIT_SECT();
segundo 0:d7810ff946c1 358 #if scmRTOS_SYSTEM_TICKS_ENABLE == 1
segundo 0:d7810ff946c1 359 SysTickCount++;
segundo 0:d7810ff946c1 360 #endif
segundo 0:d7810ff946c1 361
segundo 0:d7810ff946c1 362 #if scmRTOS_PRIORITY_ORDER == 0
segundo 0:d7810ff946c1 363 const byte BaseIndex = 0;
segundo 0:d7810ff946c1 364 #else
segundo 0:d7810ff946c1 365 const byte BaseIndex = 1;
segundo 0:d7810ff946c1 366 #endif
segundo 0:d7810ff946c1 367
segundo 0:d7810ff946c1 368 for(byte i = BaseIndex; i < (scmRTOS_PROCESS_COUNT + BaseIndex); i++)
segundo 0:d7810ff946c1 369 {
segundo 0:d7810ff946c1 370 TBaseProcess* p = ProcessTable[i];
segundo 0:d7810ff946c1 371
segundo 0:d7810ff946c1 372 if(p->Timeout > 0)
segundo 0:d7810ff946c1 373 {
segundo 0:d7810ff946c1 374 if(--p->Timeout == 0)
segundo 0:d7810ff946c1 375 {
segundo 0:d7810ff946c1 376 SetProcessReady(p->Priority);
segundo 0:d7810ff946c1 377 }
segundo 0:d7810ff946c1 378 }
segundo 0:d7810ff946c1 379 }
segundo 0:d7810ff946c1 380 }
segundo 0:d7810ff946c1 381 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 382 //
segundo 0:d7810ff946c1 383 /// ISR optimized scheduler
segundo 0:d7810ff946c1 384 ///
segundo 0:d7810ff946c1 385 /// !!! IMPORTANT: This function must be call from ISR services only !!!
segundo 0:d7810ff946c1 386 //
segundo 0:d7810ff946c1 387 //
segundo 0:d7810ff946c1 388 #if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
segundo 0:d7810ff946c1 389 void OS::TKernel::SchedISR()
segundo 0:d7810ff946c1 390 {
segundo 0:d7810ff946c1 391 byte NextPrty = GetHighPriority(ReadyProcessMap);
segundo 0:d7810ff946c1 392 if(NextPrty != CurProcPriority)
segundo 0:d7810ff946c1 393 {
segundo 0:d7810ff946c1 394 TStackItem* Next_SP = ProcessTable[NextPrty]->StackPointer;
segundo 0:d7810ff946c1 395 TStackItem** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer);
segundo 0:d7810ff946c1 396 CurProcPriority = NextPrty;
segundo 0:d7810ff946c1 397 OS_ContextSwitcher(Curr_SP_addr, Next_SP);
segundo 0:d7810ff946c1 398 }
segundo 0:d7810ff946c1 399 }
segundo 0:d7810ff946c1 400 #else
segundo 0:d7810ff946c1 401 void OS::TKernel::SchedISR()
segundo 0:d7810ff946c1 402 {
segundo 0:d7810ff946c1 403 byte NextPrty = GetHighPriority(ReadyProcessMap);
segundo 0:d7810ff946c1 404 if(NextPrty != CurProcPriority)
segundo 0:d7810ff946c1 405 {
segundo 0:d7810ff946c1 406 SchedProcPriority = NextPrty;
segundo 0:d7810ff946c1 407 RaiseContextSwitch();
segundo 0:d7810ff946c1 408 }
segundo 0:d7810ff946c1 409 }
segundo 0:d7810ff946c1 410 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 411 bool OS::TKernel::IsContextSwitchDone() const volatile
segundo 0:d7810ff946c1 412 {
segundo 0:d7810ff946c1 413 byte cur = CurProcPriority; ///< reading to temporary vars is performed due to
segundo 0:d7810ff946c1 414 byte sched = SchedProcPriority; ///< suppress warning about order of volatile access
segundo 0:d7810ff946c1 415 return cur == sched;
segundo 0:d7810ff946c1 416 }
segundo 0:d7810ff946c1 417 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 418 TStackItem* OS::TKernel::ContextSwitchHook(TStackItem* sp)
segundo 0:d7810ff946c1 419 {
segundo 0:d7810ff946c1 420 ProcessTable[CurProcPriority]->StackPointer = sp;
segundo 0:d7810ff946c1 421 sp = ProcessTable[SchedProcPriority]->StackPointer;
segundo 0:d7810ff946c1 422
segundo 0:d7810ff946c1 423 #if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
segundo 0:d7810ff946c1 424 ContextSwitchUserHook();
segundo 0:d7810ff946c1 425 #endif
segundo 0:d7810ff946c1 426
segundo 0:d7810ff946c1 427 CurProcPriority = SchedProcPriority;
segundo 0:d7810ff946c1 428 return sp;
segundo 0:d7810ff946c1 429 }
segundo 0:d7810ff946c1 430 //------------------------------------------------------------------------------
segundo 0:d7810ff946c1 431 #endif // scmRTOS_CONTEXT_SWITCH_SCHEME
segundo 0:d7810ff946c1 432
segundo 0:d7810ff946c1 433 //-----------------------------------------------------------------------------
segundo 0:d7810ff946c1 434 /// Start Operation
segundo 0:d7810ff946c1 435 INLINE inline void OS::Run()
segundo 0:d7810ff946c1 436 {
segundo 0:d7810ff946c1 437 TStackItem* sp = Kernel.ProcessTable[pr0]->StackPointer;
segundo 0:d7810ff946c1 438 OS_Start(sp);
segundo 0:d7810ff946c1 439 }
segundo 0:d7810ff946c1 440
segundo 0:d7810ff946c1 441 #include <OS_Services.h>
segundo 0:d7810ff946c1 442
segundo 0:d7810ff946c1 443 #endif // OS_KERNEL_H
segundo 0:d7810ff946c1 444