Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
mbed714
Date:
Tue Sep 21 19:48:05 2010 +0000
Commit message:

Changed in this revision

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