Quick and dirty port of scmRTOS demo to mbed 1768. scmRTOS is a small RTOS written using C++. Offers (static) processes, critical sections, mutexes, messages, channels.
Revision 0:a405220cf420, committed 2010-09-09
- Comitter:
- igorsk
- Date:
- Thu Sep 09 21:19:01 2010 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,142 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: RVCT (ARM) +//* +//* PURPOSE: Port Test File +//* +//* Version: 3.10 +//* +//* $Revision: 196 $ +//* $Date:: 2010-09-09 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* mbed port by Igor Skochinsky + +#include <mbed.h> +#include <scmRTOS.h> + +//--------------------------------------------------------------------------- +// +// Process types +// +typedef OS::process<OS::pr0, 300> TProc1; +typedef OS::process<OS::pr1, 300> TProc2; +typedef OS::process<OS::pr2, 300> TProc3; +//--------------------------------------------------------------------------- +// +// Process objects +// +TProc1 Proc1; +TProc2 Proc2; +TProc3 Proc3; +//--------------------------------------------------------------------------- +// +// IO Pins +// +DigitalOut led1(LED1); +DigitalOut led2(LED2); + +//--------------------------------------------------------------------------- +// +// Event Flags to test +// +OS::TEventFlag ef; +OS::TEventFlag timerEvent; + +//--------------------------------------------------------------------------- +// +int main() +{ + // configure IO pins + led1.write(0); + led2.write(0); + + // run + OS::Run(); +} + +//--------------------------------------------------------------------------- +template<> OS_PROCESS void TProc1::Exec() +{ + for(;;) + { + ef.Wait(); + printf("e\n"); + led1.write(0); + } +} + +//--------------------------------------------------------------------------- +template<> OS_PROCESS void TProc2::Exec() +{ + for(;;) + { + timerEvent.Wait(); + printf("t\n"); + Sleep(5000); + led2.write(0); + } +} + +//--------------------------------------------------------------------------- +template<> OS_PROCESS void TProc3::Exec() +{ + for (;;) + { + led1.write(1); + Sleep(5000); + ef.Signal(); + Sleep(5000); + } +} + +//--------------------------------------------------------------------------- +void OS::SystemTimerUserHook() +{ + static int cnt=0; + if (++cnt == 2000) + { + cnt = 0; + led2.write(1); + timerEvent.SignalISR(); + } +} + +//--------------------------------------------------------------------------- +void OS::IdleProcessUserHook() +{ + __WFI(); +} +//-----------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/OS_Kernel.cpp Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,115 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: OS Kernel Source +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** + +#include "scmRTOS.h" + +using namespace OS; +//------------------------------------------------------------------------------ +OS::TKernel OS::Kernel; + +//------------------------------------------------------------------------------ +#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0 +void TKernel::Sched() +{ + 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 TKernel::Sched() +{ + byte NextPrty = GetHighPriority(ReadyProcessMap); + if(NextPrty != CurProcPriority) + { + SchedProcPriority = NextPrty; + + RaiseContextSwitch(); + do + { + EnableContextSwitch(); + DUMMY_INSTR(); + DisableContextSwitch(); + } + while(!IsContextSwitchDone()); + } +} +//------------------------------------------------------------------------------ +TStackItem* OS_ContextSwitchHook(TStackItem* sp) { return OS::Kernel.ContextSwitchHook(sp); } +//------------------------------------------------------------------------------ +#endif // scmRTOS_CONTEXT_SWITCH_SCHEME +//------------------------------------------------------------------------------ +void TBaseProcess::Sleep(TTimeout timeout) +{ + TCritSect cs; + + Kernel.ProcessTable[Kernel.CurProcPriority]->Timeout = timeout; + Kernel.SetProcessUnready(Kernel.CurProcPriority); + Kernel.Scheduler(); +} +//------------------------------------------------------------------------------ +void OS::WakeUpProcess(TBaseProcess& p) +{ + TCritSect cs; + + if(p.Timeout) + { + p.Timeout = 0; + Kernel.SetProcessReady(p.Priority); + Kernel.Scheduler(); + } +} +//------------------------------------------------------------------------------ +void OS::ForceWakeUpProcess(TBaseProcess& p) +{ + TCritSect cs; + + p.Timeout = 0; + Kernel.SetProcessReady(p.Priority); + Kernel.Scheduler(); +} +//------------------------------------------------------------------------------ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/OS_Kernel.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,426 @@ +//****************************************************************************** +//* +//* 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, TPriority pr, void (*exec)() ); + #else + TBaseProcess( TStackItem* Stack, TStackItem* RStack, TPriority pr, void (*exec)() ); + #endif + + static void Sleep(TTimeout timeout = 0); + + protected: + TStackItem* StackPointer; + 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(); + + 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)] + , pr + , reinterpret_cast<void (*)()>(Exec) ) + { + } + + #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 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/OS_Services.cpp Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,298 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: OS Services Source +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** + +#include "scmRTOS.h" + +using namespace OS; + +//------------------------------------------------------------------------------ +// +// +// TEventFlag +// +// +bool OS::TEventFlag::Wait(TTimeout timeout) +{ + TCritSect cs; + + if(Value) // if flag already signaled + { + Value = efOff; // clear flag + return true; + } + else + { + TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; + p->Timeout = timeout; + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + + SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + + Kernel.Scheduler(); + + p->Timeout = 0; + + if( !(ProcessMap & PrioTag) ) // if waked up by signal() or signal_ISR() + return true; + + ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by + return false; // OS::ForceWakeUpProcess(), remove process from the wait map + } +} +//------------------------------------------------------------------------------ +void OS::TEventFlag::Signal() +{ + TCritSect cs; + if(ProcessMap) // if any process waits for event + { + TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired + // or it was waked up by OS::ForceWakeUpProcess() + + if( ProcessMap & ~Timeouted ) // if any process has to be waked up + { + SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map + ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. + // Used to check that process waked up by signal() or signalISR() + // and not by timeout or OS::ForceWakeUpProcess() + Kernel.Scheduler(); + return; + } + } + Value = efOn; +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// +// +// TMutex +// +// +void OS::TMutex::Lock() +{ + TCritSect cs; + + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + while(ValueTag) + { + SetPrioTag(ProcessMap, PrioTag); // mutex already locked by another process, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + + Kernel.Scheduler(); + } + ValueTag = PrioTag; // mutex has been successfully locked +} +//------------------------------------------------------------------------------ +void OS::TMutex::Unlock() +{ + TCritSect cs; + + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + if(ValueTag != PrioTag) return; // the only process that had locked mutex can unlock the mutex + ValueTag = 0; + if(ProcessMap) + { + byte pr = GetHighPriority(ProcessMap); + PrioTag = GetPrioTag(pr); + ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map + SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map + Kernel.Scheduler(); + } +} +//------------------------------------------------------------------------------ +void OS::TMutex::UnlockISR() +{ + TCritSect cs; + + ValueTag = 0; + if(ProcessMap) + { + byte pr = GetHighPriority(ProcessMap); + TProcessMap PrioTag = GetPrioTag(pr); + ClrPrioTag(ProcessMap, PrioTag); // remove next ready process from the wait map + SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map + } +} +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// +// +// TChannel +// +// +void OS::TChannel::CheckWaiters(TProcessMap& pm) +{ + if(pm) + { + byte pr = GetHighPriority(pm); + TProcessMap PrioTag = GetPrioTag(pr); + ClrPrioTag(pm, PrioTag); // remove next ready process from the wait map + SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map + Kernel.Scheduler(); + } +} +//------------------------------------------------------------------------------ +void OS::TChannel::Push(byte x) +{ + TCritSect cs; + + while (!Cbuf.get_free_size()) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag (ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); // wait until waked-up by Pop() or Read() + } + + Cbuf.put(x); + CheckWaiters(ConsumersProcessMap); +} +//------------------------------------------------------------------------------ +byte OS::TChannel::Pop() +{ + TCritSect cs; + byte x; + + while(!Cbuf.get_count()) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); // wait until waked up by Push() or Write() + } + x = Cbuf.get(); + CheckWaiters(ProducersProcessMap); + return x; +} +//------------------------------------------------------------------------------ +void OS::TChannel::Write(const byte* data, const byte count) +{ + TCritSect cs; + + while(Cbuf.get_free_size() < count) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ProducersProcessMap, PrioTag); // channel has not enough space, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); // wait until waked up by Read() or Pop() + } + + Cbuf.write(data, count); + CheckWaiters(ConsumersProcessMap); +} +//------------------------------------------------------------------------------ +void OS::TChannel::Read(byte* const data, const byte count) +{ + TCritSect cs; + + while(Cbuf.get_count() < count) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); // wait until waked up by Write() or Push() + } + + Cbuf.read(data, count); + CheckWaiters(ProducersProcessMap); +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// +// OS::message template +// +// Function-members implementation +// +// +//------------------------------------------------------------------------------ +bool OS::TBaseMessage::wait(TTimeout timeout) +{ + TCritSect cs; + + if(NonEmpty) // message alredy send + { + NonEmpty = false; + return true; + } + else + { + TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; + p->Timeout = timeout; + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + + SetPrioTag(ProcessMap, PrioTag); // put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); // wait until wake up + + p->Timeout = 0; + if( !(ProcessMap & PrioTag) ) // if waked up by send() or sendISR() + return true; + + ClrPrioTag(ProcessMap, PrioTag); // otherwise waked up by timeout or by + return false; // OS::ForceWakeUpProcess(), remove process from wait map + } +} +//------------------------------------------------------------------------------ +void OS::TBaseMessage::send() +{ + TCritSect cs; + + if(ProcessMap) + { + TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout expired, + // or it was waked up by OS::ForceWakeUpProcess() + if( ProcessMap & ~Timeouted ) // if any process has to be waked up + { + SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map + ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. + Kernel.Scheduler(); + return; + } + } + + NonEmpty = true; +} +//------------------------------------------------------------------------------ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/OS_Services.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,467 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: OS Services 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_SERVICES_H +#define OS_SERVICES_H + +namespace OS +{ + //-------------------------------------------------------------------------- + // + // NAME : Mutex + // + /// Binary semaphore for support of mutual exclusion + // + // DESCRIPTION: + // + // + class TMutex + { + public: + INLINE TMutex() : ProcessMap(0), ValueTag(0) { } + void Lock(); + void Unlock(); + void UnlockISR(); + + INLINE bool LockSoftly() { TCritSect cs; if(ValueTag) return false; else Lock(); return true; } + INLINE bool IsLocked() const { TCritSect cs; if(ValueTag) return true; else return false; } + + private: + TProcessMap ProcessMap; + TProcessMap ValueTag; + + }; + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // + /// Event Flag + /// + /// Intended for processes synchronization and + /// event notification one (or more) process by another + // + // DESCRIPTION: + // + // + class TEventFlag + { + public: + enum TValue { efOn = 1, efOff= 0 }; // prefix 'ef' means: "Event Flag" + + public: + INLINE TEventFlag(TValue init_val = efOff) : ProcessMap(0), Value(init_val) { } + + bool Wait(TTimeout timeout = 0); + void Signal(); + INLINE void Clear() { TCritSect cs; Value = efOff; } + INLINE inline void SignalISR(); + INLINE bool IsSignaled() { TCritSect cs; if(Value == efOn) return true; else return false; } + + private: + TProcessMap ProcessMap; + TValue Value; + }; + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // + /// TChannel + /// + /// Byte-wide data channel for transferring "raw" data + // + // DESCRIPTION: + // + // + class TChannel + { + public: + INLINE TChannel(byte* buf, byte size) : Cbuf(buf, size) { } + void Push(byte x); + byte Pop(); + void Write(const byte* data, const byte count); + void Read(byte* const data, const byte count); + + INLINE byte GetCount() const { TCritSect cs; return Cbuf.get_count(); } + + private: + TProcessMap ProducersProcessMap; + TProcessMap ConsumersProcessMap; + usr::TCbuf Cbuf; + + private: + void CheckWaiters(TProcessMap& pm); + }; + //-------------------------------------------------------------------------- + + + //-------------------------------------------------------------------------- + // + // NAME : channel + // + // PURPOSE : Data channel for transferring data + // objects of arbitrary type + // + // DESCRIPTION: + // + // + template<typename T, word Size, typename S = byte> + /// channel + /// + /// Data channel for transferring data objects of arbitrary type + class channel + { + public: + INLINE channel() : ProducersProcessMap(0) + , ConsumersProcessMap(0) + , pool() + { + } + + //---------------------------------------------------------------- + // + // Data transfer functions + // + void write(const T* data, const S cnt); + bool read (T* const data, const S cnt, TTimeout timeout = 0); + + void push (const T& item); + void push_front(const T& item); + + bool pop (T& item, TTimeout timeout = 0); + bool pop_back(T& item, TTimeout timeout = 0); + + + //---------------------------------------------------------------- + // + // Service functions + // + INLINE S get_count() const { TCritSect cs; return pool.get_count(); } + INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); } + void flush(); + //const T& operator[](const S index) { TCritSect cs; return pool[index]; } + + + private: + TProcessMap ProducersProcessMap; + TProcessMap ConsumersProcessMap; + usr::ring_buffer<T, Size, S> pool; + + private: + void CheckWaiters(TProcessMap& pm); + }; + + //-------------------------------------------------------------------------- + + //-------------------------------------------------------------------------- + // + /// message + /// + /// Template for messages + // + // DESCRIPTION: + // + // + class TBaseMessage + { + public: + INLINE TBaseMessage() : ProcessMap(0), NonEmpty(false) { } + + bool wait (TTimeout timeout = 0); + void send(); + INLINE inline void sendISR(); + INLINE bool is_non_empty() const { TCritSect cs; return NonEmpty; } + INLINE void reset () { TCritSect cs; NonEmpty = false; } + + private: + TProcessMap ProcessMap; + bool NonEmpty; + }; + //-------------------------------------------------------------------------- + template<typename T> + class message : public TBaseMessage + { + public: + INLINE message() : TBaseMessage() { } + INLINE const T& operator=(const T& msg) { TCritSect cs; Msg = msg; return Msg; } + INLINE operator T() const { TCritSect cs; return Msg; } + + private: + T Msg; + }; + //-------------------------------------------------------------------------- +} +//------------------------------------------------------------------------------ +// +// Function-members implementation +// +//------------------------------------------------------------------------------ +void OS::TEventFlag::SignalISR() +{ + TCritSect cs; + if(ProcessMap) // if any process waits for event + { + TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout + // expired, or it was waked up by OS::ForceWakeUpProcess() + if( ProcessMap & ~Timeouted ) // if any process has to be waked up + { + SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map + ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. + return; + } + } + Value = efOn; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void OS::channel<T, Size, S>::CheckWaiters(TProcessMap& pm) +{ + if(pm) + { + TProcessMap Timeouted = Kernel.ReadyProcessMap; + + SetPrioTag(Kernel.ReadyProcessMap, pm); // place all waiting processes to the ready map + ClrPrioTag(pm, ~Timeouted); // remove waiting processes from the wait map + Kernel.Scheduler(); + } +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void OS::channel<T, Size, S>::push(const T& item) +{ + TCritSect cs; + + while(!pool.get_free_size()) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + } + + pool.push_back(item); + CheckWaiters(ConsumersProcessMap); +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void OS::channel<T, Size, S>::push_front(const T& item) +{ + TCritSect cs; + + while(!pool.get_free_size()) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ProducersProcessMap, PrioTag); // channel is full, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + } + + pool.push_front(item); + CheckWaiters(ConsumersProcessMap); +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +bool OS::channel<T, Size, S>::pop(T& item, TTimeout timeout) +{ + TCritSect cs; + + if(pool.get_count()) + { + item = pool.pop(); + CheckWaiters(ProducersProcessMap); + return true; + } + else + { + TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; + p->Timeout = timeout; + + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + for(;;) + { + SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + + if(pool.get_count()) + { + p->Timeout = 0; + item = pool.pop(); + CheckWaiters(ProducersProcessMap); + return true; + } + + if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired + { // or by OS::ForceWakeUpProcess() + + p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess() + ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map + return false; + } + } + } +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +bool OS::channel<T, Size, S>::pop_back(T& item, TTimeout timeout) +{ + TCritSect cs; + + if(pool.get_count()) + { + item = pool.pop_back(); + CheckWaiters(ProducersProcessMap); + return true; + } + else + { + TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; + p->Timeout = timeout; + + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + for(;;) + { + SetPrioTag(ConsumersProcessMap, PrioTag); // channel is empty, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + + if(pool.get_count()) + { + p->Timeout = 0; + item = pool.pop_back(); + CheckWaiters(ProducersProcessMap); + return true; + } + + if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired + { // or by OS::ForceWakeUpProcess() + + p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess() + ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map + return false; + } + } + } +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void OS::channel<T, Size, S>::flush() +{ + TCritSect cs; + pool.flush(); + CheckWaiters(ProducersProcessMap); +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void OS::channel<T, Size, S>::write(const T* data, const S count) +{ + TCritSect cs; + + while(pool.get_free_size() < count) + { + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + SetPrioTag(ProducersProcessMap, PrioTag); // channel does not have enough space, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + } + + pool.write(data, count); + CheckWaiters(ConsumersProcessMap); +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +bool OS::channel<T, Size, S>::read(T* const data, const S count, TTimeout timeout) +{ + TCritSect cs; + + TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority]; + p->Timeout = timeout; + + TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority); + while(pool.get_count() < count) + { + SetPrioTag(ConsumersProcessMap, PrioTag); // channel doesn't contain enough data, put current process to the wait map + ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map + Kernel.Scheduler(); + + if(ConsumersProcessMap & PrioTag) // waked up by timer when timeout expired + { // or by OS::ForceWakeUpProcess() + + p->Timeout = 0; // non-zero if waked up by ForceWakeUpProcess() + ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map + return false; + } + } + + p->Timeout = 0; + pool.read(data, count); + CheckWaiters(ProducersProcessMap); + + return true; +} +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// +// OS::message template +// +// Function-members implementation +// +// +//------------------------------------------------------------------------------ +void OS::TBaseMessage::sendISR() +{ + TCritSect cs; + + if(ProcessMap) + { + TProcessMap Timeouted = OS::Kernel.ReadyProcessMap; // Process has it's tag set in ReadyProcessMap if timeout + // expired, or it was waked up by OS::ForceWakeUpProcess() + if( ProcessMap & ~Timeouted ) // if any process has to be waked up + { + SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map + ClrPrioTag(ProcessMap, ~Timeouted); // remove all non-timeouted processes from the waiting map. + return; + } + } + NonEmpty = true; +} +//------------------------------------------------------------------------------ +#endif // OS_SERVICES_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/scmRTOS.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,58 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: Main RTOS header file +//* +//* 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 scmRTOS_H +#define scmRTOS_H + +//----------------------------------------------------------------------------- +// +// !!! The order of includes is important !!! +// +#include <stddef.h> +#include <commdefs.h> +#include <usrlib.h> +#include <OS_Target.h> + +//------------------------------------------------------------------------------ + + +#endif // scmRTOS_H +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/scmRTOS_defs.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,374 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: Macros And Common 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 scmRTOS_DEFS_H +#define scmRTOS_DEFS_H + +#include <commdefs.h> + +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +// +// +/// Macro for Channel Type definition +// +// +#define DefineChannel(Name, Capacity) \ +class Name : public OS::TChannel \ +{ \ +public: \ + Name() : OS::TChannel(buf, sizeof(buf)) { } \ + \ +private: \ + byte buf[Capacity]; \ + \ +} +//----------------------------------------------------------------------------- +// +// Check CONFIG Macro Definitions +// +// + +//----------------- scmRTOS_SYSTIMER_NEST_INTS_ENABLE ------------------------- +#ifndef scmRTOS_SYSTIMER_NEST_INTS_ENABLE +#error "Error: Config macro scmRTOS_SYSTIMER_NEST_INTS_ENABLE must be defined!" +#endif + +#if (scmRTOS_SYSTIMER_NEST_INTS_ENABLE < 0) || (scmRTOS_SYSTIMER_NEST_INTS_ENABLE > 1) +#error "Error: scmRTOS_SYSTIMER_NEST_INTS_ENABLE must have values 0 or 1 only!" +#endif + +//----------------- scmRTOS_SYSTEM_TICKS_ENABLE ------------------------------- +#ifndef scmRTOS_SYSTEM_TICKS_ENABLE +#error "Error: Config macro scmRTOS_SYSTEM_TICKS_ENABLE must be defined!" +#endif + +#if (scmRTOS_SYSTEM_TICKS_ENABLE < 0) || (scmRTOS_SYSTEM_TICKS_ENABLE > 1) +#error "Error: scmRTOS_SYSTEM_TICKS_ENABLE must have values 0 or 1 only!" +#endif + + +//----------------- scmRTOS_SYSTIMER_HOOK_ENABLE ------------------------------ +#ifndef scmRTOS_SYSTIMER_HOOK_ENABLE +#error "Error: Config macro scmRTOS_SYSTIMER_HOOK_ENABLE must be defined!" +#endif + +#if (scmRTOS_SYSTIMER_HOOK_ENABLE < 0) || (scmRTOS_SYSTIMER_HOOK_ENABLE > 1) +#error "Error: scmRTOS_SYSTIMER_HOOK_ENABLE must have values 0 or 1 only!" +#endif + +//-------------- scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE ---------------------- +#ifndef scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE +#error "Error: Config macro scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE must be defined!" +#endif + +#if (scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE < 0) || (scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE > 1) +#error "Error: scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE must have values 0 or 1 only!" +#endif + +//----------------- scmRTOS_IDLE_HOOK_ENABLE ---------------------------------- +#ifndef scmRTOS_IDLE_HOOK_ENABLE +#error "Error: Config macro scmRTOS_IDLE_HOOK_ENABLE must be defined!" +#endif + +#if (scmRTOS_IDLE_HOOK_ENABLE < 0) || (scmRTOS_IDLE_HOOK_ENABLE > 1) +#error "Error: scmRTOS_IDLE_HOOK_ENABLE must have values 0 or 1 only!" +#endif + +//----------------- scmRTOS_CONTEXT_SWITCH_SCHEME ----------------------------- +#ifndef scmRTOS_CONTEXT_SWITCH_SCHEME +#error "Error: Config macro scmRTOS_CONTEXT_SWITCH_SCHEME must be defined!" +#endif + +#if (scmRTOS_CONTEXT_SWITCH_SCHEME < 0) || (scmRTOS_CONTEXT_SWITCH_SCHEME > 1) +#error "Error: scmRTOS_CONTEXT_SWITCH_SCHEME must have values 0 or 1 only!" +#endif + + +//----------------- scmRTOS_PRIORITY_ORDER ------------------------------------ +#ifndef scmRTOS_PRIORITY_ORDER +#error "Error: Config macro scmRTOS_PRIORITY_ORDER must be defined!" +#endif + +#if (scmRTOS_PRIORITY_ORDER < 0) || (scmRTOS_PRIORITY_ORDER > 1) +#error "Error: scmRTOS_PRIORITY_ORDER must have values 0 or 1 only!" +#endif + +//----------------- User Hooks inlining ------------------------------------ +#ifndef INLINE_SYS_TIMER_HOOK +#define INLINE_SYS_TIMER_HOOK +#endif + +#ifndef INLINE_CONTEXT_SWITCH_HOOK +#define INLINE_CONTEXT_SWITCH_HOOK +#endif + + +//----------------------------------------------------------------------------- +// +/// Priority and process map type definitions +// +// +namespace OS +{ + #if scmRTOS_PROCESS_COUNT < 8 + typedef byte TProcessMap; + #elif scmRTOS_PROCESS_COUNT < 16 + typedef word TProcessMap; + #else + typedef dword TProcessMap; + #endif + //------------------------------------------------------ +#if scmRTOS_PRIORITY_ORDER == 0 + enum TPriority { + #if scmRTOS_PROCESS_COUNT > 0 + pr0, + #endif + #if scmRTOS_PROCESS_COUNT > 1 + pr1, + #endif + #if scmRTOS_PROCESS_COUNT > 2 + pr2, + #endif + #if scmRTOS_PROCESS_COUNT > 3 + pr3, + #endif + #if scmRTOS_PROCESS_COUNT > 4 + pr4, + #endif + #if scmRTOS_PROCESS_COUNT > 5 + pr5, + #endif + #if scmRTOS_PROCESS_COUNT > 6 + pr6, + #endif + #if scmRTOS_PROCESS_COUNT > 7 + pr7, + #endif + #if scmRTOS_PROCESS_COUNT > 8 + pr8, + #endif + #if scmRTOS_PROCESS_COUNT > 9 + pr9, + #endif + #if scmRTOS_PROCESS_COUNT > 10 + pr10, + #endif + #if scmRTOS_PROCESS_COUNT > 11 + pr11, + #endif + #if scmRTOS_PROCESS_COUNT > 12 + pr12, + #endif + #if scmRTOS_PROCESS_COUNT > 13 + pr13, + #endif + #if scmRTOS_PROCESS_COUNT > 14 + pr14, + #endif + #if scmRTOS_PROCESS_COUNT > 15 + pr15, + #endif + #if scmRTOS_PROCESS_COUNT > 16 + pr16, + #endif + #if scmRTOS_PROCESS_COUNT > 17 + pr17, + #endif + #if scmRTOS_PROCESS_COUNT > 18 + pr18, + #endif + #if scmRTOS_PROCESS_COUNT > 19 + pr19, + #endif + #if scmRTOS_PROCESS_COUNT > 20 + pr20, + #endif + #if scmRTOS_PROCESS_COUNT > 21 + pr21, + #endif + #if scmRTOS_PROCESS_COUNT > 22 + pr22, + #endif + #if scmRTOS_PROCESS_COUNT > 23 + pr23, + #endif + #if scmRTOS_PROCESS_COUNT > 24 + pr24, + #endif + #if scmRTOS_PROCESS_COUNT > 25 + pr25, + #endif + #if scmRTOS_PROCESS_COUNT > 26 + pr26, + #endif + #if scmRTOS_PROCESS_COUNT > 27 + pr27, + #endif + #if scmRTOS_PROCESS_COUNT > 28 + pr28, + #endif + #if scmRTOS_PROCESS_COUNT > 29 + pr29, + #endif + #if scmRTOS_PROCESS_COUNT > 30 + pr30, + #endif + #if (scmRTOS_PROCESS_COUNT > 31) || (scmRTOS_PROCESS_COUNT < 1) + #error "Invalid Process Count specification! Must be from 1 to 31." + #endif + prIDLE + }; +#else // scmRTOS_PRIORITY_ORDER == 1 + enum TPriority { + prIDLE, + #if scmRTOS_PROCESS_COUNT > 30 + pr30, + #endif + #if scmRTOS_PROCESS_COUNT > 29 + pr29, + #endif + #if scmRTOS_PROCESS_COUNT > 28 + pr28, + #endif + #if scmRTOS_PROCESS_COUNT > 27 + pr27, + #endif + #if scmRTOS_PROCESS_COUNT > 26 + pr26, + #endif + #if scmRTOS_PROCESS_COUNT > 25 + pr25, + #endif + #if scmRTOS_PROCESS_COUNT > 24 + pr24, + #endif + #if scmRTOS_PROCESS_COUNT > 23 + pr23, + #endif + #if scmRTOS_PROCESS_COUNT > 22 + pr22, + #endif + #if scmRTOS_PROCESS_COUNT > 21 + pr21, + #endif + #if scmRTOS_PROCESS_COUNT > 20 + pr20, + #endif + #if scmRTOS_PROCESS_COUNT > 19 + pr19, + #endif + #if scmRTOS_PROCESS_COUNT > 18 + pr18, + #endif + #if scmRTOS_PROCESS_COUNT > 17 + pr17, + #endif + #if scmRTOS_PROCESS_COUNT > 16 + pr16, + #endif + #if scmRTOS_PROCESS_COUNT > 15 + pr15, + #endif + #if scmRTOS_PROCESS_COUNT > 14 + pr14, + #endif + #if scmRTOS_PROCESS_COUNT > 13 + pr13, + #endif + #if scmRTOS_PROCESS_COUNT > 12 + pr12, + #endif + #if scmRTOS_PROCESS_COUNT > 11 + pr11, + #endif + #if scmRTOS_PROCESS_COUNT > 10 + pr10, + #endif + #if scmRTOS_PROCESS_COUNT > 9 + pr9, + #endif + #if scmRTOS_PROCESS_COUNT > 8 + pr8, + #endif + #if scmRTOS_PROCESS_COUNT > 7 + pr7, + #endif + #if scmRTOS_PROCESS_COUNT > 6 + pr6, + #endif + #if scmRTOS_PROCESS_COUNT > 5 + pr5, + #endif + #if scmRTOS_PROCESS_COUNT > 4 + pr4, + #endif + #if scmRTOS_PROCESS_COUNT > 3 + pr3, + #endif + #if scmRTOS_PROCESS_COUNT > 2 + pr2, + #endif + #if scmRTOS_PROCESS_COUNT > 1 + pr1, + #endif + #if scmRTOS_PROCESS_COUNT > 0 + pr0 + #endif + #if (scmRTOS_PROCESS_COUNT > 31) || (scmRTOS_PROCESS_COUNT < 1) + #error "Invalid Process Count specification! Must be from 1 to 31." + #endif + }; +#endif //scmRTOS_PRIORITY_ORDER +} +//----------------------------------------------------------------------------- +// +// Process's constructor inlining control: default behaviour +// +#ifndef INLINE_PROCESS_CTOR +#define INLINE_PROCESS_CTOR +#endif + + +//----------------------------------------------------------------------------- + +#endif // scmRTOS_DEFS_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/usrlib.cpp Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,140 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: User Suport Library Source +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** + +#include <usrlib.h> +#include <commdefs.h> + +using namespace usr; + +//------------------------------------------------------------------------------ +// +/// Circular buffer function-member description +// +// +// +TCbuf::TCbuf(byte* const Address, const byte Size) : + buf(Address), + size(Size), + count(0), + first(0), + last(0) +{ +} +//------------------------------------------------------------------------------ +bool TCbuf::write(const byte* data, const byte Count) +{ + if( Count > (size - count) ) + return false; + + for(byte i = 0; i < Count; i++) + push(*(data++)); + + return true; +} +//------------------------------------------------------------------------------ +void TCbuf::read(byte* data, const byte Count) +{ + byte N = Count <= count ? Count : count; + + for(byte i = 0; i < N; i++) + data[i] = pop(); +} +//------------------------------------------------------------------------------ +byte TCbuf::get_byte(const byte index) const +{ + byte x = first + index; + + if(x < size) + return buf[x]; + else + return buf[x - size]; +} + +//------------------------------------------------------------------------------ +bool TCbuf::put(const byte item) +{ + if(count == size) + return false; + + push(item); + return true; +} +//------------------------------------------------------------------------------ +byte TCbuf::get() +{ + if(count) + return pop(); + else + return 0; +} +//------------------------------------------------------------------------------ +// +/// \note +/// For internal purposes. +/// Use this function with care - it doesn't perform free size check. +// +void TCbuf::push(const byte item) +{ + buf[last] = item; + last++; + count++; + + if(last == size) + last = 0; +} +//------------------------------------------------------------------------------ +// +/// \note +/// For internal purposes. +/// Use this function with care - it doesn't perform free size check. +// +byte TCbuf::pop() +{ + byte item = buf[first]; + + count--; + first++; + if(first == size) + first = 0; + + return item; +} +//------------------------------------------------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/Common/usrlib.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,298 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PURPOSE: User Suport Library Header +//* +//* 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 USRLIB_H +#define USRLIB_H + +#include <commdefs.h> + +//------------------------------------------------------------------------------ +// +// DESCRIPTON: user namespace for some useful types and functions +// +// +namespace usr +{ + //------------------------------------------------------------------------------ + // + /// The Circular Buffer + // + /// Byte-wide FIFO. + // + /// Allows to: + /// add byte, + /// get byte, + /// write bytes from array, + /// read bytes to array, + /// and some other service actions. + // + class TCbuf + { + public: + TCbuf(byte* const Address, const byte Size); + bool write(const byte* data, const byte Count); + void read(byte* const data, const byte Count); + byte get_count() const { return count; } + byte get_free_size() const { return size - count; } + byte get_byte(const byte index) const; + void clear() { count = 0; last = first; } + bool put(const byte item); + byte get(); + + private: + //------------------------------------------------------------------------------ + // + // DESCRIPTON: For internal purposes + // + void push(const byte item); ///< Use this function with care - it doesn't perform free size check + byte pop(); ///< Use this function with care - it doesn't perform count check + //------------------------------------------------------------------------------ + + private: + byte* buf; + byte size; + volatile byte count; + byte first; + byte last; + }; + //------------------------------------------------------------------------------ + + + + //----------------------------------------------------------------------- + // + /// The Ring Buffer Template + /// + /// Carries out FIFO functionality for + /// arbitrary data types + /// + /// Allows to: + /// add item to back (default), + /// add item to front, + /// get item at front (default), + /// get item from back, + /// write items from array, + /// read items to array and some other actions + // + // + // + template<typename T, word Size, typename S = byte> + class ring_buffer + { + public: + ring_buffer() : Count(0), First(0), Last(0) { } + + //---------------------------------------------------------------- + // + // Data transfer functions + // + bool write(const T* data, const S cnt); + void read(T* const data, const S cnt); + + bool push_back(const T item); + bool push_front(const T item); + + T pop_front(); + T pop_back(); + + bool push(const T item) { return push_back(item); } + T pop() { return pop_front(); } + + //---------------------------------------------------------------- + // + // Service functions + // + S get_count() const { return Count; } + S get_free_size() const { return Size - Count; } + T& operator[](const S index); + void flush() { Count = 0; Last = First; } + + private: + //-------------------------------------------------------------- + // DESCRIPTON: For internal purposes + // Use this functions with care: it don't perform + // free size and count check + // + void push_item(const T item); + void push_item_front(const T item); + T pop_item(); + T pop_item_back(); + //-------------------------------------------------------------- + + private: + S Count; + S First; + S Last; + T Buf[Size]; + }; + //------------------------------------------------------------------ +} +//--------------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +// +// The ring buffer function-member definitions +// +// +// +template<typename T, word Size, typename S> +bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt) +{ + if( cnt > (Size - Count) ) + return false; + + for(S i = 0; i < cnt; i++) + push_item(*(data++)); + + return true; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt) +{ + S nItems = cnt <= Count ? cnt : Count; + + for(S i = 0; i < nItems; i++) + data[i] = pop_item(); +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +T& usr::ring_buffer<T, Size, S>::operator[](const S index) +{ + S x = First + index; + + if(x < Size) + return Buf[x]; + else + return Buf[x - Size]; +} + +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +bool usr::ring_buffer<T, Size, S>::push_back(const T item) +{ + if(Count == Size) + return false; + + push_item(item); + return true; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +bool usr::ring_buffer<T, Size, S>::push_front(const T item) +{ + if(Count == Size) + return false; + + push_item_front(item); + return true; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +T usr::ring_buffer<T, Size, S>::pop_front() +{ + if(Count) + return pop_item(); + else + return Buf[First]; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +T usr::ring_buffer<T, Size, S>::pop_back() +{ + if(Count) + return pop_item_back(); + else + return Buf[First]; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void usr::ring_buffer<T, Size, S>::push_item(const T item) +{ + Buf[Last] = item; + Last++; + Count++; + + if(Last == Size) + Last = 0; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +void usr::ring_buffer<T, Size, S>::push_item_front(const T item) +{ + if(First == 0) + First = Size - 1; + else + --First; + Buf[First] = item; + Count++; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +T usr::ring_buffer<T, Size, S>::pop_item() +{ + T item = Buf[First]; + + Count--; + First++; + if(First == Size) + First = 0; + + return item; +} +//------------------------------------------------------------------------------ +template<typename T, word Size, typename S> +T usr::ring_buffer<T, Size, S>::pop_item_back() +{ + + if(Last == 0) + Last = Size - 1; + else + --Last; + + Count--; + return Buf[Last];; +} +//------------------------------------------------------------------------------ + + +#endif // USRLIB_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/CortexM3/OS_Target.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,236 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: RVCT (ARM) +//* +//* PURPOSE: Target Dependent Stuff Header. Declarations And Definitions +//* +//* Version: 3.10 +//* +//* $Revision: 195 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* Ported by Andrey Chuikin, Copyright (c) 2008-2010 + +#ifndef scmRTOS_CORTEXM3_H +#define scmRTOS_CORTEXM3_H + +#include <commdefs.h> + +//------------------------------------------------------------------------------ +// +// Compiler and Target checks +// +// +#ifndef __ARMCC_VERSION +#error "This file should only be compiled with ARM RVCT Compiler" +#endif // __ARMCC_VERSION + +#if __TARGET_ARCH_ARM != 0 || __TARGET_ARCH_THUMB != 4 +#error "This file must be compiled for ARMv7-M (Cortex-M3) processor only." +#endif + +//------------------------------------------------------------------------------ +// +// Target specific types +// +// +typedef dword TStackItem; +typedef dword TStatusReg; + +//----------------------------------------------------------------------------- +// +// Configuration macros +// +// +#define OS_PROCESS __attribute__((__noreturn__)) +#define OS_INTERRUPT +#define DUMMY_INSTR() __NOP() +#define INLINE_PROCESS_CTOR INLINE inline + +//----------------------------------------------------------------------------- +// +// Uncomment macro value below for SystemTimer() run in critical section +// +// This is useful (and necessary) when target processor has hardware +// enabled nested interrups. Cortex-M3 have such interrupts. +// +#define SYS_TIMER_CRIT_SECT() TCritSect cs + +//----------------------------------------------------------------------------- +// Separate return stack not required +#define SEPARATE_RETURN_STACK 0 + +//----------------------------------------------------------------------------- +// Software interrupt stack switching not supported in Cortex-M3 port +// because processor implements hardware stack switching. +// So, system timer isr wrapper can't be choosen at project level +// +#define scmRTOS_ISRW_TYPE TISRW + +//----------------------------------------------------------------------------- +// +// scmRTOS Context Switch Scheme +// +// The macro defines a context switch manner. Value 0 sets direct context +// switch in the scheduler and in the OS ISRs. This is the primary method. +// Value 1 sets the second way to switch context - by using of software +// interrupt. See documentation fo details. +// Cortex-M3 port supports software interrupt switch method only. +// +#define scmRTOS_CONTEXT_SWITCH_SCHEME 1 + +//----------------------------------------------------------------------------- +// +// Include project-level configurations +// !!! The order of includes is important !!! +// +#include "../../scmRTOS_config.h" +#include "../scmRTOS_TARGET_CFG.h" +#include <scmRTOS_defs.h> +#include <LPC17xx.h> + +//----------------------------------------------------------------------------- +// +// The Critital Section Wrapper +// +// +#define __enable_interrupt() __enable_irq() +#define __disable_interrupt() __disable_irq() + +#define __set_interrupt_state(status) __set_PRIMASK(status) +#define __get_interrupt_state() __get_PRIMASK() + +class TCritSect +{ +public: + TCritSect () : StatusReg(__get_interrupt_state()) { __disable_interrupt(); } + ~TCritSect() { __set_interrupt_state(StatusReg); } + +private: + TStatusReg StatusReg; +}; +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// +// Priority stuff +// +// +namespace OS +{ +INLINE inline OS::TProcessMap GetPrioTag(const byte pr) { return static_cast<OS::TProcessMap> (1 << pr); } + +#if scmRTOS_PRIORITY_ORDER == 0 + INLINE inline byte GetHighPriority(TProcessMap pm) + { + byte pr = 0; + + while( !(pm & 0x0001) ) + { + pr++; + pm >>= 1; + } + return pr; + } +#else + INLINE inline byte GetHighPriority(TProcessMap pm) { return (31 - __clz(pm)); } +#endif // scmRTOS_PRIORITY_ORDER +} + +//----------------------------------------------------------------------------- +// +// Interrupt and Interrupt Service Routines support +// +INLINE inline TStatusReg GetInterruptState( ) { return __get_interrupt_state(); } +INLINE inline void SetInterruptState(TStatusReg sr) { __set_interrupt_state(sr); } + +INLINE inline void EnableInterrupts() { __enable_interrupt(); } +INLINE inline void DisableInterrupts() { __disable_interrupt(); } + + +namespace OS +{ + INLINE inline void EnableContextSwitch() { EnableInterrupts(); } + INLINE inline void DisableContextSwitch() { DisableInterrupts(); } +} + +#include <OS_Kernel.h> + +namespace OS +{ + //-------------------------------------------------------------------------- + // + // NAME : OS ISR support + // + // PURPOSE : Implements common actions on interrupt enter and exit + // under the OS + // + // DESCRIPTION: + // + // + class TISRW + { + public: + INLINE TISRW() { ISR_Enter(); } + INLINE ~TISRW() { ISR_Exit(); } + + private: + //----------------------------------------------------- + INLINE void ISR_Enter() + { + TCritSect cs; + Kernel.ISR_NestCount++; + } + //----------------------------------------------------- + INLINE void ISR_Exit() + { + TCritSect cs; + if(--Kernel.ISR_NestCount) return; + Kernel.SchedISR(); + } + //----------------------------------------------------- + }; + + // No software interrupt stack switching provided, + // TISRW_SS declared to be the same as TISRW for porting compability + #define TISRW_SS TISRW + +} // ns OS +//----------------------------------------------------------------------------- + +#endif // scmRTOS_CORTEXM3_H +//----------------------------------------------------------------------------- +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/CortexM3/OS_Target_asm.s Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,178 @@ +; ****************************************************************************** +; * +; * FULLNAME: Single-Chip Microcontroller Real-Time Operating System +; * +; * NICKNAME: scmRTOS +; * +; * PROCESSOR: ARM Cortex-M3 +; * +; * TOOLKIT: EWARM (IAR Systems) +; * +; * PURPOSE: Target Dependent Low-Level Stuff +; * +; * Version: 3.10 +; * +; * $Revision: 195 $ +; * $Date:: 2008-06-19 #$ +; * +; * 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. +; * ================================================================= +; * +; ****************************************************************************** +; * Ported by Andrey Chuikin, Copyright (c) 2008-2010 + +; #include "scmRTOS_TARGET_CFG.h" + +; ----------------------------------------------------------------------------- +; PUBLIC FUNCTIONS +; + EXTERN OS_ContextSwitchHook + + EXPORT OS_Start + EXPORT PendSV_Handler + +; ----------------------------------------------------------------------------- +; EQUATES +; +NVIC_INT_CTRL EQU 0xE000ED04 ; Interrupt control state register. +NVIC_PENDSVSET EQU 0x10000000 ; Value to trigger PendSV exception. + +NVIC_SYSPRI14 EQU 0xE000ED22 ; System priority register (priority 14). +NVIC_PENDSV_PRI EQU 0xFF ; PendSV priority value (lowest). +NVIC_SYSPRI15 EQU 0xE000ED23 ; System priority register (priority 15). +NVIC_ST_PRI EQU 0xFF ; SysTick priority value (lowest). + +NVIC_ST_CTRL EQU 0xE000E010 ; SysTick Ctrl & Status Reg. +NVIC_ST_RELOAD EQU 0xE000E014 ; SysTick Reload Value Reg. +NVIC_ST_CTRL_CLK_SRC EQU 0x00000004 ; Clock Source. +NVIC_ST_CTRL_INTEN EQU 0x00000002 ; Interrupt enable. +NVIC_ST_CTRL_ENABLE EQU 0x00000001 ; Counter mode. + +; should be the same as in scmRTOS_TARGET_CFG.h +SYSTICKFREQ EQU 100000000 +SYSTICKINTRATE EQU 1000 + +; ----------------------------------------------------------------------------- +; CODE GENERATION DIRECTIVES +; + AREA TEXT, CODE, READONLY + THUMB + +; ----------------------------------------------------------------------------- +; HANDLE PendSV EXCEPTION +; void PendSV_Handler(void) +; +; Note(s) : 1) PendSV is used to cause a context switch. This is a recommended method for performing +; context switches with Cortex-M3. This is because the Cortex-M3 auto-saves half of the +; processor context on any exception, and restores same on return from exception. So only +; saving of R4-R11 is required and fixing up the stack pointers. Using the PendSV exception +; this way means that context saving and restoring is identical whether it is initiated from +; a thread or occurs due to an interrupt or exception. +; +; 2) Pseudo-code is: +; a) Get the process SP, if 0 then skip (goto f) the saving part (first context switch); +; b) Save remaining regs r4-r11 on process stack; +; c) Call OS_ContextSwitchHook for save current task SP and get new task SP; +; d) Restore R4-R11 from new process stack; +; e) Perform exception return which will restore remaining context. +; f) Get SP for the first context switch (R2 hold it); +; run SysTick; goto d); +; +; 3) On entry into PendSV handler: +; a) The following have been saved on the process stack (by processor): +; xPSR, PC, LR, R12, R0-R3 +; b) Processor mode is switched to Handler mode (from Thread mode) +; c) Stack is Main stack (switched from Process stack) +; +; 4) Since PendSV is set to lowest priority in the system (by OS_Start() below), we +; know that it will only be run when no other exception or interrupt is active, and +; therefore safe to assume that context being switched out was using the process stack (PSP). +; +PendSV_Handler + CPSID I ; Prevent interruption during context switch + MRS R0, PSP ; PSP is process stack pointer + CBZ R0, nosave ; Skip register save the first time + + STMDB R0!, {R4-R11} ; Save remaining regs r4-11 on process stack + ; At this point, entire context of process has been saved + + PUSH {R14} ; Save LR exc_return value + LDR R1, =OS_ContextSwitchHook ; OS_ContextSwitchHook(); + BLX R1 + POP {R14} + +ContextRestore + ; R0 is new process SP; + LDMIA R0!, {R4-R11} ; Restore r4-11 from new process stack + MSR PSP, R0 ; Load PSP with new process SP + ORR LR, LR, #0x04 ; Ensure exception return uses process stack + CPSIE I + BX LR ; Exception return will restore remaining context +nosave + MOV R0, R2 ; R2 hold the first task SP + + LDR R1, =NVIC_ST_CTRL ; Enable and run SysTick + LDR R2, =(NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | NVIC_ST_CTRL_ENABLE) + STR R2, [R1] + + B ContextRestore + + +; ----------------------------------------------------------------------------- +; START MULTITASKING +; void OS_Start(TStackItem* sp) +; +; Note(s) : 1) OS_Start() MUST: +; a) Setup PendSV and SysTick exception priority to lowest; +; b) Setup SysTick (reload value); +; c) Enable interrupts (tasks will run with interrupts enabled). +; +OS_Start + LDR R1, =NVIC_SYSPRI14 ; Set the PendSV exception priority (lowest) + LDR R2, =NVIC_PENDSV_PRI + STRB R2, [R1] + LDR R1, =NVIC_SYSPRI15 ; Set the SysTick exception priority (lowest) + LDR R2, =NVIC_ST_PRI + STRB R2, [R1] + + LDR R1, =NVIC_ST_RELOAD ; Setup SysTick + LDR R2, =(SYSTICKFREQ/SYSTICKINTRATE-1) + STR R2, [R1] + + MOV R2, R0 ; Save the first task stack + MOVS R0, #0 ; Set the PSP to 0 for initial context switch call + MSR PSP, R0 + + LDR R0, =NVIC_INT_CTRL ; Trigger the PendSV exception (causes context switch) + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + + CPSIE I ; Enable interrupts at processor level +loop + B loop ; Should never get here + + + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/CortexM3/OS_Target_cpp.cpp Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,131 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: EWARM (IAR Systems) +//* +//* PURPOSE: Target Dependent Stuff Source +//* +//* Version: 3.10 +//* +//* $Revision: 195 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* Ported by Andrey Chuikin, Copyright (c) 2008-2010 + + +#include <scmRTOS.h> + +using namespace OS; + +//------------------------------------------------------------------------------ +// +// OS Process's constructor +// +// Performs: +// * initializing process data; +// * registering of the process in kernel; +// * preparing stack frame; +// +// +TBaseProcess::TBaseProcess(TStackItem* Stack, TPriority pr, void (*exec)()) + : StackPointer(Stack) + , Timeout(0) + , Priority(pr) +{ + Kernel.RegisterProcess(this); + + //--------------------------------------------------------------- + // + // Prepare Process Stack Frame + // + *(--StackPointer) = 0x01000000L; // xPSR + *(--StackPointer) = reinterpret_cast<dword>(exec); // Entry Point + StackPointer -= 14; // emulate "push R14,R12,R3,R2,R1,R0,R11-R4" + + // The code below can be used for debug purpose. In this case comment + // line above and uncomment block below. +/* + *(--StackPointer) = 0xFFFFFFFEL; // R14 (LR) (init value will cause fault if ever used) + *(--StackPointer) = 0x12121212L; // R12 + *(--StackPointer) = 0x03030303L; // R3 + *(--StackPointer) = 0x02020202L; // R2 + *(--StackPointer) = 0x01010101L; // R1 + *(--StackPointer) = 0x00000000L; // R0 + + // Remaining registers saved on process stack + *(--StackPointer) = 0x11111111L; // R11 + *(--StackPointer) = 0x10101010L; // R10 + *(--StackPointer) = 0x09090909L; // R9 + *(--StackPointer) = 0x08080808L; // R8 + *(--StackPointer) = 0x07070707L; // R7 + *(--StackPointer) = 0x06060606L; // R6 + *(--StackPointer) = 0x05050505L; // R5 + *(--StackPointer) = 0x04040404L; // R4 +*/ +} +//------------------------------------------------------------------------------ +// +// Idle Process +// +typedef process<prIDLE, scmRTOS_IDLE_PROCESS_STACK_SIZE> TIdleProcess; + +TIdleProcess IdleProcess; + +template<> OS_PROCESS void TIdleProcess::Exec() +{ + for(;;) + { + #if scmRTOS_IDLE_HOOK_ENABLE == 1 + IdleProcessUserHook(); + #endif + } +} +//------------------------------------------------------------------------------ +OS_INTERRUPT void OS::SysTick_Handler() +{ + scmRTOS_ISRW_TYPE ISR; + + Kernel.SystemTimer(); + +#if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0 + DISABLE_NESTED_INTERRUPTS(); +#endif + +#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 + SystemTimerUserHook(); +#endif +} +//------------------------------------------------------------------------------ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/CortexM3/commdefs.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,71 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: EWARM (IAR Systems) +//* +//* PURPOSE: Common Type Definitions +//* +//* Version: 3.10 +//* +//* $Revision: 195 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* Ported by Andrey Chuikin, Copyright (c) 2008-2010 + + +#ifndef COMMONDEFS_H +#define COMMONDEFS_H + +#ifndef __IAR_SYSTEMS_ASM__ + +typedef unsigned char byte; +typedef signed char sbyte; +typedef unsigned short word; +typedef unsigned long dword; + +typedef volatile byte sfr_byte; +typedef volatile word sfr_word; +typedef volatile dword sfr_dword; + +#define INLINE _Pragma("inline=forced") + +#endif // __IAR_SYSTEMS_ASM__ + +#endif // COMMONDEFS_H + +//----------------------------------------------------------------------------- + +/*============================================================================*/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/CortexM3/device.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,60 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: EWARM (IAR Systems) +//* +//* PURPOSE: Device Definitions +//* +//* Version: 3.10 +//* +//* $Revision: 196 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* Ported by Andrey Chuikin, Copyright (c) 2008-2010 + +#ifndef DEVICE_H +#define DEVICE_H + +#include <commdefs.h> + +//------------------------------------------------------------------------------ +// Definitions for some processor registers in order to not include specific +// header file for various Cortex-M3 processor derivatives. +#define CPU_ICSR ( ( sfr_dword *) 0xE000ED04 ) // Interrupt Control State Register +#define CPU_SYSTICKCSR ( ( sfr_dword *) 0xE000E010 ) // SysTick Control and Status Register +#define CPU_SYSTICKCSR_EINT 0x02 // Bit for enable/disable SysTick interrupt + + +#endif /* DEVICE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS/scmRTOS_TARGET_CFG.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,102 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: EWARM (IAR Systems) +//* +//* PURPOSE: Project Level Target Extensions Config +//* +//* Version: 3.10 +//* +//* $Revision: 196 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* mbed port by Igor Skochinsky + +#ifndef scmRTOS_TARGET_CFG_H +#define scmRTOS_TARGET_CFG_H + +#include "device.h" + +// Define SysTick clock frequency and its interrupt rate in Hz. +#define SYSTICKFREQ 100000000 +#define SYSTICKINTRATE 1000 + +//------------------------------------------------------------------------------ +// +// System Timer stuff +// +// +namespace OS +{ +extern "C" void SysTick_Handler(); +} + +#define LOCK_SYSTEM_TIMER() ( *CPU_SYSTICKCSR &= ~CPU_SYSTICKCSR_EINT ) +#define UNLOCK_SYSTEM_TIMER() ( *CPU_SYSTICKCSR |= CPU_SYSTICKCSR_EINT ) + +//------------------------------------------------------------------------------ +// +// Context Switch ISR stuff +// +// +namespace OS +{ +#if scmRTOS_IDLE_HOOK_ENABLE == 1 + void IdleProcessUserHook(); +#endif + +#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 + + INLINE inline void RaiseContextSwitch() { *CPU_ICSR |= 0x10000000; } + + #define ENABLE_NESTED_INTERRUPTS() + + #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0 + #define DISABLE_NESTED_INTERRUPTS() TCritSect cs + #else + #define DISABLE_NESTED_INTERRUPTS() + #endif + +#else + #error "Cortex-M3 port supports software interrupt switch method only!" + +#endif // scmRTOS_CONTEXT_SWITCH_SCHEME + +} +//----------------------------------------------------------------------------- + +#endif // scmRTOS_TARGET_CFG_H +//----------------------------------------------------------------------------- +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scmRTOS_config.h Thu Sep 09 21:19:01 2010 +0000 @@ -0,0 +1,133 @@ +//****************************************************************************** +//* +//* FULLNAME: Single-Chip Microcontroller Real-Time Operating System +//* +//* NICKNAME: scmRTOS +//* +//* PROCESSOR: ARM Cortex-M3 +//* +//* TOOLKIT: EWARM (IAR Systems) +//* +//* PURPOSE: Project Level Configuration +//* +//* Version: 3.10 +//* +//* $Revision: 196 $ +//* $Date:: 2008-06-19 #$ +//* +//* 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. +//* ================================================================= +//* +//****************************************************************************** +//* Ported by Andrey Chuikin, Copyright (c) 2008-2010 + +#ifndef scmRTOS_CONFIG_H +#define scmRTOS_CONFIG_H + +#ifndef __IAR_SYSTEMS_ASM__ +#include <commdefs.h> + +typedef word TTimeout; + +#endif // __IAR_SYSTEMS_ASM__ + +#include "device.h" +//------------------------------------------------------------------------------ +// +// Specify scmRTOS Process Count. Must be less than 31 +// +// +#define scmRTOS_PROCESS_COUNT 3 + +//----------------------------------------------------------------------------- +// +// scmRTOS System Timer +// +// Nested Interrupts enable macro. Value 1 means that interrupts are +// globally enabled within System Timer ISR (this is default for Cortex-M3). +// +// +#define scmRTOS_SYSTIMER_NEST_INTS_ENABLE 1 + +//----------------------------------------------------------------------------- +// +// scmRTOS System Timer Tick Counter Enable +// +// +#define scmRTOS_SYSTEM_TICKS_ENABLE 1 + + +//----------------------------------------------------------------------------- +// +// scmRTOS System Timer Hook +// +// +#define scmRTOS_SYSTIMER_HOOK_ENABLE 1 + +//----------------------------------------------------------------------------- +// +// scmRTOS Idle Process Hook +// +// +#define scmRTOS_IDLE_HOOK_ENABLE 1 + +//----------------------------------------------------------------------------- +// +// scmRTOS Idle Process Stack size (in bytes) +// (20 * sizeof(TStackItem)) - it's a minimum allowed value. +// +#define scmRTOS_IDLE_PROCESS_STACK_SIZE (20 * sizeof(TStackItem)) + +//----------------------------------------------------------------------------- +// +// scmRTOS Priority Order +// +// This macro defines the order of the process's priorities. Default, +// the ascending order is used. Alternatively, the descending priority +// order can be used. On some platforms the descending order is preferred +// because of performance. +// +// Default (corresponding to ascending order) value of macro is 0. +// Alternative (corresponding to descending order) value of macro is 1. +// +// On Cortex-M3 the descending order is preferred for performance reason. +// +#define scmRTOS_PRIORITY_ORDER 1 + +//----------------------------------------------------------------------------- +// +// scmRTOS Context Switch User Hook enable +// +// The macro enables/disables user defined hook called from system +// Context Switch Hook function. +// +// +#define scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE 0 + + +#endif // scmRTOS_CONFIG_H +//----------------------------------------------------------------------------- +