![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
LED Fork
Fork of RtosTest by
Diff: scmRTOS/Common/OS_Kernel.h
- Revision:
- 1:a33478a10fd0
- Parent:
- 0:331db0b44b67
--- a/scmRTOS/Common/OS_Kernel.h Tue Sep 21 19:48:05 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,439 +0,0 @@ -//****************************************************************************** -//* -//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System -//* -//* NICKNAME: scmRTOS -//* -//* PURPOSE: OS Kernel Header. Declarations And Definitions -//* -//* Version: 3.10 -//* -//* $Revision: 256 $ -//* $Date:: 2010-01-22 #$ -//* -//* Copyright (c) 2003-2010, Harry E. Zhurov -//* -//* Permission is hereby granted, free of charge, to any person -//* obtaining a copy of this software and associated documentation -//* files (the "Software"), to deal in the Software without restriction, -//* including without limitation the rights to use, copy, modify, merge, -//* publish, distribute, sublicense, and/or sell copies of the Software, -//* and to permit persons to whom the Software is furnished to do so, -//* subject to the following conditions: -//* -//* The above copyright notice and this permission notice shall be included -//* in all copies or substantial portions of the Software. -//* -//* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -//* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -//* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -//* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -//* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -//* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH -//* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -//* -//* ================================================================= -//* See http://scmrtos.sourceforge.net for documentation, latest -//* information, license and contact details. -//* ================================================================= -//* -//***************************************************************************** - -#ifndef OS_KERNEL_H -#define OS_KERNEL_H - -#include <stddef.h> -#include <commdefs.h> -#include <usrlib.h> - -//------------------------------------------------------------------------------ - -//============================================================================== -extern "C" void OS_Start(TStackItem* sp); - -#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0 - extern "C" void OS_ContextSwitcher(TStackItem** Curr_SP, TStackItem* Next_SP); -#else - extern "C" TStackItem* OS_ContextSwitchHook(TStackItem* sp); -#endif - -//============================================================================== - -//------------------------------------------------------------------------------ -// -// -// NAME : OS -// -// PURPOSE : Namespace for all OS stuff -// -// DESCRIPTION: Includes: Kernel, -// Processes, -// Mutexes, -// Event Flags, -// Byte-wide Channels, -// Arbitrary-type Channels, -// Messages -// -namespace OS -{ - class TBaseProcess; - - INLINE inline void SetPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm |= PrioTag; } - INLINE inline void ClrPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm &= ~PrioTag; } - - //-------------------------------------------------------------------------- - // - // NAME : TKernel - // - /// Implements kernel-level operations such as - /// process management, process-level scheduling, - /// ISR-level scheduling, system timing. - // - // DESCRIPTION: - // - // - class TKernel - { - //----------------------------------------------------------- - // - // Declarations - // - - - friend class TISRW; - friend class TISRW_SS; - friend class TBaseProcess; - friend class TMutex; - friend class TEventFlag; - friend class TChannel; - friend class TBaseMessage; - - template<typename T, word size, class S> friend class channel; - template<typename T> friend class message; - - friend void Run(); - friend void WakeUpProcess(TBaseProcess& p); - friend void ForceWakeUpProcess(TBaseProcess& p); - friend inline bool IsProcessSleeping(const TBaseProcess& p); - friend inline bool IsProcessSuspended(const TBaseProcess& p); - friend inline dword GetTickCount(); - - //----------------------------------------------------------- - // - // Data - // - private: - byte CurProcPriority; - TProcessMap ReadyProcessMap; - TBaseProcess* ProcessTable[scmRTOS_PROCESS_COUNT+1]; - volatile byte ISR_NestCount; - - #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 - byte SchedProcPriority; - #endif - - #if scmRTOS_SYSTEM_TICKS_ENABLE == 1 - volatile dword SysTickCount; - #endif - - //----------------------------------------------------------- - // - // Functions - // - public: - INLINE TKernel() - : CurProcPriority(pr0) - , ReadyProcessMap( (1 << (scmRTOS_PROCESS_COUNT + 1)) - 1) // set all processes ready - , ISR_NestCount(0) - { - } - - private: - INLINE inline void RegisterProcess(TBaseProcess* const p); - - void Sched(); - INLINE void Scheduler() { if(ISR_NestCount) return; else Sched(); } - INLINE inline void SchedISR(); - - #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 - INLINE inline bool IsContextSwitchDone() const volatile; - #endif - INLINE void SetProcessReady (const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); SetPrioTag( ReadyProcessMap, PrioTag); } - INLINE void SetProcessUnready(const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); ClrPrioTag( ReadyProcessMap, PrioTag); } - - public: - INLINE inline void SystemTimer(); - #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 - INLINE inline TStackItem* ContextSwitchHook(TStackItem* sp); - #endif - - }; // End of TKernel class definition - //-------------------------------------------------------------------------- - extern TKernel Kernel; - - //-------------------------------------------------------------------------- - // - /// BaseProcess - /// - /// Implements base class-type for application processes - // - // DESCRIPTION: - // - // - class TBaseProcess - { - friend class TKernel; - friend class TISRW; - friend class TISRW_SS; - friend class TEventFlag; - friend class TMutex; - friend class TBaseMessage; - - template<typename T, word size, class S> friend class channel; - template<typename T> friend class message; - - - friend void Run(); - friend void WakeUpProcess(TBaseProcess& p); - friend void ForceWakeUpProcess(TBaseProcess& p); - friend bool IsProcessSleeping(const TBaseProcess& p); - friend bool IsProcessSuspended(const TBaseProcess& p); - - public: - #if SEPARATE_RETURN_STACK == 0 - TBaseProcess( TStackItem* Stack, word stack_size, TPriority pr, void (*exec)() ); - #else - TBaseProcess( TStackItem* Stack, TStackItem* RStack, TPriority pr, void (*exec)() ); - #endif - - static void Sleep(TTimeout timeout = 0); - - protected: - TStackItem* StackPointer; - word StackSize; - TTimeout Timeout; - TPriority Priority; - - }; - //-------------------------------------------------------------------------- - - //-------------------------------------------------------------------------- - // - /// process - /// - /// Implements template for application processes instantiation - // - // DESCRIPTION: - // - // - #if SEPARATE_RETURN_STACK == 0 - - template<TPriority pr, word stack_size> - class process : public TBaseProcess - { - public: - INLINE_PROCESS_CTOR process(); -#ifdef DEBUG_STACK -word UsedStackSize(); -#endif //DEBUG_STACK - OS_PROCESS static void Exec(); - - private: - TStackItem Stack[stack_size/sizeof(TStackItem)]; - }; - - template<TPriority pr, word stack_size> - OS::process<pr, stack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)] - , stack_size // debug - , pr - , reinterpret_cast<void (*)()>(Exec) ) - { - } -#ifdef DEBUG_STACK -template<TPriority pr, word stack_size> -word process<pr,stack_size>::UsedStackSize() -{ -TStackItem* Idx = Stack; -while(*(Idx++) == STACK_FILL_CONST); -return ((Stack + (StackSize/sizeof(TStackItem))) - Idx)*sizeof(TStackItem); -} -#endif //DEBUG_STACK - #else - - template<TPriority pr, word stack_size, word rstack_size> - class process : public TBaseProcess - { - public: - INLINE_PROCESS_CTOR process(); - - OS_PROCESS static void Exec(); - - private: - TStackItem Stack [stack_size/sizeof(TStackItem)]; - TStackItem RStack[rstack_size/sizeof(TStackItem)]; - }; - - template<TPriority pr, word stack_size, word rstack_size> - process<pr, stack_size, rstack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)] - , &RStack[rstack_size/sizeof(TStackItem)] - , pr - , reinterpret_cast<void (*)()>(Exec)) - { - } - - #endif - //-------------------------------------------------------------------------- - - //-------------------------------------------------------------------------- - // - // Miscellaneous - // - // - INLINE inline void Run(); - INLINE inline void LockSystemTimer() { TCritSect cs; LOCK_SYSTEM_TIMER(); } - INLINE inline void UnlockSystemTimer() { TCritSect cs; UNLOCK_SYSTEM_TIMER(); } - void WakeUpProcess(TBaseProcess& p); - void ForceWakeUpProcess(TBaseProcess& p); - INLINE inline void Sleep(TTimeout t = 0) { TBaseProcess::Sleep(t); } - - INLINE inline bool IsProcessSleeping(const TBaseProcess& p) - { - TCritSect cs; - if(p.Timeout) - return true; - else - return false; - } - - INLINE inline bool IsProcessSuspended(const TBaseProcess& p) - { - TCritSect cs; - if(Kernel.ReadyProcessMap & GetPrioTag(p.Priority)) - return false; - else - return true; - } - //-------------------------------------------------------------------------- - -#if scmRTOS_SYSTEM_TICKS_ENABLE == 1 - INLINE inline dword GetTickCount() { TCritSect cs; return Kernel.SysTickCount; } -#endif - -#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 - INLINE_SYS_TIMER_HOOK void SystemTimerUserHook(); -#endif - -#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1 - INLINE_CONTEXT_SWITCH_HOOK void ContextSwitchUserHook(); -#endif - -} -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// -/// Register Process -/// -/// Places pointer to process in kernel's process table -// -void OS::TKernel::RegisterProcess(OS::TBaseProcess* const p) -{ - ProcessTable[p->Priority] = p; -} -//------------------------------------------------------------------------------ -// -/// System Timer Implementation -/// -/// Performs process's timeouts checking and -/// moving processes to ready-to-run state -// -void OS::TKernel::SystemTimer() -{ - SYS_TIMER_CRIT_SECT(); -#if scmRTOS_SYSTEM_TICKS_ENABLE == 1 - SysTickCount++; -#endif - -#if scmRTOS_PRIORITY_ORDER == 0 - const byte BaseIndex = 0; -#else - const byte BaseIndex = 1; -#endif - - for(byte i = BaseIndex; i < (scmRTOS_PROCESS_COUNT + BaseIndex); i++) - { - TBaseProcess* p = ProcessTable[i]; - - if(p->Timeout > 0) - { - if(--p->Timeout == 0) - { - SetProcessReady(p->Priority); - } - } - } -} -//------------------------------------------------------------------------------ -// -/// ISR optimized scheduler -/// -/// !!! IMPORTANT: This function must be call from ISR services only !!! -// -// -#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0 -void OS::TKernel::SchedISR() -{ - byte NextPrty = GetHighPriority(ReadyProcessMap); - if(NextPrty != CurProcPriority) - { - TStackItem* Next_SP = ProcessTable[NextPrty]->StackPointer; - TStackItem** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer); - CurProcPriority = NextPrty; - OS_ContextSwitcher(Curr_SP_addr, Next_SP); - } -} -#else -void OS::TKernel::SchedISR() -{ - byte NextPrty = GetHighPriority(ReadyProcessMap); - if(NextPrty != CurProcPriority) - { - SchedProcPriority = NextPrty; - RaiseContextSwitch(); - } -} -//------------------------------------------------------------------------------ -bool OS::TKernel::IsContextSwitchDone() const volatile -{ - byte cur = CurProcPriority; ///< reading to temporary vars is performed due to - byte sched = SchedProcPriority; ///< suppress warning about order of volatile access - return cur == sched; -} -//------------------------------------------------------------------------------ -TStackItem* OS::TKernel::ContextSwitchHook(TStackItem* sp) -{ - ProcessTable[CurProcPriority]->StackPointer = sp; - sp = ProcessTable[SchedProcPriority]->StackPointer; - -#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1 - ContextSwitchUserHook(); -#endif - - CurProcPriority = SchedProcPriority; - return sp; -} -//------------------------------------------------------------------------------ -#endif // scmRTOS_CONTEXT_SWITCH_SCHEME - -//----------------------------------------------------------------------------- -/// Start Operation -INLINE inline void OS::Run() -{ - TStackItem* sp = Kernel.ProcessTable[pr0]->StackPointer; - OS_Start(sp); -} - -#include <OS_Services.h> - -#endif // OS_KERNEL_H -