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

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
jberry
Date:
Mon Nov 01 20:39:01 2010 +0000
Commit message:

Changed in this revision

Hexacopter/Command_handler.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/Motor_control.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/Mutexes.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/PING_rangefinder.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/Servo_Control.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/accelerometer.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/channels.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/event_flags.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/messages.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/processes.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/serial.h Show annotated file Show diff for this revision Revisions of this file
Hexacopter/serial_out.h Show annotated file Show diff for this revision Revisions of this file
Servo.cpp Show annotated file Show diff for this revision Revisions of this file
Servo.h Show annotated file Show diff for this revision Revisions of this file
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/scmRTOS_config.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 9b057566f9ee Hexacopter/Command_handler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/Command_handler.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,91 @@
+#pragma once
+#ifndef COMMAND_HANDLER_H
+#define COMMAND_HANDLER_H
+#include <messages.h>
+#include <processes.h>
+
+//DigitalOut led2(LED2); 
+extern BusOut leds;
+template<> OS_PROCESS void Command_handler::Exec() //serial stream handling process
+{
+    //led2 = 0;
+    char RX_Command[100] = "";
+    RX_Command[99] = '\0';
+   
+    for(;;)
+    {       
+       
+       //RX_channel.pop(temp);
+       for(byte i = 0; i<100; i++)
+       {            
+            RX_channel.pop(RX_Command[i]);
+            leds = 0x4;
+            if(i == 99)
+                {
+                    RX_Command[i] = '\0';                    
+                }
+            //pc.putc(RX_Command[i]);
+            if(RX_Command[i] == '\0')  //keep popping chars until a delimiter is found
+               break;
+       }
+      //led2 = !led2; 
+      TX_channel.write(RX_Command, strlen(RX_Command)+1); //output the command for debugging
+      TX_channel.push('\n');
+      //char temp = 0;
+      //TX_channel.pop(temp);
+      //OUT->putc(temp);
+      //OUT->printf(RX_Command);
+      
+        if (strstr(RX_Command,"SER:") != NULL) //check for Serv: in the command - this will indicate that the command is destined for the servo process
+            {
+               SER_channel.write(RX_Command, strlen(RX_Command)+1);
+               //Servo_Command_Event.Signal();                
+             }
+            
+        else if (strstr(RX_Command,"PIN") != NULL) //check for PING in the command - this will indicate that the command is destined for the PING process
+            {
+
+               PING_MESSAGE = 0;
+               PING_MESSAGE.send();
+             }    
+        
+        else if (strstr(RX_Command,"PIC") != NULL) //check for PING in the command - this will indicate that the command is destined for the PING process
+        {
+
+           PING_MESSAGE = 1;
+           PING_MESSAGE.send();
+         }    
+        
+        else if (strstr(RX_Command, "MOT:") != NULL) //check to see if incoming motor control command
+        {
+            MOT_channel.write(RX_Command, strlen(RX_Command)+1);
+            
+        }
+        else if (strstr(RX_Command, "MO2:") != NULL) //this command will deal with both motors
+        {
+            MOT_channel.write(RX_Command, strlen(RX_Command)+1);
+            
+        }
+        
+        else if (strstr(RX_Command, "ACR") != NULL) //check to see if incoming motor control command
+        { //OS::message<byte> ACCELEROMETER_MESSAGE; //if message is a zero, then return acceleration once, if a 1 then continually return acceleration data         
+                         
+                ACCELEROMETER_MESSAGE = 1;
+                ACCELEROMETER_MESSAGE.send(); //send the message
+            
+        }        
+        else if (strstr(RX_Command, "ACC") != NULL) //check to see if incoming motor control command
+        { //OS::message<byte> ACCELEROMETER_Message; //if message is a zero, then return acceleration once, if a 1 then continually return acceleration data         
+                         
+                ACCELEROMETER_MESSAGE = 0;
+                ACCELEROMETER_MESSAGE.send(); //send the message
+            
+        }
+        leds = 0x4;
+    }
+    
+}  
+
+
+#endif
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/Motor_control.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/Motor_control.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,224 @@
+#pragma once
+#ifndef MOTOR_CONTROL_H
+#define MOTOR_CONTROL_H
+#include <cmath>
+#include <processes.h>
+
+
+//Motor_controller M_cont_process;
+enum direction{CLOCKWISE,ANTICLOCKWISE};
+ //PwmOut Out1(p23); //motor1
+ //PwmOut Out2(p24);
+ //PwmOut Out3(p25);
+ //PwmOut Out4(p26);
+
+class motor_control
+{
+    public:
+    motor_control(PinName OUT1, PinName OUT2)
+    :Out1(OUT1),Out2(OUT2),Output(&Out1)
+    {
+        //Output = &Out1;
+        set_direction(CLOCKWISE);
+        SPEED = 0.0;
+        Out1.pulsewidth_ms(1); // pulsewidth should be 1ms
+        Out1.write(0.0); //set initial duty cycle to 0 (i.e. off)
+        Out2.write(0.0); //set initial duty cycle to 0 (i.e. off)
+        
+        
+
+        
+     }
+        
+    void set_direction(direction D)
+    {
+        if( D == CLOCKWISE )
+        {
+            *Output = 0;
+            Output = &Out2;            
+         }
+        else
+        {
+            *Output = 0;
+            Output = &Out1;            
+        }
+        DIR = D;
+        //set_speed(get_speed());
+     }
+    
+     direction get_direction()
+     {
+            return DIR;
+     }
+     
+     void set_speed(float speed)
+     {
+        SPEED = speed;
+        if(speed >= -1 && speed < 0)
+        {
+           if(get_direction() == CLOCKWISE) //ALLOW SOME TIME for the motor to change direction
+           {
+                *Output = 0;
+                //wait_ms(500);
+           }
+           
+           set_direction(ANTICLOCKWISE);
+           *Output = speed;
+        }
+        else if(speed >= 0 && speed <= 1)
+        {
+            if(get_direction() == CLOCKWISE) //ALLOW SOME TIME for the motor to change direction
+            {
+                *Output = 0;
+                //wait_ms(500);
+            }
+            
+            set_direction(CLOCKWISE);
+            *Output = speed;
+        }
+        
+      }
+      float get_speed()
+      {
+        return SPEED;
+      }
+      
+      void speed_inc()
+      {
+        if( (get_speed() + 0.1) <= 1)
+        set_speed(SPEED + 0.1);
+        else if( get_speed() + 0.1 > 1)
+        set_speed(1);        
+      }
+      
+      void speed_dec()
+      {
+        if( (get_speed() - 0.1) >= 0)
+        set_speed(SPEED - 0.1);
+        else if( get_speed() - 0.1 < 0)
+        set_speed(0);        
+        
+      }
+      
+      void change_direction()
+      {
+        if (get_direction() == CLOCKWISE)
+            set_direction(ANTICLOCKWISE);
+        else
+            set_direction(CLOCKWISE);
+      }
+            
+    
+    private:
+    //int PIN1,PIN2;
+    direction DIR;
+    PwmOut Out1;
+    PwmOut Out2;
+    PwmOut* Output;
+    
+
+    float SPEED;
+    
+ };
+
+
+char MOT_Return_chars[100]; //defined in accelerometer.h
+char Motor_command[100] = "";
+byte Motor_number = 0;
+
+extern BusOut leds;
+template<> OS_PROCESS void Motor_controller::Exec() //motor control handling process
+{
+    Motor_command[99] = '\0';
+   motor_control Motor1(p23,p24);
+   motor_control Motor2(p25,p26);
+   motor_control *M = &Motor1;
+   float motor_percentage = -1, motor_direction = 0.5, motor_strength = 0; //motor direction is a float from 0-1 which indicates the relative strength of one motor to the other the strength is the PWM output of the strongest motor as dictated by direction
+   direction PREV_DIR = CLOCKWISE;
+   
+   
+   
+   
+   char* pEND, *pEND2;
+   
+//MOT_channel      
+   for (;;)
+   {
+       
+       //OS::message<byte> MOTOR_message;
+       for(byte i = 0; i<100; i++)
+       {
+           MOT_channel.pop(Motor_command[i]); //if data is available, pop, else wait
+            leds = 0x5;
+            if(Motor_command[i] == '\0')  //keep popping chars until a delimiter is found
+                break;
+            else if(Motor_command[i] != '\0' && i == 99)
+                Motor_command[i] = '\0';
+                
+       }
+        
+        //sprintf(MOT_Return_chars, "a command was received.\n"); 
+       //TX_Channel.write(MOT_Return_chars, strlen(MOT_Return_chars)+1); //output the command for debugging
+       //TX_Channel.write(Motor_command, strlen(Motor_command) +1);
+            
+       //which motor?
+       //if (strlen(Servo_Command) >= 20 && strstr(Servo_Command,":Calibrate")) 
+        if(strstr(Motor_command, "MOT:") != NULL)
+           {
+           Motor_number = strtod(1+strstr(Motor_command, ":"), &pEND);
+           // motor_percentage = -1;
+          
+           //sprintf(output_chars, "motor number is: %d\n", Motor_number);
+           //TX_Channel.write(output_chars, strlen(output_chars)+1); //output the command for debugging
+           
+           
+               if(Motor_number < 2) // valid conversion
+                    {
+                        if(Motor_number == 0)
+                            M = &Motor1;
+                        else
+                            M = &Motor2;
+                        motor_percentage = strtod(1+pEND, &pEND2);
+                        //sprintf(output_chars, "percentage is: %f\n", motor_percentage);
+                        //TX_Channel.write(output_chars, strlen(output_chars)+1); //output the command for debugging
+                        M->set_speed(motor_percentage*(-1)); 
+                    } //end valid conversion check
+                } //end single MOT: command
+                
+                
+                else if(strstr(Motor_command, "MO2:") != NULL)
+                {
+                    motor_direction = strtod(&Motor_command[4], &pEND);
+                    if(motor_direction >= -1 && motor_direction <= 1)
+                    {                    
+                        motor_strength = strtod(1+pEND, &pEND2);
+                        if(motor_strength >= -1 && motor_strength <= 1)
+                        {
+                            //sprintf(output_chars, "Motor direction is: %f Motor strength is:%f\n", motor_direction, motor_strength);
+                            //TX_Channel.write(output_chars, strlen(output_chars)+1); //output the command for debugging
+                            if(motor_direction < 0)
+                            {
+                                Motor1.set_speed(motor_strength);
+                                Motor2.set_speed(motor_strength*abs(motor_direction)*2);
+                            }
+                            else if(motor_direction>0)
+                            {
+                                Motor2.set_speed(motor_strength);
+                                Motor1.set_speed(motor_strength*abs(motor_direction)*2);
+                            
+                            }
+                        }
+                    }
+                
+           }
+           leds = 0x5;
+   }
+   
+   
+    
+}  
+
+
+
+#endif
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/Mutexes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/Mutexes.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,14 @@
+
+#pragma once
+#ifndef MUTEXES_H
+#define MUTEXES_H
+
+//----------------------------------------------------------------------
+//This file defines the mutexes that are in use in this program
+
+OS::TMutex Serial_Mutex; //this Mutex is used to selectively give access to the serial port
+OS::TMutex XB_Mutex; //this Mutex is used to selectively give access to the XBEE serial port
+OS::TMutex Ser_out_Mutex; //serial output mutex
+
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b057566f9ee Hexacopter/PING_rangefinder.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/PING_rangefinder.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,203 @@
+#pragma once
+#ifndef PING_RANGEFINDER_H
+#define PING_RANGEFINDER_H
+
+#include <processes.h>
+#include <Mutexes.h>
+#include <channels.h>
+#define PINGPIN p22
+
+
+//DigitalOut led3(LED3); //these LEDs are used to indicate when an interrupt occurs.
+//DigitalOut led4(LED4);
+//byte count = 0;
+
+class rangefinder {
+public:
+    rangefinder()
+            :Pinterrupt(PINGPIN), PingPin(PINGPIN)
+     {
+            //led3 = ~(led4 = 0);
+            
+            time = 0;
+            enable_flag = false;
+            set_interrupts();
+            PingPin.mode(PullDown);
+            //Pinterrupt.mode(PullDown);
+    //        Pinterrupt.mode(PullUp);       
+            PingPin.output(); //set pingpin as output
+            PingPin = 0;
+    }
+
+    void ping() {
+        T.reset(); //reset the timer to 0
+        set_interrupts();
+        enable_flag = false;
+        PingPin.output(); //set as output
+        PingPin = 0; //output initiation sequence of 0 1 0 to the rangefinder
+        wait_us(2);
+        PingPin = 1;
+        wait_us(5);
+        PingPin = 0;
+        wait_us(1);
+        //printf("now waiting for input.\n");
+        PingPin.input(); //set as input
+        wait_us(10);
+        //set_interrupts();
+        enable_flag = true;
+        wait_ms(25); //more than required for maximum distance measurement
+        
+        
+        
+        //T.start(); //begin timing the length of time for an interrupt to occur
+    }
+    void set_interrupts()
+    {
+         Pinterrupt.fall(this, &rangefinder::set_time);
+         Pinterrupt.rise(this, &rangefinder::start_timing);
+    }
+    void disable_interrupts()
+    {
+         Pinterrupt.fall(NULL);
+         Pinterrupt.rise(NULL);
+    
+    } 
+    void start_timing() {  OS::TISRW ISRW;
+       if(enable_flag == true)
+       {
+           T.start();
+           //led3 = !led3;
+           //count++;       
+       }
+        
+        //printf("start_timing called.\n");
+    }
+
+    void set_time() { OS::TISRW ISRW;
+        if(enable_flag == true)
+        {
+            T.stop();
+            //led4 = !led4;
+            //disable_interrupts();
+            //enable_flag = false;
+            //printf("set_time being called...\n");
+            time = T.read_us();
+            //count++;
+        }
+                //printf("value stored in time %f: \n", time);
+        
+        //PingPin.output();
+        //PingPin = 0;
+        //printf("PING:%f\n",get_time());
+
+    }
+   
+
+
+    float get_time() {
+       //disable_interrupts();
+        return time/2.0;
+        
+    }
+
+   
+private:
+    Timer T;
+    float time; //time in us
+    InterruptIn Pinterrupt;
+    DigitalInOut PingPin;
+    bool enable_flag;
+    //Ticker TICKER;// send_ticker;
+    
+
+};
+
+
+
+
+
+
+
+
+
+
+extern BusOut leds;
+
+template<> OS_PROCESS void PING_PROC::Exec() //Output stream handling process
+{
+    byte M = 0;
+    rangefinder PING;
+ 
+
+char PIN_Return_chars[100]; //defined in accelerometer.h
+     
+     for(;;)
+     {
+       if(PING_MESSAGE.wait(80)) //length of time to wait also determines how rapidly to ticker ping
+       {    leds = 0x2;
+            M = PING_MESSAGE; //read the message that was destined for this process
+            PING_MESSAGE.reset();
+       
+           if(M == 0) //then ping! command was sent
+           {
+                {
+                    //OS::TISRW ISRW; //this is a critical section as timing is involved
+                    //this will not work though as it disables interrupts. 
+                    PING.ping();
+                }
+                
+                {   
+                    //TCritSect cs;
+                    sprintf(PIN_Return_chars, "PING:%f\n", PING.get_time()); //
+                 }
+                 //Ser_out_Mutex.Lock();
+                //if(TX_Channel.get_free_size() > strlen(Return_chars)+1)
+                    TX_channel.write(PIN_Return_chars, strlen(PIN_Return_chars)+1); //output the ping result
+                //Ser_out_Mutex.Unlock();
+                
+                
+           }
+       }
+       if(M == 1) //ticker ping
+       {
+            {
+                //OS::TISRW ISRW; //this is a critical section as timing is involved
+                PING.ping();
+            }
+            //Sleep(2);
+             {
+                //TCritSect cs;
+                sprintf(PIN_Return_chars, "PING:%f\n", PING.get_time()); //"PING:%f\n"
+              }
+              //Ser_out_Mutex.Lock();
+              //if(TX_Channel.get_free_size() > strlen(Return_chars)+1)
+               TX_channel.write(PIN_Return_chars, strlen(PIN_Return_chars)+1); //output the result
+              //Ser_out_Mutex.Unlock();
+             //TX_flag.Signal();
+            
+       }
+       
+              //PING_MESSAGE.reset();
+            
+        leds = 0x2;
+       
+     }
+}
+
+ 
+ #endif
+
+  //void enable_ticker() {
+    //    TICKER.attach_us(this, &rangefinder::ping, TX_RATE); //call ping() every 40 ms
+        //send_ticker.attach_us(this, &rangefinder::send_data, TX_RATE); //send the data out every 40 ms
+    //}
+    //void disable_ticker() {
+        //printf("ticker should now be detached.\n");
+    //    TICKER.detach();
+        //send_ticker.detach();
+    //}
+ 
+
+
+
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/Servo_Control.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/Servo_Control.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,89 @@
+#pragma once
+#ifndef SERVO_CONTROL_H
+#define SERVO_CONTROL_H
+//#include <processes.h>
+#include "Servo.h"
+
+#define SERVO_PIN p21
+extern BusOut leds;
+template<> OS_PROCESS void Servo_control::Exec() //serial stream handling process
+{
+   Servo Servo_object(SERVO_PIN);
+   char Servo_Command[100] = "";
+   Servo_Command[99] = '\0';     
+   float servo_position = 0, range = 0, degrees = 0;
+   char *pEnd;
+   //char output_chars[50] = "";
+   
+   for (;;)
+   {
+        
+       //Servo_Command_Event.Wait();
+       for(byte i = 0; i<100; i++)
+       {
+           SER_channel.pop(Servo_Command[i]);
+            leds = 0x6;
+            if(Servo_Command[i] == '\0')  //keep popping chars until a delimiter is found
+                break;
+            else if(Servo_Command[i] != '\0' && i == 99)
+                Servo_Command[i] = '\0';
+                
+       }
+             
+        //sprintf(output_chars, "a servo command was received:\n");
+        //TX_Channel.write(output_chars, strlen(output_chars)+1); //output the command for debugging
+        //TX_Channel.write(Servo_Command, strlen(Servo_Command)+1); //output the command for debugging
+        
+        if(strlen(Servo_Command) > 6)
+        {
+        
+            if (strlen(Servo_Command) >= 20 && strstr(Servo_Command,":Calibrate")) 
+            {    //Serv:Calibrate:range:degrees
+                   
+                    range = strtod(&Servo_Command[15], &pEnd);
+                    if (range >= 0 && range <= 1 && pEnd - &Servo_Command[15] != 0)
+                    {
+                        const char* deg = strstr(strstr(strstr(Servo_Command,":"),":"),":");
+                        degrees = strtod(deg+1, &pEnd);
+                        if (degrees >= -360 && range <= 360 && (pEnd - deg) != 0)
+                        {
+                            //printf("Received command: Serv:Calibrate:%f:%f. \n", range, degrees);
+                            Servo_object.calibrate(range,degrees);
+                        }
+                    }
+                
+            }
+            
+            else
+            {
+                servo_position = strtod(&Servo_Command[4], &pEnd); //&Servo_Command[5]
+                
+                //sprintf(output_chars, "servo position is %f\n", servo_position);         
+                //TX_Channel.write(output_chars, strlen(output_chars)+1); //output the command for debugging
+
+                if (servo_position >= 0 && servo_position <= 1 && (pEnd - &Servo_Command[4]) != 0) //the magic number 4 relates to the position in the string where the actual data should start
+                {
+                    Servo_object = servo_position;
+                }
+                else if (servo_position == -1) //sweep the position through range
+                {
+                    for(float p=0; p<1.0; p += 0.1)
+                       {
+                            Servo_object = p;
+                            Sleep(200);
+                       }
+                       
+                }
+             }
+        }
+        leds = 0x6;
+   }
+   
+   
+    
+}  
+
+
+
+#endif
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/accelerometer.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/accelerometer.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,197 @@
+#pragma once
+#ifndef ACCELEROMETER_H
+#define ACCELEROMETER_H
+
+#include <processes.h>
+#include <Mutexes.h>
+#include <channels.h>
+#define X_axis p28
+#define Y_axis p27
+
+//DigitalOut led3(LED3); //these LEDs are used to indicate when an interrupt occurs.
+//DigitalOut led4(LED4);
+
+
+class accelerometer {
+public:
+    accelerometer()
+            :X_int(X_axis),
+             Y_int(Y_axis)
+             //X_input(X_axis),
+             //Y_input(Y_axis)
+     {
+            //led3 = led4 = 0;
+            X_time = Y_time = 0;
+            //enable_flag = false;
+            enable_X_rising_flag = enable_X_falling_flag = enable_Y_rising_flag = enable_Y_falling_flag = false;
+            X_int.mode(PullDown);
+            Y_int.mode(PullDown);
+            //Y_input.mode(PullDown);
+            //X_input.mode(PullDown);
+            X_timer.reset();
+            Y_timer.reset();
+            set_interrupts();
+            enable_X_rising_flag = enable_Y_rising_flag = true;
+     }
+
+    
+    void set_interrupts()
+    {
+         X_int.fall(this, &accelerometer::set_X_time);
+         X_int.rise(this, &accelerometer::start_X_timing);
+         Y_int.fall(this, &accelerometer::set_Y_time);
+         Y_int.rise(this, &accelerometer::start_Y_timing);
+    }
+    
+    void start_X_timing() 
+    {
+         OS::TISRW ISRW;
+       if(enable_X_rising_flag == true)
+       {
+           X_timer.start();
+           enable_X_falling_flag = true;
+           //printf("In start_x_time().\n");
+           
+       }
+        
+        
+    }
+    void start_Y_timing() 
+    {   
+                 OS::TISRW ISRW;
+       if(enable_Y_rising_flag == true)
+       {
+           Y_timer.start();
+           enable_Y_falling_flag = true;
+
+       }
+        
+        
+    }
+
+    void set_X_time() {
+        if(enable_X_falling_flag == true)
+        {
+             OS::TISRW ISRW;
+            X_timer.stop();
+            X_time = X_timer.read_us();
+            X_timer.reset();
+            //                       led3 = !led3;
+                                   //printf("In set_x_time().\n");
+
+            
+        }
+    }
+    
+    
+    void set_Y_time() {
+        if(enable_Y_falling_flag == true)
+        {
+             OS::TISRW ISRW;
+            Y_timer.stop();
+            Y_time = Y_timer.read_us();
+           Y_timer.reset();
+              //                   led4 = !led4;
+
+            
+        }
+    }
+
+    float get_X_time() 
+    {
+       return X_time;
+    }
+    
+    float get_Y_time() 
+    {
+       return Y_time;
+    }
+
+   
+private:
+    Timer X_timer;
+    Timer Y_timer;
+    float X_time; //time in us
+    float Y_time;
+    InterruptIn X_int;
+    InterruptIn Y_int;
+    //DigitalIn X_input;
+    //DigitalIn Y_input;
+    bool enable_X_rising_flag;
+    bool enable_X_falling_flag;
+    bool enable_Y_rising_flag;
+    bool enable_Y_falling_flag;
+};
+
+
+
+
+
+
+
+
+extern BusOut leds;
+
+char ACC_Return_chars[100] = "";
+
+
+//typedef OS::process<OS::pr2, 1400> Accelo_proc;
+template<> OS_PROCESS void Accelo_proc::Exec() //Output stream handling process
+{
+   
+    accelerometer ACC;
+     
+     byte M = 0;
+     for(;;)
+     { 
+     if(ACCELEROMETER_MESSAGE.wait(70)) //length of time to wait also determines how rapidly to return accelerometer data
+       {    leds = 0x2;
+            M = ACCELEROMETER_MESSAGE; //read the message that was destined for this process
+            ACCELEROMETER_MESSAGE.reset();
+       
+           if(M == 0) //then return x and y data once
+           {
+                sprintf(ACC_Return_chars, "ACC_X:%f\nACC_Y:%f\n", ACC.get_X_time(), ACC.get_Y_time()); // ready return string
+                //if(!Ser_out_Mutex.IsLocked())
+                {
+                    //Ser_out_Mutex.Lock();
+                    //if(TX_Channel.get_free_size() > strlen(Return_chars)+1)
+                        TX_channel.write(ACC_Return_chars, strlen(ACC_Return_chars)+1); //output the data!
+                    //Ser_out_Mutex.Unlock();
+                }    
+                
+                
+                
+           }
+       }
+       if(M == 1) //ticker
+       {
+             
+              {
+                //TCritSect cs;
+                sprintf(ACC_Return_chars, "ACC_X:%f\nACC_Y:%f\n", ACC.get_X_time(), ACC.get_Y_time()); // ready return string //"ACC_X:%f\nACC_Y:%f\n"
+               }
+                //if(!Ser_out_Mutex.IsLocked())
+                {
+                    //Ser_out_Mutex.Lock();
+                    //if(TX_Channel.get_free_size() > strlen(Return_chars)+1)
+                         TX_channel.write(ACC_Return_chars, strlen(ACC_Return_chars)+1); //output the data!
+                    //Ser_out_Mutex.Unlock();
+                }
+              //TX_flag.Signal();
+            
+       }   
+
+            leds = 0x2;
+        
+       
+     }
+}
+
+ 
+ #endif
+
+  
+
+
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/channels.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/channels.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,17 @@
+#pragma once
+#ifndef CHANNELS_H
+#define CHANNELS_H
+
+//--------------------------------------------------------------------------------------------
+//define the channels that are going to be used in the program
+       // command channel
+
+OS::channel<char, 100> RX_channel;
+OS::channel<char, 100> SER_channel;
+OS::channel<char, 100> MOT_channel;
+OS::channel<char, 100> TX_channel;
+
+
+
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b057566f9ee Hexacopter/event_flags.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/event_flags.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,18 @@
+#pragma once
+#ifndef EVENT_FLAGS_H
+#define EVENT_FLAGS_H
+
+//---------------------------------------------------------------------------
+//
+//      Event Flags to test
+//
+OS::TEventFlag ef;
+//OS::TEventFlag RX_flag; //this signals the command_handler process
+//OS::TEventFlag TX_flag; //signals the serial_out process
+OS::TEventFlag timerEvent;
+//OS::TEventFlag Servo_Command_Event; //signals the servo_control process that there is a new command
+
+
+
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b057566f9ee Hexacopter/messages.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/messages.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,17 @@
+//-----------------------------------------------------------------
+//file containing the os::message list used in the program
+
+#pragma once
+#ifndef MESSAGES_H
+#define MESSAGES_H
+
+//--------------------------------------------------------------------------------------------
+//define the channels that are going to be used in the program
+       // command channel
+
+OS::message<byte> PING_MESSAGE; //if message is a zero, then PING once, if a 1 then Ticker ping
+OS::message<byte> ACCELEROMETER_MESSAGE; //if message is a zero, then return acceleration once, if a 1 then continually return acceleration data
+//OS::message<float> MOTOR_message;
+
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 9b057566f9ee Hexacopter/processes.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/processes.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,105 @@
+#pragma once
+
+#ifndef PROCESSES_H
+#define PROCESSES_H
+#include <event_flags.h>
+//#include <Servo_Control.h>
+
+//      Process types
+//
+
+/*
+typedef OS::process<OS::pr0, 1400> PING_PROC;
+typedef OS::process<OS::pr1, 1000> TProc2;
+typedef OS::process<OS::pr2, 3000> Accelo_proc;
+typedef OS::process<OS::pr3, 1000> Servo_control;
+typedef OS::process<OS::pr4, 3000> Command_handler;
+typedef OS::process<OS::pr5, 1000> Motor_controller;
+typedef OS::process<OS::pr6, 4000> Serial_Out;
+*/
+
+typedef OS::process<OS::pr0, 2000> PING_PROC;
+typedef OS::process<OS::pr1, 1400> TProc2;
+typedef OS::process<OS::pr2, 3000> Accelo_proc;
+typedef OS::process<OS::pr3, 2000> Servo_control;
+typedef OS::process<OS::pr4, 3000> Command_handler;
+typedef OS::process<OS::pr5, 2000> Motor_controller;
+typedef OS::process<OS::pr6, 4000> Serial_Out;
+
+//typedef OS::process<OS::pr3, 300> TProc4;
+
+//---------------------------------------------------------------------------
+//
+//      Process objects
+//
+PING_PROC PING_PROCESS;
+TProc2 Proc2;
+Accelo_proc Accelerometer_process;
+Servo_control Servo_process;
+Command_handler Com_Handler;
+Serial_Out Serial_Out_Proc;
+Motor_controller M_cont_process;
+
+//---------------------------------------------------------------------------
+
+
+
+//      IO Pins
+//
+//DigitalOut led1(LED1);
+//DigitalOut led2(LED2);
+
+
+//---------------------------------------------------------------------------
+ 
+
+//---------------------------------------------------------------------------
+//extra declarations
+
+
+
+
+
+
+
+
+BusOut leds(LED1, LED2, LED3, LED4);
+
+
+//---------------------------------------------------------------------------
+template<> OS_PROCESS void TProc2::Exec()
+{
+    for(;;)
+    {
+        Sleep(500); //suspend process
+        //printf("e\n");
+        //led1 = !led1;
+        //leds = 0x1;
+    }
+}
+
+//---------------------------------------------------------------------------
+
+
+
+void OS::SystemTimerUserHook()
+{
+    static int cnt=0;
+    if (++cnt == 2000)
+    {
+        cnt = 0;
+        //led2.write(1);
+        timerEvent.SignalISR();
+    }
+}
+
+//---------------------------------------------------------------------------
+void OS::IdleProcessUserHook()
+{
+    __WFI(); //sleep the ucontroller and wait for interrupt
+}
+//-----------------------------------------------------------------------------
+
+#endif
+
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/serial.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/serial.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,97 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+#include <channels.h>
+#include <Mutexes.h>
+#include <processes.h>
+
+#define UART1TX p9
+#define UART1RX p10
+
+Serial USB(USBTX, USBRX); // tx, rx
+Serial XB(UART1TX, UART1RX); // tx, rx
+Serial *OUT = &USB; //intially set to USB
+
+extern BusOut leds;
+ void USB_serial() //signal RTOS event that RXinterrupt has been asserted
+{
+    OS::TISRW ISRW;
+    leds = 0x7;
+    //char count = 0;
+    //led3 = !led3;
+    char temp = 0;    
+    
+    //leds = 0xa;
+    if(true)//!Serial_Mutex.IsLocked())
+    {
+        //leds = 0xb;
+        //Serial_Mutex.Lock();
+        leds = 0xc;
+        if(USB.readable())
+        {
+            temp = USB.getc(); 
+            leds = 0xd;
+
+            if(RX_channel.get_free_size() >0 ) //only push a character onto the channel if there is free space
+            {    
+                //OUT = &USB;              
+                if(temp != '\n')
+                {                    
+                    RX_channel.push(temp);
+                    leds = 0xe;                    
+                }
+                else if(temp == '\n')
+                {                     
+                    RX_channel.push('\0');                    
+                }
+            }
+            else USB.getc(); //start discarding characters!*/
+         leds = 0xf;
+         leds = 0xa;            
+        }   
+        leds = 0xb;
+       //Serial_Mutex.Unlock();
+       //Serial_Mutex.Lock();
+       //if(USB.writeable())
+        //USB.putc(temp);
+           //Serial_Mutex.Unlock();
+       leds = 0x1;
+     }
+     else USB.getc(); //start discarding characters!
+        
+   leds = 0x9;
+}
+
+/*void XB_serial() 
+{
+    //led4 = !led4;
+    char temp = 0;    
+    OS::TISRW ISRW;
+    if(!XB_Mutex.IsLocked())
+    {
+        XB_Mutex.Lock();
+        while(XB.readable())
+        {
+            temp = XB.getc();  
+            if(RX_channel.get_free_size() >0 ) //only push a character onto the channel if there is free space
+            {                  
+                OUT = &XB;
+                if(temp != '\n')
+                {                    
+                    RX_channel.push(temp);                    
+                 }
+                else if(temp == '\n')
+                {
+                    OUT = &XB;                        
+                    RX_channel.push('\0');                    
+                }
+            }
+            else temp = XB.getc(); //otherwise, wait until another character is sent and try then
+        }   
+        XB_Mutex.Unlock();
+     } 
+         
+   
+}*/
+
+#endif
+
diff -r 000000000000 -r 9b057566f9ee Hexacopter/serial_out.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexacopter/serial_out.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,60 @@
+#pragma once
+#ifndef SERIAL_OUT_H
+#define SERIAL_OUT_H
+#include <processes.h>
+#include <Mutexes.h>
+#include <channels.h>
+#include <serial.h>
+//DigitalOut led3(LED3);
+extern BusOut leds;
+template<> OS_PROCESS void Serial_Out::Exec() //Output stream handling process
+{
+
+
+     char temp1 = 0;
+     //led3 = 0;
+     //char buf[50] = "output process working.\n";
+     for(;;)
+     {
+               //Sleep(500);
+               TX_channel.pop(temp1); 
+                      leds = 0x8;              
+               //wait_ms(200); //simulate delays
+               //Sleep(10);
+               //led3 = !led3; 
+               //OUT->printf(buf);
+               //if(OUT == &USB)
+               //{
+                   //Serial_Mutex.Lock();
+                   //XB_Mutex.Lock();
+                   if(OUT->writeable())
+                   {
+                     OUT->putc(temp1);
+                     
+                    
+                     
+                     
+                     
+                     //XB_Mutex.Unlock();
+                   }
+                   else
+                   {
+                    //TX_channel.push_front(temp1);
+                    //OUT->printf("output is not writeable!\n");
+                    //Sleep(0.5); //sleep 
+                   }
+                   //Serial_Mutex.Unlock();
+              //}
+              
+               
+           
+                      leds = 0x8;
+           
+     }
+}
+
+ 
+ #endif
+
+ 
+ 
diff -r 000000000000 -r 9b057566f9ee Servo.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Servo.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,74 @@
+/* mbed R/C Servo Library
+ *  
+ * Copyright (c) 2007-2010 sford, cstyles
+ *
+ * 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.
+ */
+ 
+#include "Servo.h"
+#include "mbed.h"
+
+static float clamp(float value, float min, float max) {
+    if(value < min) {
+        return min;
+    } else if(value > max) {
+        return max;
+    } else {
+        return value;
+    }
+}
+
+Servo::Servo(PinName pin) : _pwm(pin) {
+    calibrate();
+    write(0.5);
+}
+
+void Servo::write(float percent) {
+    float offset = _range * 2.0 * (percent - 0.5);
+    _pwm.pulsewidth(0.0015 + clamp(offset, -_range, _range));
+    _p = clamp(percent, 0.0, 1.0);
+}
+
+void Servo::position(float degrees) {
+    float offset = _range * (degrees / _degrees);
+    _pwm.pulsewidth(0.0015 + clamp(offset, -_range, _range));
+}
+
+void Servo::calibrate(float range, float degrees) {
+    _range = range;
+    _degrees = degrees;
+}
+
+float Servo::read() {
+    return _p;
+}
+
+Servo& Servo::operator= (float percent) { 
+    write(percent);
+    return *this;
+}
+
+Servo& Servo::operator= (Servo& rhs) {
+    write(rhs.read());
+    return *this;
+}
+
+Servo::operator float() {
+    return read();
+}
diff -r 000000000000 -r 9b057566f9ee Servo.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Servo.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,98 @@
+/* mbed R/C Servo Library
+ * Copyright (c) 2007-2010 sford, cstyles
+ *
+ * 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.
+ */
+  
+#ifndef MBED_SERVO_H
+#define MBED_SERVO_H
+
+#include "mbed.h"
+
+/** Servo control class, based on a PwmOut
+ *
+ * Example:
+ * @code
+ * // Continuously sweep the servo through it's full range
+ * #include "mbed.h"
+ * #include "Servo.h"
+ * 
+ * Servo myservo(p21);
+ * 
+ * int main() {
+ *     while(1) {
+ *         for(int i=0; i<100; i++) {
+ *             myservo = i/100.0;
+ *             wait(0.01);
+ *         }
+ *         for(int i=100; i>0; i--) {
+ *             myservo = i/100.0;
+ *             wait(0.01);
+ *         }
+ *     }
+ * }
+ * @endcode
+ */
+class Servo {
+
+public:
+    /** Create a servo object connected to the specified PwmOut pin
+     *
+     * @param pin PwmOut pin to connect to 
+     */
+    Servo(PinName pin);
+    
+    /** Set the servo position, normalised to it's full range
+     *
+     * @param percent A normalised number 0.0-1.0 to represent the full range.
+     */
+    void write(float percent);
+    
+    /**  Read the servo motors current position
+     *
+     * @param returns A normalised number 0.0-1.0  representing the full range.
+     */
+    float read();
+    
+    /** Set the servo position
+     *
+     * @param degrees Servo position in degrees
+     */
+    void position(float degrees);
+    
+    /**  Allows calibration of the range and angles for a particular servo
+     *
+     * @param range Pulsewidth range from center (1.5ms) to maximum/minimum position in seconds
+     * @param degrees Angle from centre to maximum/minimum position in degrees
+     */
+    void calibrate(float range = 0.0005, float degrees = 45.0); 
+        
+    /**  Shorthand for the write and read functions */
+    Servo& operator= (float percent);
+    Servo& operator= (Servo& rhs);
+    operator float();
+
+protected:
+    PwmOut _pwm;
+    float _range;
+    float _degrees;
+    float _p;
+};
+
+#endif
diff -r 000000000000 -r 9b057566f9ee main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,89 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   RVCT (ARM)
+//*
+//*     PURPOSE:   Port Test File
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 196 $
+//*     $Date:: 2010-09-09 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     mbed port by Igor Skochinsky
+
+#include <mbed.h>
+#include <scmRTOS.h>
+#include <processes.h>
+#include <serial.h>
+#include <Command_handler.h>
+#include <event_flags.h>
+#include <Servo_Control.h>
+#include <serial_out.h>
+#include <PING_rangefinder.h>
+#include <Motor_control.h>
+#include <accelerometer.h>
+//---------------------------------------------------------------------------
+//
+
+//
+
+    
+
+
+
+//
+int main()
+{
+    
+    USB.baud(921600);
+    USB.attach(USB_serial);
+    //XB.baud(115200);
+    //XB.attach(XB_serial);
+    // configure IO pins
+    //led1.write(0);
+    //led2.write(0);
+    
+    // run
+    OS::Run();
+}
+
+
+
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/OS_Kernel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/OS_Kernel.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,115 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  OS Kernel Source
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#include "scmRTOS.h"
+
+using namespace OS;
+//------------------------------------------------------------------------------
+OS::TKernel OS::Kernel;
+
+//------------------------------------------------------------------------------
+#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
+void TKernel::Sched()
+{
+    byte NextPrty = GetHighPriority(ReadyProcessMap);
+    if(NextPrty != CurProcPriority)
+    {
+        TStackItem*  Next_SP = ProcessTable[NextPrty]->StackPointer;
+        TStackItem** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer);
+        CurProcPriority = NextPrty;
+        OS_ContextSwitcher(Curr_SP_addr, Next_SP);
+    }
+}
+#else
+//------------------------------------------------------------------------------
+void TKernel::Sched()
+{
+    byte NextPrty = GetHighPriority(ReadyProcessMap);
+    if(NextPrty != CurProcPriority)
+    {
+        SchedProcPriority = NextPrty;
+    
+        RaiseContextSwitch();
+        do
+        {
+            EnableContextSwitch();
+            DUMMY_INSTR();
+            DisableContextSwitch();
+        } 
+        while(!IsContextSwitchDone());
+    }
+}
+//------------------------------------------------------------------------------
+TStackItem* OS_ContextSwitchHook(TStackItem* sp) { return OS::Kernel.ContextSwitchHook(sp); }
+//------------------------------------------------------------------------------
+#endif // scmRTOS_CONTEXT_SWITCH_SCHEME
+//------------------------------------------------------------------------------
+void TBaseProcess::Sleep(TTimeout timeout)
+{
+    TCritSect cs;
+
+    Kernel.ProcessTable[Kernel.CurProcPriority]->Timeout = timeout;
+    Kernel.SetProcessUnready(Kernel.CurProcPriority);
+    Kernel.Scheduler();
+}
+//------------------------------------------------------------------------------
+void OS::WakeUpProcess(TBaseProcess& p)
+{
+    TCritSect cs;
+
+    if(p.Timeout)
+    {
+        p.Timeout = 0;
+        Kernel.SetProcessReady(p.Priority);
+        Kernel.Scheduler();
+    }
+}
+//------------------------------------------------------------------------------
+void OS::ForceWakeUpProcess(TBaseProcess& p)
+{
+    TCritSect cs;
+
+    p.Timeout = 0;
+    Kernel.SetProcessReady(p.Priority);
+    Kernel.Scheduler();
+}
+//------------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/OS_Kernel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/OS_Kernel.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,426 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  OS Kernel Header. Declarations And Definitions
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c)c 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person
+//*     obtaining  a copy of this software and associated documentation
+//*     files (the "Software"), to deal in the Software without restriction,
+//*     including without limitation the rights to use, copy, modify, merge,
+//*     publish, distribute, sublicense, and/or sell copies of the Software,
+//*     and to permit persons to whom the Software is furnished to do so,
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//*****************************************************************************
+
+#ifndef OS_KERNEL_H
+#define OS_KERNEL_H
+
+#include <stddef.h>
+#include <commdefs.h>
+#include <usrlib.h>
+
+//------------------------------------------------------------------------------
+
+//==============================================================================
+extern "C" void OS_Start(TStackItem* sp);
+
+#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
+    extern "C" void OS_ContextSwitcher(TStackItem** Curr_SP, TStackItem* Next_SP);
+#else
+    extern "C" TStackItem* OS_ContextSwitchHook(TStackItem* sp);
+#endif
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+//
+//
+//     NAME       :   OS
+//
+//     PURPOSE    :   Namespace for all OS stuff
+//
+//     DESCRIPTION:   Includes:  Kernel,
+//                               Processes,
+//                               Mutexes,
+//                               Event Flags,
+//                               Byte-wide Channels,
+//                               Arbitrary-type Channels,
+//                               Messages
+//
+namespace OS
+{
+    class TBaseProcess;
+
+    INLINE inline void SetPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm |=  PrioTag; }
+    INLINE inline void ClrPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm &= ~PrioTag; }
+
+    //--------------------------------------------------------------------------
+    //
+    //     NAME       :   TKernel
+    //
+    ///  Implements kernel-level operations such as
+    ///  process management, process-level scheduling,
+    ///  ISR-level scheduling, system timing.
+    //
+    //     DESCRIPTION:
+    //
+    //
+    class TKernel
+    {
+        //-----------------------------------------------------------
+        //
+        //     Declarations
+        //
+        
+
+        friend class TISRW;
+        friend class TISRW_SS;
+        friend class TBaseProcess;
+        friend class TMutex;
+        friend class TEventFlag;
+        friend class TChannel;
+        friend class TBaseMessage;
+
+        template<typename T, word size, class S> friend class channel;
+        template<typename T>                     friend class message;
+
+        friend void          Run();
+        friend void          WakeUpProcess(TBaseProcess& p);
+        friend void          ForceWakeUpProcess(TBaseProcess& p);
+        friend inline bool   IsProcessSleeping(const TBaseProcess& p);
+        friend inline bool   IsProcessSuspended(const TBaseProcess& p);
+        friend inline dword  GetTickCount();
+
+        //-----------------------------------------------------------
+        //
+        //      Data
+        //
+    private:
+        byte CurProcPriority;
+        TProcessMap ReadyProcessMap;
+        TBaseProcess* ProcessTable[scmRTOS_PROCESS_COUNT+1];
+        volatile byte ISR_NestCount;
+
+    #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
+        byte SchedProcPriority;
+    #endif
+
+    #if scmRTOS_SYSTEM_TICKS_ENABLE == 1
+        volatile dword SysTickCount;
+    #endif
+
+    //-----------------------------------------------------------
+    //
+    //      Functions
+    //
+    public:
+        INLINE TKernel()
+            : CurProcPriority(pr0)
+            , ReadyProcessMap( (1 << (scmRTOS_PROCESS_COUNT + 1)) - 1)  // set all processes ready
+            , ISR_NestCount(0)
+        {
+        }
+
+    private:
+        INLINE inline void RegisterProcess(TBaseProcess* const p);
+
+        void Sched();
+        INLINE void Scheduler() { if(ISR_NestCount) return; else  Sched(); }
+        INLINE inline void SchedISR();
+
+    #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
+        INLINE inline bool IsContextSwitchDone() const volatile;
+    #endif
+        INLINE void SetProcessReady  (const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); SetPrioTag( ReadyProcessMap, PrioTag); }
+        INLINE void SetProcessUnready(const byte pr) { TProcessMap PrioTag = GetPrioTag(pr); ClrPrioTag( ReadyProcessMap, PrioTag); }
+
+    public:
+        INLINE inline void SystemTimer();
+    #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
+        INLINE inline TStackItem* ContextSwitchHook(TStackItem* sp);
+    #endif
+
+    };  // End of TKernel class definition
+    //--------------------------------------------------------------------------
+    extern TKernel Kernel;
+
+    //--------------------------------------------------------------------------
+    //
+    /// BaseProcess
+    ///
+    /// Implements base class-type for application processes
+    //
+    //      DESCRIPTION:
+    //
+    //
+    class TBaseProcess
+    {
+        friend class TKernel;
+        friend class TISRW;
+        friend class TISRW_SS;
+        friend class TEventFlag;
+        friend class TMutex;
+        friend class TBaseMessage;
+
+        template<typename T, word size, class S> friend class channel;
+        template<typename T>                     friend class message;
+
+
+        friend void         Run();
+        friend void         WakeUpProcess(TBaseProcess& p);
+        friend void         ForceWakeUpProcess(TBaseProcess& p);
+        friend bool         IsProcessSleeping(const TBaseProcess& p);
+        friend bool         IsProcessSuspended(const TBaseProcess& p);
+
+    public:
+    #if SEPARATE_RETURN_STACK == 0
+        TBaseProcess( TStackItem* Stack, TPriority pr, void (*exec)() );
+    #else
+        TBaseProcess( TStackItem* Stack, TStackItem* RStack, TPriority pr, void (*exec)() );
+    #endif
+
+        static void Sleep(TTimeout timeout = 0);
+
+    protected:
+        TStackItem* StackPointer;
+        TTimeout Timeout;
+        TPriority Priority;
+    };
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    ///  process
+    ///
+    ///  Implements template for application processes instantiation
+    //
+    //      DESCRIPTION:
+    //
+    //
+    #if SEPARATE_RETURN_STACK == 0
+
+        template<TPriority pr, word stack_size>
+        class process : public TBaseProcess
+        {
+        public:
+            INLINE_PROCESS_CTOR process();
+
+            OS_PROCESS static void Exec();
+
+        private:
+            TStackItem Stack[stack_size/sizeof(TStackItem)];
+        };
+
+        template<TPriority pr, word stack_size>
+        OS::process<pr, stack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)]
+                                                              , pr
+                                                              , reinterpret_cast<void (*)()>(Exec) )
+        {
+        }
+
+    #else
+
+        template<TPriority pr, word stack_size, word rstack_size>
+        class process : public TBaseProcess
+        {
+        public:
+            INLINE_PROCESS_CTOR process();
+
+            OS_PROCESS static void Exec();
+
+        private:
+            TStackItem Stack [stack_size/sizeof(TStackItem)];
+            TStackItem RStack[rstack_size/sizeof(TStackItem)];
+        };
+
+        template<TPriority pr, word stack_size, word rstack_size>
+        process<pr, stack_size, rstack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(TStackItem)]
+                                                                      , &RStack[rstack_size/sizeof(TStackItem)]
+                                                                      , pr
+                                                                      , reinterpret_cast<void (*)()>(Exec))
+        {
+        }
+
+    #endif
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    //       Miscellaneous
+    //
+    //
+    INLINE inline void Run();
+    INLINE inline void LockSystemTimer()   { TCritSect cs; LOCK_SYSTEM_TIMER();   }
+    INLINE inline void UnlockSystemTimer() { TCritSect cs; UNLOCK_SYSTEM_TIMER(); }
+    void WakeUpProcess(TBaseProcess& p);
+    void ForceWakeUpProcess(TBaseProcess& p);
+    INLINE inline void Sleep(TTimeout t = 0) { TBaseProcess::Sleep(t); }
+
+    INLINE inline bool IsProcessSleeping(const TBaseProcess& p)
+    {
+        TCritSect cs;
+        if(p.Timeout)
+            return true;
+        else
+            return false;
+    }
+
+    INLINE inline bool IsProcessSuspended(const TBaseProcess& p)
+    {
+        TCritSect cs;
+        if(Kernel.ReadyProcessMap & GetPrioTag(p.Priority))
+            return false;
+        else
+            return true;
+    }
+    //--------------------------------------------------------------------------
+
+#if scmRTOS_SYSTEM_TICKS_ENABLE == 1
+    INLINE inline dword GetTickCount() { TCritSect cs; return Kernel.SysTickCount; }
+#endif
+
+#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
+    INLINE_SYS_TIMER_HOOK void  SystemTimerUserHook();
+#endif
+
+#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
+    INLINE_CONTEXT_SWITCH_HOOK void  ContextSwitchUserHook();
+#endif
+    
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//
+///  Register Process
+///
+///  Places pointer to process in kernel's process table
+//
+void OS::TKernel::RegisterProcess(OS::TBaseProcess* const p)
+{
+    ProcessTable[p->Priority] = p;
+}
+//------------------------------------------------------------------------------
+//
+/// System Timer Implementation
+///
+/// Performs process's timeouts checking and
+///               moving processes to ready-to-run state
+//
+void OS::TKernel::SystemTimer()
+{
+    SYS_TIMER_CRIT_SECT();
+#if scmRTOS_SYSTEM_TICKS_ENABLE == 1
+    SysTickCount++;
+#endif
+
+#if scmRTOS_PRIORITY_ORDER == 0
+    const byte BaseIndex = 0;
+#else
+    const byte BaseIndex = 1;
+#endif
+
+    for(byte i = BaseIndex; i < (scmRTOS_PROCESS_COUNT + BaseIndex); i++)
+    {
+        TBaseProcess* p = ProcessTable[i];
+
+        if(p->Timeout > 0)
+        {
+            if(--p->Timeout == 0)
+            {
+                SetProcessReady(p->Priority);
+            }
+        }
+    }
+}
+//------------------------------------------------------------------------------
+//
+///    ISR optimized scheduler
+///
+///    !!! IMPORTANT: This function must be call from ISR services only !!!
+//
+//
+#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
+void OS::TKernel::SchedISR()
+{
+    byte NextPrty = GetHighPriority(ReadyProcessMap);
+    if(NextPrty != CurProcPriority)
+    {
+        TStackItem*  Next_SP = ProcessTable[NextPrty]->StackPointer;
+        TStackItem** Curr_SP_addr = &(ProcessTable[CurProcPriority]->StackPointer);
+        CurProcPriority = NextPrty;
+        OS_ContextSwitcher(Curr_SP_addr, Next_SP);
+    }
+}
+#else
+void OS::TKernel::SchedISR()
+{
+    byte NextPrty = GetHighPriority(ReadyProcessMap);
+    if(NextPrty != CurProcPriority)
+    {
+        SchedProcPriority    = NextPrty;
+        RaiseContextSwitch();
+    }
+}
+//------------------------------------------------------------------------------
+bool OS::TKernel::IsContextSwitchDone() const volatile
+{
+     byte cur    = CurProcPriority;    ///< reading to temporary vars is performed due to
+     byte sched  = SchedProcPriority;  ///< suppress warning about order of volatile access
+     return cur == sched;
+}
+//------------------------------------------------------------------------------
+TStackItem* OS::TKernel::ContextSwitchHook(TStackItem* sp)
+{
+    ProcessTable[CurProcPriority]->StackPointer = sp;
+    sp = ProcessTable[SchedProcPriority]->StackPointer;
+
+#if scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE == 1
+    ContextSwitchUserHook();
+#endif 
+
+    CurProcPriority = SchedProcPriority;
+    return sp;
+}
+//------------------------------------------------------------------------------
+#endif // scmRTOS_CONTEXT_SWITCH_SCHEME
+
+//-----------------------------------------------------------------------------
+/// Start Operation
+INLINE inline void OS::Run()
+{
+    TStackItem* sp = Kernel.ProcessTable[pr0]->StackPointer;
+    OS_Start(sp);
+}
+
+#include <OS_Services.h>
+
+#endif // OS_KERNEL_H
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/OS_Services.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/OS_Services.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,298 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  OS Services Source
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person
+//*     obtaining  a copy of this software and associated documentation
+//*     files (the "Software"), to deal in the Software without restriction,
+//*     including without limitation the rights to use, copy, modify, merge,
+//*     publish, distribute, sublicense, and/or sell copies of the Software,
+//*     and to permit persons to whom the Software is furnished to do so,
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#include "scmRTOS.h"
+
+using namespace OS;
+
+//------------------------------------------------------------------------------
+//
+//
+//      TEventFlag
+//
+//
+bool OS::TEventFlag::Wait(TTimeout timeout)
+{
+    TCritSect cs;
+
+    if(Value)                                           // if flag already signaled
+    {
+        Value = efOff;                                  // clear flag
+        return true;
+    }
+    else
+    {
+        TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
+        p->Timeout = timeout;
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+
+        SetPrioTag(ProcessMap, PrioTag);                // put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);    // remove current process from the ready map
+
+        Kernel.Scheduler();
+
+        p->Timeout = 0;
+
+        if( !(ProcessMap & PrioTag) )                   // if waked up by signal() or signal_ISR()
+            return true;
+
+        ClrPrioTag(ProcessMap, PrioTag);                // otherwise waked up by timeout or by
+        return false;                                   // OS::ForceWakeUpProcess(), remove process from the wait map
+    }
+}
+//------------------------------------------------------------------------------
+void OS::TEventFlag::Signal()
+{
+    TCritSect cs;
+    if(ProcessMap)                                          // if any process waits for event
+    {
+        TProcessMap Timeouted = Kernel.ReadyProcessMap;     // Process has its tag set in ReadyProcessMap if timeout expired
+                                                            // or it was waked up by OS::ForceWakeUpProcess()
+
+        if( ProcessMap & ~Timeouted )                       // if any process has to be waked up
+        {
+            SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
+            ClrPrioTag(ProcessMap, ~Timeouted);             // remove all non-timeouted processes from the waiting map.
+                                                            // Used to check that process waked up by signal() or signalISR()
+                                                            // and not by timeout or OS::ForceWakeUpProcess()
+            Kernel.Scheduler();
+            return;
+        }
+    }
+    Value = efOn;
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//
+//
+//      TMutex
+//
+//
+void OS::TMutex::Lock()
+{
+    TCritSect cs;
+
+    TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+    while(ValueTag)
+    {
+        SetPrioTag(ProcessMap, PrioTag);             // mutex already locked by another process, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
+
+        Kernel.Scheduler();
+    }
+    ValueTag = PrioTag;                              // mutex has been successfully locked
+}
+//------------------------------------------------------------------------------
+void OS::TMutex::Unlock()
+{
+    TCritSect cs;
+
+    TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+    if(ValueTag != PrioTag) return;                  // the only process that had locked mutex can unlock the mutex
+    ValueTag = 0;
+    if(ProcessMap)
+    {
+        byte pr = GetHighPriority(ProcessMap);
+        PrioTag = GetPrioTag(pr);
+        ClrPrioTag(ProcessMap, PrioTag);             // remove next ready process from the wait map
+        SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
+        Kernel.Scheduler();
+    }
+}
+//------------------------------------------------------------------------------
+void OS::TMutex::UnlockISR()
+{
+    TCritSect cs;
+
+    ValueTag = 0;
+    if(ProcessMap)
+    {
+        byte pr = GetHighPriority(ProcessMap);
+        TProcessMap PrioTag = GetPrioTag(pr);
+        ClrPrioTag(ProcessMap, PrioTag);             // remove next ready process from the wait map
+        SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
+    }
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//
+//
+//      TChannel
+//
+//
+void OS::TChannel::CheckWaiters(TProcessMap& pm)
+{
+    if(pm)
+    {
+        byte pr = GetHighPriority(pm);
+        TProcessMap PrioTag = GetPrioTag(pr);
+        ClrPrioTag(pm, PrioTag);                     // remove next ready process from the wait map
+        SetPrioTag(Kernel.ReadyProcessMap, PrioTag); // place next process to the ready map
+        Kernel.Scheduler();
+    }
+}
+//------------------------------------------------------------------------------
+void OS::TChannel::Push(byte x)
+{
+    TCritSect cs;
+
+    while (!Cbuf.get_free_size())
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag  (ProducersProcessMap, PrioTag);  // channel is full, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
+        Kernel.Scheduler();                          // wait until waked-up by Pop() or Read()
+    }
+
+    Cbuf.put(x);
+    CheckWaiters(ConsumersProcessMap);
+}
+//------------------------------------------------------------------------------
+byte OS::TChannel::Pop()
+{
+    TCritSect cs;
+    byte x;
+
+    while(!Cbuf.get_count())
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ConsumersProcessMap, PrioTag);    // channel is empty, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
+        Kernel.Scheduler();                          // wait until waked up by Push() or Write()
+    }
+    x = Cbuf.get();
+    CheckWaiters(ProducersProcessMap);
+    return x;
+}
+//------------------------------------------------------------------------------
+void OS::TChannel::Write(const byte* data, const byte count)
+{
+    TCritSect cs;
+
+    while(Cbuf.get_free_size() < count)
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ProducersProcessMap, PrioTag);    // channel has not enough space, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
+        Kernel.Scheduler();                          // wait until waked up by Read() or Pop()
+    }
+
+    Cbuf.write(data, count);
+    CheckWaiters(ConsumersProcessMap);
+}
+//------------------------------------------------------------------------------
+void OS::TChannel::Read(byte* const data, const byte count)
+{
+    TCritSect cs;
+
+    while(Cbuf.get_count() < count)
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ConsumersProcessMap, PrioTag);    // channel doesn't contain enough data, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag); // remove current process from the ready map
+        Kernel.Scheduler();                          // wait until waked up by Write() or Push()
+    }
+
+    Cbuf.read(data, count);
+    CheckWaiters(ProducersProcessMap);
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//
+//              OS::message template
+//
+//          Function-members implementation
+//
+//
+//------------------------------------------------------------------------------
+bool OS::TBaseMessage::wait(TTimeout timeout)
+{
+    TCritSect cs;
+
+    if(NonEmpty)                                                  // message alredy send
+    {
+        NonEmpty = false;
+        return true;
+    }
+    else
+    {
+        TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
+        p->Timeout = timeout;
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+
+        SetPrioTag(ProcessMap, PrioTag);                          // put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);              // remove current process from the ready map
+        Kernel.Scheduler();                                       // wait until wake up
+
+        p->Timeout = 0;
+        if( !(ProcessMap & PrioTag) )                             // if waked up by send() or sendISR()
+            return true;
+
+        ClrPrioTag(ProcessMap, PrioTag);                          // otherwise waked up by timeout or by
+            return false;                                         // OS::ForceWakeUpProcess(), remove process from wait map
+    }
+}
+//------------------------------------------------------------------------------
+void OS::TBaseMessage::send()
+{
+    TCritSect cs;
+
+    if(ProcessMap)
+    {
+        TProcessMap Timeouted = Kernel.ReadyProcessMap;         // Process has its tag set in ReadyProcessMap if timeout expired,
+                                                                // or it was waked up by OS::ForceWakeUpProcess()
+        if( ProcessMap & ~Timeouted )                           // if any process has to be waked up
+        {
+            SetPrioTag(Kernel.ReadyProcessMap, ProcessMap);     // place all waiting processes to the ready map
+            ClrPrioTag(ProcessMap, ~Timeouted);                 // remove all non-timeouted processes from the waiting map.
+            Kernel.Scheduler();
+            return;
+        }
+    }
+
+    NonEmpty = true;
+}
+//------------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/OS_Services.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/OS_Services.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,467 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  OS Services Header. Declarations And Definitions
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person
+//*     obtaining  a copy of this software and associated documentation
+//*     files (the "Software"), to deal in the Software without restriction,
+//*     including without limitation the rights to use, copy, modify, merge,
+//*     publish, distribute, sublicense, and/or sell copies of the Software,
+//*     and to permit persons to whom the Software is furnished to do so,
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#ifndef OS_SERVICES_H
+#define OS_SERVICES_H
+
+namespace OS
+{
+    //--------------------------------------------------------------------------
+    //
+    //       NAME       :   Mutex
+    //
+    /// Binary semaphore for support of mutual exclusion
+    //
+    //       DESCRIPTION:
+    //
+    //
+    class TMutex
+    {
+    public:
+        INLINE TMutex() : ProcessMap(0), ValueTag(0) { }
+        void Lock();
+        void Unlock();
+        void UnlockISR();
+
+        INLINE bool LockSoftly()     { TCritSect cs; if(ValueTag) return false; else Lock(); return true; }
+        INLINE bool IsLocked() const { TCritSect cs; if(ValueTag) return true; else return false; }
+
+    private:
+        TProcessMap ProcessMap;
+        TProcessMap ValueTag;
+
+    };
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    ///  Event Flag
+    ///
+    ///  Intended for processes synchronization and
+    ///  event notification one (or more) process by another
+    //
+    //       DESCRIPTION:
+    //
+    //
+    class TEventFlag
+    {
+    public:
+        enum TValue { efOn = 1, efOff= 0 };     // prefix 'ef' means: "Event Flag"
+
+    public:
+        INLINE TEventFlag(TValue init_val = efOff) : ProcessMap(0), Value(init_val) { }
+
+        bool Wait(TTimeout timeout = 0);
+        void Signal();
+        INLINE void Clear() { TCritSect cs; Value = efOff; }
+        INLINE inline void SignalISR();
+        INLINE bool IsSignaled() { TCritSect cs; if(Value == efOn) return true; else return false; }
+
+    private:
+        TProcessMap ProcessMap;
+        TValue      Value;
+    };
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    ///  TChannel
+    ///
+    ///  Byte-wide data channel for transferring "raw" data
+    //
+    //       DESCRIPTION:
+    //
+    //
+    class TChannel
+    {
+    public:
+        INLINE TChannel(byte* buf, byte size) : Cbuf(buf, size) { }
+        void Push(byte x);
+        byte Pop();
+        void Write(const byte* data, const byte count);
+        void Read(byte* const data, const byte count);
+
+        INLINE byte GetCount() const { TCritSect cs; return Cbuf.get_count(); }
+
+    private:
+        TProcessMap ProducersProcessMap;
+        TProcessMap ConsumersProcessMap;
+        usr::TCbuf Cbuf;
+
+    private:
+        void CheckWaiters(TProcessMap& pm);
+    };
+    //--------------------------------------------------------------------------
+
+
+    //--------------------------------------------------------------------------
+    //
+    //       NAME       :  channel
+    //
+    //       PURPOSE    :  Data channel for transferring data
+    //                     objects of arbitrary type
+    //
+    //       DESCRIPTION:
+    //
+    //
+    template<typename T, word Size, typename S = byte>
+    ///  channel
+    ///
+    ///  Data channel for transferring data objects of arbitrary type
+    class channel
+    {
+    public:
+        INLINE channel() : ProducersProcessMap(0)
+                         , ConsumersProcessMap(0)
+                         , pool()
+        {
+        }
+
+        //----------------------------------------------------------------
+        //
+        //    Data transfer functions
+        //
+        void write(const T* data, const S cnt);
+        bool read (T* const data, const S cnt, TTimeout timeout = 0);
+
+        void push      (const T& item);
+        void push_front(const T& item);
+
+        bool pop     (T& item, TTimeout timeout = 0);
+        bool pop_back(T& item, TTimeout timeout = 0);
+
+
+        //----------------------------------------------------------------
+        //
+        //    Service functions
+        //
+        INLINE S get_count()     const { TCritSect cs; return pool.get_count();     }
+        INLINE S get_free_size() const { TCritSect cs; return pool.get_free_size(); }
+        void flush();
+        //const T& operator[](const S index) { TCritSect cs; return pool[index]; }
+
+
+    private:
+        TProcessMap ProducersProcessMap;
+        TProcessMap ConsumersProcessMap;
+        usr::ring_buffer<T, Size, S> pool;
+
+    private:
+        void CheckWaiters(TProcessMap& pm);
+    };
+
+    //--------------------------------------------------------------------------
+
+    //--------------------------------------------------------------------------
+    //
+    /// message
+    ///
+    /// Template for messages
+    //
+    //       DESCRIPTION:
+    //
+    //
+    class TBaseMessage
+    {
+    public:
+        INLINE TBaseMessage() : ProcessMap(0), NonEmpty(false) { }
+
+        bool wait  (TTimeout timeout = 0);
+        void send();
+        INLINE inline void sendISR();
+        INLINE bool is_non_empty() const { TCritSect cs; return NonEmpty;  }
+        INLINE void reset       ()       { TCritSect cs; NonEmpty = false; }
+
+    private:
+        TProcessMap ProcessMap;
+        bool NonEmpty;
+    };
+    //--------------------------------------------------------------------------
+    template<typename T>
+    class message : public TBaseMessage
+    {
+    public:
+        INLINE message() : TBaseMessage()   { }
+        INLINE const T& operator=(const T& msg) { TCritSect cs; Msg = msg; return Msg; }
+        INLINE operator     T() const       { TCritSect cs; return Msg; }
+
+    private:
+        T Msg;
+    };
+    //--------------------------------------------------------------------------
+}
+//------------------------------------------------------------------------------
+//
+//          Function-members implementation
+//
+//------------------------------------------------------------------------------
+void OS::TEventFlag::SignalISR()
+{
+    TCritSect cs;
+    if(ProcessMap)                                          // if any process waits for event
+    {
+        TProcessMap Timeouted = Kernel.ReadyProcessMap;     // Process has its tag set in ReadyProcessMap if timeout
+                                                            // expired, or it was waked up by OS::ForceWakeUpProcess()
+        if( ProcessMap & ~Timeouted )                       // if any process has to be waked up
+        {
+            SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
+            ClrPrioTag(ProcessMap, ~Timeouted);             // remove all non-timeouted processes from the waiting map.
+            return;
+        }
+    }
+    Value = efOn;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void OS::channel<T, Size, S>::CheckWaiters(TProcessMap& pm)
+{
+    if(pm)
+    {
+        TProcessMap Timeouted = Kernel.ReadyProcessMap;
+
+        SetPrioTag(Kernel.ReadyProcessMap, pm);       // place all waiting processes to the ready map
+        ClrPrioTag(pm, ~Timeouted);                   // remove waiting processes from the wait map
+        Kernel.Scheduler();
+    }
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void OS::channel<T, Size, S>::push(const T& item)
+{
+    TCritSect cs;
+
+    while(!pool.get_free_size())
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ProducersProcessMap, PrioTag);     // channel is full, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+        Kernel.Scheduler();
+    }
+
+    pool.push_back(item);
+    CheckWaiters(ConsumersProcessMap);
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void OS::channel<T, Size, S>::push_front(const T& item)
+{
+    TCritSect cs;
+
+    while(!pool.get_free_size())
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ProducersProcessMap, PrioTag);     // channel is full, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+        Kernel.Scheduler();
+    }
+
+    pool.push_front(item);
+    CheckWaiters(ConsumersProcessMap);
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool OS::channel<T, Size, S>::pop(T& item, TTimeout timeout)
+{
+    TCritSect cs;
+
+    if(pool.get_count())
+    {
+        item = pool.pop();
+        CheckWaiters(ProducersProcessMap);
+        return true;
+    }
+    else
+    {
+        TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
+        p->Timeout = timeout;
+
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        for(;;)
+        {
+            SetPrioTag(ConsumersProcessMap, PrioTag);     // channel is empty, put current process to the wait map
+            ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+            Kernel.Scheduler();
+
+            if(pool.get_count())
+            {
+                p->Timeout = 0;
+                item = pool.pop();
+                CheckWaiters(ProducersProcessMap);
+                return true;
+            }
+
+            if(ConsumersProcessMap & PrioTag)             // waked up by timer when timeout expired
+            {                                             // or by OS::ForceWakeUpProcess()
+
+                p->Timeout = 0;                           // non-zero if waked up by ForceWakeUpProcess()
+                ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
+                return false;
+            }
+        }
+    }
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool OS::channel<T, Size, S>::pop_back(T& item, TTimeout timeout)
+{
+    TCritSect cs;
+
+    if(pool.get_count())
+    {
+        item = pool.pop_back();
+        CheckWaiters(ProducersProcessMap);
+        return true;
+    }
+    else
+    {
+        TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
+        p->Timeout = timeout;
+
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        for(;;)
+        {
+            SetPrioTag(ConsumersProcessMap, PrioTag);     // channel is empty, put current process to the wait map
+            ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+            Kernel.Scheduler();
+
+            if(pool.get_count())
+            {
+                p->Timeout = 0;
+                item = pool.pop_back();
+                CheckWaiters(ProducersProcessMap);
+                return true;
+            }
+
+            if(ConsumersProcessMap & PrioTag)             // waked up by timer when timeout expired
+            {                                             // or by OS::ForceWakeUpProcess()
+
+                p->Timeout = 0;                           // non-zero if waked up by ForceWakeUpProcess()
+                ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
+                return false;
+            }
+        }
+    }
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void OS::channel<T, Size, S>::flush()
+{
+    TCritSect cs;
+    pool.flush();
+    CheckWaiters(ProducersProcessMap);
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void OS::channel<T, Size, S>::write(const T* data, const S count)
+{
+    TCritSect cs;
+
+    while(pool.get_free_size() < count)
+    {
+        TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+        SetPrioTag(ProducersProcessMap, PrioTag);     // channel does not have enough space, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+        Kernel.Scheduler();
+    }
+
+    pool.write(data, count);
+    CheckWaiters(ConsumersProcessMap);
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool OS::channel<T, Size, S>::read(T* const data, const S count, TTimeout timeout)
+{
+    TCritSect cs;
+
+    TBaseProcess* p = Kernel.ProcessTable[Kernel.CurProcPriority];
+    p->Timeout = timeout;
+
+    TProcessMap PrioTag = GetPrioTag(Kernel.CurProcPriority);
+    while(pool.get_count() < count)
+    {
+        SetPrioTag(ConsumersProcessMap, PrioTag);     // channel doesn't contain enough data, put current process to the wait map
+        ClrPrioTag(Kernel.ReadyProcessMap, PrioTag);  // remove current process from the ready map
+        Kernel.Scheduler();
+
+        if(ConsumersProcessMap & PrioTag)             // waked up by timer when timeout expired
+        {                                             // or by OS::ForceWakeUpProcess()
+
+            p->Timeout = 0;                           // non-zero if waked up by ForceWakeUpProcess()
+            ClrPrioTag(ConsumersProcessMap, PrioTag); // remove current process from the wait map
+            return false;
+        }
+    }
+
+    p->Timeout = 0;
+    pool.read(data, count);
+    CheckWaiters(ProducersProcessMap);
+
+    return true;
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+//
+//              OS::message template
+//
+//          Function-members implementation
+//
+//
+//------------------------------------------------------------------------------
+void OS::TBaseMessage::sendISR()
+{
+    TCritSect cs;
+
+    if(ProcessMap)
+    {
+        TProcessMap Timeouted = OS::Kernel.ReadyProcessMap;     // Process has it's tag set in ReadyProcessMap if timeout
+                                                                // expired, or it was waked up by  OS::ForceWakeUpProcess()
+        if( ProcessMap & ~Timeouted )                           // if any process has to be waked up
+        {
+            SetPrioTag(Kernel.ReadyProcessMap, ProcessMap);     // place all waiting processes to the ready map
+            ClrPrioTag(ProcessMap, ~Timeouted);                 // remove all non-timeouted processes from the waiting map.
+            return;
+        }
+    }
+    NonEmpty = true;
+}
+//------------------------------------------------------------------------------
+#endif // OS_SERVICES_H
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/scmRTOS.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/scmRTOS.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,58 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  Main RTOS header file
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person
+//*     obtaining  a copy of this software and associated documentation
+//*     files (the "Software"), to deal in the Software without restriction,
+//*     including without limitation the rights to use, copy, modify, merge,
+//*     publish, distribute, sublicense, and/or sell copies of the Software,
+//*     and to permit persons to whom the Software is furnished to do so,
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#ifndef scmRTOS_H
+#define scmRTOS_H
+
+//-----------------------------------------------------------------------------
+//
+//    !!! The order of includes is important !!!
+//
+#include <stddef.h>
+#include <commdefs.h>
+#include <usrlib.h>
+#include <OS_Target.h>
+
+//------------------------------------------------------------------------------
+
+
+#endif // scmRTOS_H
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/scmRTOS_defs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/scmRTOS_defs.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,374 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PURPOSE:  Macros And Common Definitions
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person
+//*     obtaining  a copy of this software and associated documentation
+//*     files (the "Software"), to deal in the Software without restriction,
+//*     including without limitation the rights to use, copy, modify, merge,
+//*     publish, distribute, sublicense, and/or sell copies of the Software,
+//*     and to permit persons to whom the Software is furnished to do so,
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#ifndef scmRTOS_DEFS_H
+#define scmRTOS_DEFS_H
+
+#include <commdefs.h>
+
+//------------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+//
+//
+///   Macro for Channel Type definition
+//
+//
+#define DefineChannel(Name, Capacity)                                            \
+class Name : public OS::TChannel                                                 \
+{                                                                                \
+public:                                                                          \
+    Name() : OS::TChannel(buf, sizeof(buf)) { }                                  \
+                                                                                 \
+private:                                                                         \
+    byte buf[Capacity];                                                          \
+                                                                                 \
+}
+//-----------------------------------------------------------------------------
+//
+//    Check CONFIG Macro Definitions
+//
+//
+
+//----------------- scmRTOS_SYSTIMER_NEST_INTS_ENABLE -------------------------
+#ifndef scmRTOS_SYSTIMER_NEST_INTS_ENABLE
+#error "Error: Config macro scmRTOS_SYSTIMER_NEST_INTS_ENABLE must be defined!"
+#endif
+
+#if (scmRTOS_SYSTIMER_NEST_INTS_ENABLE < 0) || (scmRTOS_SYSTIMER_NEST_INTS_ENABLE > 1)
+#error "Error: scmRTOS_SYSTIMER_NEST_INTS_ENABLE must have values 0 or 1 only!"
+#endif
+
+//----------------- scmRTOS_SYSTEM_TICKS_ENABLE -------------------------------
+#ifndef scmRTOS_SYSTEM_TICKS_ENABLE
+#error "Error: Config macro scmRTOS_SYSTEM_TICKS_ENABLE must be defined!"
+#endif
+
+#if (scmRTOS_SYSTEM_TICKS_ENABLE < 0) || (scmRTOS_SYSTEM_TICKS_ENABLE > 1)
+#error "Error: scmRTOS_SYSTEM_TICKS_ENABLE must have values 0 or 1 only!"
+#endif
+
+
+//----------------- scmRTOS_SYSTIMER_HOOK_ENABLE ------------------------------
+#ifndef scmRTOS_SYSTIMER_HOOK_ENABLE
+#error "Error: Config macro scmRTOS_SYSTIMER_HOOK_ENABLE must be defined!"
+#endif
+
+#if (scmRTOS_SYSTIMER_HOOK_ENABLE < 0) || (scmRTOS_SYSTIMER_HOOK_ENABLE > 1)
+#error "Error: scmRTOS_SYSTIMER_HOOK_ENABLE must have values 0 or 1 only!"
+#endif
+
+//-------------- scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE ----------------------
+#ifndef scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE
+#error "Error: Config macro scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE must be defined!"
+#endif
+
+#if (scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE < 0) || (scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE > 1)
+#error "Error: scmRTOS_CONTEXT_SWITCH_USER_HOOK_ENABLE must have values 0 or 1 only!"
+#endif
+
+//----------------- scmRTOS_IDLE_HOOK_ENABLE ----------------------------------
+#ifndef scmRTOS_IDLE_HOOK_ENABLE
+#error "Error: Config macro scmRTOS_IDLE_HOOK_ENABLE must be defined!"
+#endif
+
+#if (scmRTOS_IDLE_HOOK_ENABLE < 0) || (scmRTOS_IDLE_HOOK_ENABLE > 1)
+#error "Error: scmRTOS_IDLE_HOOK_ENABLE must have values 0 or 1 only!"
+#endif
+
+//----------------- scmRTOS_CONTEXT_SWITCH_SCHEME -----------------------------
+#ifndef scmRTOS_CONTEXT_SWITCH_SCHEME
+#error "Error: Config macro scmRTOS_CONTEXT_SWITCH_SCHEME must be defined!"
+#endif
+
+#if (scmRTOS_CONTEXT_SWITCH_SCHEME < 0) || (scmRTOS_CONTEXT_SWITCH_SCHEME > 1)
+#error "Error: scmRTOS_CONTEXT_SWITCH_SCHEME must have values 0 or 1 only!"
+#endif
+
+
+//----------------- scmRTOS_PRIORITY_ORDER ------------------------------------
+#ifndef scmRTOS_PRIORITY_ORDER
+#error "Error: Config macro scmRTOS_PRIORITY_ORDER must be defined!"
+#endif
+
+#if (scmRTOS_PRIORITY_ORDER < 0) || (scmRTOS_PRIORITY_ORDER > 1)
+#error "Error: scmRTOS_PRIORITY_ORDER must have values 0 or 1 only!"
+#endif
+
+//----------------- User Hooks inlining ------------------------------------
+#ifndef INLINE_SYS_TIMER_HOOK
+#define INLINE_SYS_TIMER_HOOK
+#endif
+
+#ifndef INLINE_CONTEXT_SWITCH_HOOK
+#define INLINE_CONTEXT_SWITCH_HOOK
+#endif
+
+
+//-----------------------------------------------------------------------------
+//
+///    Priority and process map type definitions
+//
+//
+namespace OS
+{
+    #if scmRTOS_PROCESS_COUNT < 8
+        typedef byte TProcessMap;
+    #elif scmRTOS_PROCESS_COUNT < 16
+        typedef word TProcessMap;
+    #else
+        typedef dword TProcessMap;
+    #endif
+    //------------------------------------------------------
+#if scmRTOS_PRIORITY_ORDER == 0
+    enum TPriority {
+        #if scmRTOS_PROCESS_COUNT   > 0
+            pr0,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 1
+            pr1,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 2
+            pr2,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 3
+            pr3,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 4
+            pr4,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 5
+            pr5,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 6
+            pr6,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 7
+            pr7,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 8
+            pr8,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 9
+            pr9,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 10
+            pr10,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 11
+            pr11,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 12
+            pr12,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 13
+            pr13,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 14
+            pr14,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 15
+            pr15,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 16
+            pr16,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 17
+            pr17,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 18
+            pr18,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 19
+            pr19,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 20
+            pr20,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 21
+            pr21,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 22
+            pr22,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 23
+            pr23,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 24
+            pr24,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 25
+            pr25,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 26
+            pr26,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 27
+            pr27,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 28
+            pr28,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 29
+            pr29,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 30
+            pr30,
+        #endif
+        #if (scmRTOS_PROCESS_COUNT   > 31) || (scmRTOS_PROCESS_COUNT   < 1)
+            #error "Invalid Process Count specification! Must be from 1 to 31."
+        #endif
+            prIDLE
+    };
+#else   // scmRTOS_PRIORITY_ORDER == 1
+    enum TPriority {
+            prIDLE,
+        #if scmRTOS_PROCESS_COUNT   > 30
+            pr30,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 29
+            pr29,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 28
+            pr28,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 27
+            pr27,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 26
+            pr26,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 25
+            pr25,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 24
+            pr24,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 23
+            pr23,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 22
+            pr22,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 21
+            pr21,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 20
+            pr20,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 19
+            pr19,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 18
+            pr18,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 17
+            pr17,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 16
+            pr16,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 15
+            pr15,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 14
+            pr14,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 13
+            pr13,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 12
+            pr12,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 11
+            pr11,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 10
+            pr10,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 9
+            pr9,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 8
+            pr8,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 7
+            pr7,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 6
+            pr6,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 5
+            pr5,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 4
+            pr4,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 3
+            pr3,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 2
+            pr2,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 1
+            pr1,
+        #endif
+        #if scmRTOS_PROCESS_COUNT   > 0
+            pr0
+        #endif
+        #if (scmRTOS_PROCESS_COUNT   > 31) || (scmRTOS_PROCESS_COUNT   < 1)
+            #error "Invalid Process Count specification! Must be from 1 to 31."
+        #endif
+    };
+#endif //scmRTOS_PRIORITY_ORDER
+}
+//-----------------------------------------------------------------------------
+//
+//     Process's constructor inlining control: default behaviour
+//
+#ifndef INLINE_PROCESS_CTOR
+#define INLINE_PROCESS_CTOR
+#endif
+
+
+//-----------------------------------------------------------------------------
+
+#endif // scmRTOS_DEFS_H
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/usrlib.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/usrlib.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,140 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*               
+//*     PURPOSE:  User Suport Library Source
+//*               
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#include <usrlib.h>
+#include <commdefs.h>
+
+using namespace usr;
+
+//------------------------------------------------------------------------------
+//
+///   Circular buffer function-member description
+//
+//
+//
+TCbuf::TCbuf(byte* const Address, const byte Size) :
+        buf(Address),
+        size(Size),
+        count(0),
+        first(0),
+        last(0)
+{
+}
+//------------------------------------------------------------------------------
+bool TCbuf::write(const byte* data, const byte Count)
+{
+    if( Count > (size - count) )
+        return false;
+
+    for(byte i = 0; i < Count; i++)
+        push(*(data++));
+
+    return true;
+}
+//------------------------------------------------------------------------------
+void TCbuf::read(byte* data, const byte Count)
+{
+    byte N = Count <= count ? Count : count;
+
+    for(byte i = 0; i < N; i++)
+        data[i] = pop();
+}
+//------------------------------------------------------------------------------
+byte TCbuf::get_byte(const byte index) const
+{
+    byte x = first + index;
+
+    if(x < size)
+        return buf[x];
+    else
+        return buf[x - size];
+}
+
+//------------------------------------------------------------------------------
+bool TCbuf::put(const byte item)
+{
+    if(count == size)
+        return false;
+
+    push(item);
+    return true;
+}
+//------------------------------------------------------------------------------
+byte TCbuf::get()
+{
+    if(count)
+        return pop();
+    else
+        return 0;
+}
+//------------------------------------------------------------------------------
+//
+/// \note
+/// For internal purposes.
+/// Use this function with care - it doesn't perform free size check.
+//
+void TCbuf::push(const byte item)
+{
+    buf[last] = item;
+    last++;
+    count++;
+
+    if(last == size)
+        last = 0;
+}
+//------------------------------------------------------------------------------
+//
+/// \note
+/// For internal purposes.
+/// Use this function with care - it doesn't perform free size check.
+//
+byte TCbuf::pop()
+{
+    byte item = buf[first];
+
+    count--;
+    first++;
+    if(first == size)
+        first = 0;
+
+    return item;
+}
+//------------------------------------------------------------------------------
diff -r 000000000000 -r 9b057566f9ee scmRTOS/Common/usrlib.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/Common/usrlib.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,298 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*               
+//*     PURPOSE:  User Suport Library Header
+//*               
+//*     Version: 3.10
+//*
+//*     $Revision: 256 $
+//*     $Date:: 2010-01-22 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+
+#ifndef USRLIB_H
+#define USRLIB_H
+
+#include <commdefs.h>
+
+//------------------------------------------------------------------------------
+//
+//  DESCRIPTON: user namespace for some useful types and functions
+//
+//
+namespace usr
+{
+    //------------------------------------------------------------------------------
+    //
+    ///     The Circular Buffer
+    //
+    ///         Byte-wide FIFO.
+    //
+    ///         Allows to:
+    ///             add byte,
+    ///             get byte,
+    ///             write bytes from array,
+    ///             read bytes to array,
+    ///             and some other service actions.
+    //
+    class TCbuf
+    {
+    public:
+        TCbuf(byte* const Address, const byte Size);
+        bool write(const byte* data, const byte Count);
+        void read(byte* const data, const byte Count);
+        byte get_count() const { return count; }
+        byte get_free_size() const { return size - count; }
+        byte get_byte(const byte index) const;
+        void clear() { count = 0; last = first; }
+        bool put(const byte item);
+        byte get();
+
+    private:
+       //------------------------------------------------------------------------------
+       //
+       //  DESCRIPTON: For internal purposes
+       //
+        void push(const byte item); ///< Use this function with care - it doesn't perform free size check
+        byte pop();                 ///< Use this function with care - it doesn't perform count check
+       //------------------------------------------------------------------------------
+
+    private:
+        byte* buf;
+        byte  size;
+        volatile byte count;
+        byte  first;
+        byte  last;
+    };
+    //------------------------------------------------------------------------------
+
+
+
+    //-----------------------------------------------------------------------
+    //
+    ///     The Ring Buffer Template
+    ///
+    ///         Carries out FIFO functionality for
+    ///         arbitrary data types
+    ///
+    ///         Allows to:
+    ///             add item to back (default),
+    ///             add item to front,
+    ///             get item at front (default),
+    ///             get item from back,
+    ///             write items from array,
+    ///             read items to array and some other actions
+    //
+    //
+    //
+    template<typename T, word Size, typename S = byte>
+    class ring_buffer
+    {
+    public:
+        ring_buffer() : Count(0), First(0), Last(0) { }
+
+        //----------------------------------------------------------------
+        //
+        //    Data transfer functions
+        //
+        bool write(const T* data, const S cnt);
+        void read(T* const data, const S cnt);
+
+        bool push_back(const T item);
+        bool push_front(const T item);
+
+        T pop_front();
+        T pop_back();
+
+        bool push(const T item) { return push_back(item); }
+        T pop() { return pop_front(); }
+
+        //----------------------------------------------------------------
+        //
+        //    Service functions
+        //
+        S get_count() const { return Count; }
+        S get_free_size() const { return Size - Count; }
+        T& operator[](const S index);
+        void flush() { Count = 0; Last = First; }
+
+    private:
+        //--------------------------------------------------------------
+        //  DESCRIPTON: For internal purposes
+        //              Use this functions with care: it don't perform
+        //              free size and count check
+        //
+        void push_item(const T item);
+        void push_item_front(const T item);
+        T pop_item();
+        T pop_item_back();
+        //--------------------------------------------------------------
+
+    private:
+        S  Count;
+        S  First;
+        S  Last;
+        T  Buf[Size];
+    };
+    //------------------------------------------------------------------
+}
+//---------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+//
+//    The ring buffer function-member definitions
+//
+//
+//
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::write(const T* data, const S cnt)
+{
+    if( cnt > (Size - Count) )
+        return false;
+
+    for(S i = 0; i < cnt; i++)
+        push_item(*(data++));
+
+    return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::read(T* data, const S cnt)
+{
+    S nItems = cnt <= Count ? cnt : Count;
+
+    for(S i = 0; i < nItems; i++)
+        data[i] = pop_item();
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T& usr::ring_buffer<T, Size, S>::operator[](const S index)
+{
+    S x = First + index;
+
+    if(x < Size)
+        return Buf[x];
+    else
+        return Buf[x - Size];
+}
+
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::push_back(const T item)
+{
+    if(Count == Size)
+        return false;
+
+    push_item(item);
+    return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+bool usr::ring_buffer<T, Size, S>::push_front(const T item)
+{
+    if(Count == Size)
+        return false;
+
+    push_item_front(item);
+    return true;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_front()
+{
+    if(Count)
+        return pop_item();
+    else
+        return Buf[First];
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_back()
+{
+    if(Count)
+        return pop_item_back();
+    else
+        return Buf[First];
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::push_item(const T item)
+{
+    Buf[Last] = item;
+    Last++;
+    Count++;
+
+    if(Last == Size)
+        Last = 0;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+void usr::ring_buffer<T, Size, S>::push_item_front(const T item)
+{
+    if(First == 0)
+        First = Size - 1;
+    else
+        --First;
+    Buf[First] = item;
+    Count++;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_item()
+{
+    T item = Buf[First];
+
+    Count--;
+    First++;
+    if(First == Size)
+        First = 0;
+
+    return item;
+}
+//------------------------------------------------------------------------------
+template<typename T, word Size, typename S>
+T usr::ring_buffer<T, Size, S>::pop_item_back()
+{
+
+    if(Last == 0)
+        Last = Size - 1;
+    else
+        --Last;
+
+    Count--;
+    return Buf[Last];;
+}
+//------------------------------------------------------------------------------
+
+
+#endif // USRLIB_H
diff -r 000000000000 -r 9b057566f9ee scmRTOS/CortexM3/OS_Target.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/CortexM3/OS_Target.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,236 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   RVCT (ARM)
+//*               
+//*     PURPOSE:   Target Dependent Stuff Header. Declarations And Definitions
+//*               
+//*     Version: 3.10
+//*
+//*     $Revision: 195 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+#ifndef scmRTOS_CORTEXM3_H
+#define scmRTOS_CORTEXM3_H
+
+#include <commdefs.h>
+
+//------------------------------------------------------------------------------
+//
+//    Compiler and Target checks
+//
+//
+#ifndef __ARMCC_VERSION
+#error "This file should only be compiled with ARM RVCT Compiler"
+#endif // __ARMCC_VERSION
+
+#if __TARGET_ARCH_ARM != 0 || __TARGET_ARCH_THUMB != 4
+#error "This file must be compiled for ARMv7-M (Cortex-M3) processor only."
+#endif
+
+//------------------------------------------------------------------------------
+//
+//    Target specific types
+//
+//
+typedef dword TStackItem;
+typedef dword TStatusReg;
+
+//-----------------------------------------------------------------------------
+//
+//    Configuration macros
+//
+//
+#define OS_PROCESS    __attribute__((__noreturn__))
+#define OS_INTERRUPT 
+#define DUMMY_INSTR() __NOP()
+#define INLINE_PROCESS_CTOR INLINE inline
+
+//-----------------------------------------------------------------------------
+//
+//   Uncomment macro value below for SystemTimer() run in critical section
+// 
+//   This is useful (and necessary) when target processor has hardware 
+//   enabled nested interrups. Cortex-M3 have such interrupts.
+// 
+#define SYS_TIMER_CRIT_SECT()  TCritSect cs
+
+//-----------------------------------------------------------------------------
+// Separate return stack not required
+#define SEPARATE_RETURN_STACK   0
+
+//-----------------------------------------------------------------------------
+// Software interrupt stack switching not supported in Cortex-M3 port
+// because processor implements hardware stack switching.
+// So, system timer isr wrapper can't be choosen at project level
+//
+#define scmRTOS_ISRW_TYPE       TISRW
+
+//-----------------------------------------------------------------------------
+//
+//    scmRTOS Context Switch Scheme
+//
+//    The macro defines a context switch manner. Value 0 sets direct context
+//    switch in the scheduler and in the OS ISRs. This is the primary method.
+//    Value 1 sets the second way to switch context - by using of software 
+//    interrupt. See documentation fo details.
+//    Cortex-M3 port supports software interrupt switch method only.
+//
+#define  scmRTOS_CONTEXT_SWITCH_SCHEME 1
+
+//-----------------------------------------------------------------------------
+//
+//     Include project-level configurations
+//    !!! The order of includes is important !!!
+//
+#include "../scmRTOS_config.h"
+#include "../scmRTOS_TARGET_CFG.h"
+#include <scmRTOS_defs.h>
+#include <LPC17xx.h>
+
+//-----------------------------------------------------------------------------
+//
+//     The Critital Section Wrapper
+//
+//
+#define __enable_interrupt()  __enable_irq()
+#define __disable_interrupt() __disable_irq()
+
+#define __set_interrupt_state(status) __set_PRIMASK(status)
+#define __get_interrupt_state() __get_PRIMASK()
+
+class TCritSect
+{
+public:
+    TCritSect () : StatusReg(__get_interrupt_state()) { __disable_interrupt(); }
+    ~TCritSect() { __set_interrupt_state(StatusReg); }
+
+private:
+    TStatusReg StatusReg;
+};
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+//
+//     Priority stuff
+//
+//
+namespace OS
+{
+INLINE inline OS::TProcessMap GetPrioTag(const byte pr) { return static_cast<OS::TProcessMap> (1 << pr); }
+
+#if scmRTOS_PRIORITY_ORDER == 0
+    INLINE inline byte GetHighPriority(TProcessMap pm)
+    {
+        byte pr = 0;
+
+        while( !(pm & 0x0001) )
+        {
+            pr++;
+            pm >>= 1;
+        }
+        return pr;
+    }
+#else
+    INLINE inline byte GetHighPriority(TProcessMap pm) { return (31 - __clz(pm)); }
+#endif // scmRTOS_PRIORITY_ORDER
+}
+
+//-----------------------------------------------------------------------------
+//
+//     Interrupt and Interrupt Service Routines support
+//
+INLINE inline TStatusReg GetInterruptState( )             { return __get_interrupt_state(); }
+INLINE inline void       SetInterruptState(TStatusReg sr) { __set_interrupt_state(sr);      }
+
+INLINE inline void EnableInterrupts()  { __enable_interrupt();  }
+INLINE inline void DisableInterrupts() { __disable_interrupt(); }
+
+
+namespace OS
+{
+    INLINE inline void EnableContextSwitch()  { EnableInterrupts(); }
+    INLINE inline void DisableContextSwitch() { DisableInterrupts(); }
+}
+
+#include <OS_Kernel.h>
+
+namespace OS
+{
+    //--------------------------------------------------------------------------
+    //
+    //      NAME       :   OS ISR support 
+    //
+    //      PURPOSE    :   Implements common actions on interrupt enter and exit 
+    //                     under the OS
+    //
+    //      DESCRIPTION:
+    //
+    //
+    class TISRW
+    {
+    public:
+        INLINE  TISRW()  { ISR_Enter(); }
+        INLINE  ~TISRW() { ISR_Exit();  }
+
+    private:
+        //-----------------------------------------------------
+        INLINE void ISR_Enter()
+        {
+            TCritSect cs;
+            Kernel.ISR_NestCount++;
+        }
+        //-----------------------------------------------------
+        INLINE void ISR_Exit()
+        {
+            TCritSect cs;
+            if(--Kernel.ISR_NestCount) return;
+            Kernel.SchedISR();
+        }
+        //-----------------------------------------------------
+    };
+
+    // No software interrupt stack switching provided,
+    // TISRW_SS declared to be the same as TISRW for porting compability
+    #define TISRW_SS    TISRW
+    
+} // ns OS
+//-----------------------------------------------------------------------------
+
+#endif // scmRTOS_CORTEXM3_H
+//-----------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/CortexM3/OS_Target_asm.s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/CortexM3/OS_Target_asm.s	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,178 @@
+; ******************************************************************************
+; *
+; *     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+; *
+; *     NICKNAME:  scmRTOS
+; *
+; *     PROCESSOR: ARM Cortex-M3 
+; *
+; *     TOOLKIT:   EWARM (IAR Systems)
+; *               
+; *     PURPOSE:   Target Dependent Low-Level Stuff
+; *               
+; *     Version: 3.10
+; *
+; *     $Revision: 195 $
+; *     $Date:: 2008-06-19 #$
+; *
+; *     Copyright (c) 2003-2010, Harry E. Zhurov
+; *
+; *     Permission is hereby granted, free of charge, to any person 
+; *     obtaining  a copy of this software and associated documentation 
+; *     files (the "Software"), to deal in the Software without restriction, 
+; *     including without limitation the rights to use, copy, modify, merge, 
+; *     publish, distribute, sublicense, and/or sell copies of the Software, 
+; *     and to permit persons to whom the Software is furnished to do so, 
+; *     subject to the following conditions:
+; *
+; *     The above copyright notice and this permission notice shall be included 
+; *     in all copies or substantial portions of the Software.
+; *
+; *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+; *     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+; *     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+; *     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+; *     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+; *     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+; *     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+; *
+; *     =================================================================
+; *     See http://scmrtos.sourceforge.net for documentation, latest
+; *     information, license and contact details.
+; *     =================================================================
+; *
+; ******************************************************************************
+; *     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+; #include "scmRTOS_TARGET_CFG.h"
+
+; -----------------------------------------------------------------------------
+;   PUBLIC FUNCTIONS
+;
+    EXTERN  OS_ContextSwitchHook
+
+    EXPORT  OS_Start
+    EXPORT  PendSV_Handler
+
+; -----------------------------------------------------------------------------
+;   EQUATES
+;
+NVIC_INT_CTRL        EQU     0xE000ED04  ; Interrupt control state register.
+NVIC_PENDSVSET       EQU     0x10000000  ; Value to trigger PendSV exception.
+
+NVIC_SYSPRI14        EQU     0xE000ED22  ; System priority register (priority 14).
+NVIC_PENDSV_PRI      EQU           0xFF  ; PendSV priority value (lowest).
+NVIC_SYSPRI15        EQU     0xE000ED23  ; System priority register (priority 15).
+NVIC_ST_PRI          EQU           0xFF  ; SysTick priority value (lowest).
+
+NVIC_ST_CTRL         EQU    0xE000E010   ; SysTick Ctrl & Status Reg.
+NVIC_ST_RELOAD       EQU    0xE000E014   ; SysTick Reload  Value Reg.
+NVIC_ST_CTRL_CLK_SRC EQU    0x00000004   ; Clock Source.
+NVIC_ST_CTRL_INTEN   EQU    0x00000002   ; Interrupt enable.
+NVIC_ST_CTRL_ENABLE  EQU    0x00000001   ; Counter mode.
+
+; should be the same as in scmRTOS_TARGET_CFG.h
+SYSTICKFREQ          EQU    100000000
+SYSTICKINTRATE       EQU    1000
+
+; -----------------------------------------------------------------------------
+;       CODE GENERATION DIRECTIVES
+; 
+        AREA TEXT, CODE, READONLY
+        THUMB
+
+; -----------------------------------------------------------------------------
+;       HANDLE PendSV EXCEPTION
+;       void PendSV_Handler(void)
+; 
+;  Note(s) : 1) PendSV is used to cause a context switch.  This is a recommended method for performing
+;               context switches with Cortex-M3.  This is because the Cortex-M3 auto-saves half of the
+;               processor context on any exception, and restores same on return from exception.  So only
+;               saving of R4-R11 is required and fixing up the stack pointers.  Using the PendSV exception
+;               this way means that context saving and restoring is identical whether it is initiated from
+;               a thread or occurs due to an interrupt or exception.
+; 
+;            2) Pseudo-code is:
+;               a) Get the process SP, if 0 then skip (goto f) the saving part (first context switch);
+;               b) Save remaining regs r4-r11 on process stack;
+;               c) Call OS_ContextSwitchHook for save current task SP and get new task SP;
+;               d) Restore R4-R11 from new process stack;
+;               e) Perform exception return which will restore remaining context.
+;               f) Get SP for the first context switch (R2 hold it);
+;                  run SysTick; goto d);
+; 
+;            3) On entry into PendSV handler:
+;               a) The following have been saved on the process stack (by processor):
+;                  xPSR, PC, LR, R12, R0-R3
+;               b) Processor mode is switched to Handler mode (from Thread mode)
+;               c) Stack is Main stack (switched from Process stack)
+; 
+;            4) Since PendSV is set to lowest priority in the system (by OS_Start() below), we
+;               know that it will only be run when no other exception or interrupt is active, and
+;               therefore safe to assume that context being switched out was using the process stack (PSP).
+; 
+PendSV_Handler
+    CPSID   I                 ;  Prevent interruption during context switch
+    MRS     R0, PSP           ;  PSP is process stack pointer
+    CBZ     R0, nosave        ;  Skip register save the first time    
+
+    STMDB R0!, {R4-R11}       ;  Save remaining regs r4-11 on process stack
+    ;  At this point, entire context of process has been saved                                                            
+
+    PUSH    {R14}                        ;  Save LR exc_return value
+    LDR     R1, =OS_ContextSwitchHook    ;  OS_ContextSwitchHook();
+    BLX     R1
+    POP     {R14}
+    
+ContextRestore
+    ;  R0 is new process SP;
+    LDMIA R0!, {R4-R11}         ;  Restore r4-11 from new process stack
+    MSR     PSP, R0           ;  Load PSP with new process SP
+    ORR     LR, LR, #0x04     ;  Ensure exception return uses process stack
+    CPSIE   I
+    BX      LR                ;  Exception return will restore remaining context
+nosave
+    MOV R0, R2                ;  R2 hold the first task SP
+    
+    LDR     R1, =NVIC_ST_CTRL ;  Enable and run SysTick
+    LDR     R2, =(NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | NVIC_ST_CTRL_ENABLE)
+    STR     R2, [R1]
+    
+    B   ContextRestore
+
+   
+; -----------------------------------------------------------------------------
+;       START MULTITASKING
+;       void OS_Start(TStackItem* sp)
+; 
+;  Note(s) : 1) OS_Start() MUST:
+;               a) Setup PendSV and SysTick exception priority to lowest;
+;               b) Setup SysTick (reload value);
+;               c) Enable interrupts (tasks will run with interrupts enabled).
+; 
+OS_Start
+    LDR     R1, =NVIC_SYSPRI14      ;  Set the PendSV exception priority (lowest)
+    LDR     R2, =NVIC_PENDSV_PRI
+    STRB    R2, [R1]
+    LDR     R1, =NVIC_SYSPRI15      ;  Set the SysTick exception priority (lowest)
+    LDR     R2, =NVIC_ST_PRI
+    STRB    R2, [R1]
+    
+    LDR     R1, =NVIC_ST_RELOAD     ;  Setup SysTick
+    LDR     R2, =(SYSTICKFREQ/SYSTICKINTRATE-1)  
+    STR     R2, [R1]
+
+    MOV     R2, R0                  ;  Save the first task stack
+    MOVS    R0, #0                  ;  Set the PSP to 0 for initial context switch call
+    MSR     PSP, R0
+
+    LDR     R0, =NVIC_INT_CTRL      ;  Trigger the PendSV exception (causes context switch)
+    LDR     R1, =NVIC_PENDSVSET
+    STR     R1, [R0]
+
+    CPSIE   I                       ;  Enable interrupts at processor level
+loop
+    B       loop                    ;  Should never get here
+
+
+    END
diff -r 000000000000 -r 9b057566f9ee scmRTOS/CortexM3/OS_Target_cpp.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/CortexM3/OS_Target_cpp.cpp	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,131 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   EWARM (IAR Systems)
+//*               
+//*     PURPOSE:   Target Dependent Stuff Source
+//*               
+//*     Version: 3.10
+//*
+//*     $Revision: 195 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+
+#include <scmRTOS.h>
+
+using namespace OS;
+
+//------------------------------------------------------------------------------
+//
+//       OS Process's constructor
+//
+//       Performs:  
+//           * initializing process data;
+//           * registering of the process in kernel;
+//           * preparing stack frame;
+//                  
+//
+TBaseProcess::TBaseProcess(TStackItem* Stack, TPriority pr, void (*exec)())
+    : StackPointer(Stack)
+    , Timeout(0)
+    , Priority(pr)
+{
+    Kernel.RegisterProcess(this);
+
+    //---------------------------------------------------------------
+    //
+    //  Prepare Process Stack Frame
+    //
+    *(--StackPointer)  = 0x01000000L;             // xPSR
+    *(--StackPointer)  = reinterpret_cast<dword>(exec); // Entry Point
+    StackPointer -= 14;                           // emulate "push R14,R12,R3,R2,R1,R0,R11-R4"
+    
+    // The code below can be used for debug purpose. In this case comment
+    // line above and uncomment block below.
+/*
+    *(--StackPointer)  = 0xFFFFFFFEL;             // R14 (LR) (init value will cause fault if ever used)
+    *(--StackPointer)  = 0x12121212L;             // R12
+    *(--StackPointer)  = 0x03030303L;             // R3
+    *(--StackPointer)  = 0x02020202L;             // R2
+    *(--StackPointer)  = 0x01010101L;             // R1
+    *(--StackPointer)  = 0x00000000L;             // R0
+
+                                                  // Remaining registers saved on process stack
+    *(--StackPointer)  = 0x11111111L;             // R11
+    *(--StackPointer)  = 0x10101010L;             // R10
+    *(--StackPointer)  = 0x09090909L;             // R9
+    *(--StackPointer)  = 0x08080808L;             // R8
+    *(--StackPointer)  = 0x07070707L;             // R7
+    *(--StackPointer)  = 0x06060606L;             // R6
+    *(--StackPointer)  = 0x05050505L;             // R5
+    *(--StackPointer)  = 0x04040404L;             // R4
+*/
+}
+//------------------------------------------------------------------------------
+//
+//   Idle Process
+//
+typedef process<prIDLE, scmRTOS_IDLE_PROCESS_STACK_SIZE> TIdleProcess;
+
+TIdleProcess IdleProcess;
+
+template<> OS_PROCESS void TIdleProcess::Exec()
+{
+    for(;;)
+    {
+        #if scmRTOS_IDLE_HOOK_ENABLE == 1
+        IdleProcessUserHook();
+        #endif
+    }
+}
+//------------------------------------------------------------------------------
+OS_INTERRUPT void OS::SysTick_Handler()
+{
+    scmRTOS_ISRW_TYPE ISR;
+
+    Kernel.SystemTimer();
+    
+#if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0
+    DISABLE_NESTED_INTERRUPTS();
+#endif
+    
+#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1
+    SystemTimerUserHook();
+#endif
+}
+//------------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/CortexM3/commdefs.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/CortexM3/commdefs.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,71 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   EWARM (IAR Systems)
+//*
+//*     PURPOSE:   Common Type Definitions
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 195 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+
+#ifndef COMMONDEFS_H
+#define COMMONDEFS_H
+
+#ifndef __IAR_SYSTEMS_ASM__
+
+typedef unsigned char  byte;
+typedef signed char    sbyte;
+typedef unsigned short word;
+typedef unsigned long  dword;
+
+typedef volatile byte  sfr_byte;
+typedef volatile word  sfr_word;
+typedef volatile dword sfr_dword;
+
+#define INLINE _Pragma("inline=forced")
+
+#endif // __IAR_SYSTEMS_ASM__
+
+#endif // COMMONDEFS_H
+
+//-----------------------------------------------------------------------------
+
+/*============================================================================*/
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/CortexM3/device.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/CortexM3/device.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,60 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   EWARM (IAR Systems)
+//*
+//*     PURPOSE:   Device Definitions
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 196 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+#ifndef DEVICE_H
+#define DEVICE_H
+
+#include <commdefs.h>
+
+//------------------------------------------------------------------------------
+// Definitions for some processor registers in order to not include specific
+// header file for various Cortex-M3 processor derivatives.
+#define CPU_ICSR            ( ( sfr_dword *) 0xE000ED04 )   // Interrupt Control State Register
+#define CPU_SYSTICKCSR      ( ( sfr_dword *) 0xE000E010 )   // SysTick Control and Status Register
+#define CPU_SYSTICKCSR_EINT 0x02                            // Bit for enable/disable SysTick interrupt
+
+
+#endif  /* DEVICE_H */
diff -r 000000000000 -r 9b057566f9ee scmRTOS/scmRTOS_TARGET_CFG.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/scmRTOS_TARGET_CFG.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,102 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   EWARM (IAR Systems)
+//*
+//*     PURPOSE:   Project Level Target Extensions Config
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 196 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     mbed port by Igor Skochinsky
+
+#ifndef  scmRTOS_TARGET_CFG_H
+#define  scmRTOS_TARGET_CFG_H
+
+#include "device.h"
+
+// Define SysTick clock frequency and its interrupt rate in Hz.
+#define SYSTICKFREQ     100000000
+#define SYSTICKINTRATE  1000
+
+//------------------------------------------------------------------------------
+//
+//       System Timer stuff
+//
+//
+namespace OS
+{
+extern "C" void SysTick_Handler();
+}
+
+#define  LOCK_SYSTEM_TIMER()    ( *CPU_SYSTICKCSR &= ~CPU_SYSTICKCSR_EINT )
+#define  UNLOCK_SYSTEM_TIMER()  ( *CPU_SYSTICKCSR |=  CPU_SYSTICKCSR_EINT )
+
+//------------------------------------------------------------------------------
+//
+//       Context Switch ISR stuff
+//
+//
+namespace OS
+{
+#if scmRTOS_IDLE_HOOK_ENABLE == 1
+    void IdleProcessUserHook();
+#endif
+
+#if scmRTOS_CONTEXT_SWITCH_SCHEME == 1
+
+    INLINE inline void RaiseContextSwitch() { *CPU_ICSR |= 0x10000000; }
+
+    #define ENABLE_NESTED_INTERRUPTS()
+    
+    #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0
+        #define DISABLE_NESTED_INTERRUPTS() TCritSect cs
+    #else
+        #define DISABLE_NESTED_INTERRUPTS()
+    #endif
+
+#else
+    #error "Cortex-M3 port supports software interrupt switch method only!"
+
+#endif // scmRTOS_CONTEXT_SWITCH_SCHEME
+
+}
+//-----------------------------------------------------------------------------
+
+#endif // scmRTOS_TARGET_CFG_H
+//-----------------------------------------------------------------------------
+
diff -r 000000000000 -r 9b057566f9ee scmRTOS/scmRTOS_config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scmRTOS/scmRTOS_config.h	Mon Nov 01 20:39:01 2010 +0000
@@ -0,0 +1,133 @@
+//******************************************************************************
+//*
+//*     FULLNAME:  Single-Chip Microcontroller Real-Time Operating System
+//*
+//*     NICKNAME:  scmRTOS
+//*
+//*     PROCESSOR: ARM Cortex-M3 
+//*
+//*     TOOLKIT:   EWARM (IAR Systems)
+//*
+//*     PURPOSE:   Project Level Configuration
+//*
+//*     Version: 3.10
+//*
+//*     $Revision: 196 $
+//*     $Date:: 2008-06-19 #$
+//*
+//*     Copyright (c) 2003-2010, Harry E. Zhurov
+//*
+//*     Permission is hereby granted, free of charge, to any person 
+//*     obtaining  a copy of this software and associated documentation 
+//*     files (the "Software"), to deal in the Software without restriction, 
+//*     including without limitation the rights to use, copy, modify, merge, 
+//*     publish, distribute, sublicense, and/or sell copies of the Software, 
+//*     and to permit persons to whom the Software is furnished to do so, 
+//*     subject to the following conditions:
+//*
+//*     The above copyright notice and this permission notice shall be included 
+//*     in all copies or substantial portions of the Software.
+//*
+//*     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
+//*     EXPRESS  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
+//*     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
+//*     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
+//*     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
+//*     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH 
+//*     THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//*
+//*     =================================================================
+//*     See http://scmrtos.sourceforge.net for documentation, latest
+//*     information, license and contact details.
+//*     =================================================================
+//*
+//******************************************************************************
+//*     Ported by Andrey Chuikin, Copyright (c) 2008-2010
+
+#ifndef  scmRTOS_CONFIG_H
+#define  scmRTOS_CONFIG_H
+
+#ifndef __IAR_SYSTEMS_ASM__
+#include <commdefs.h>
+
+typedef word TTimeout;
+
+#endif // __IAR_SYSTEMS_ASM__
+
+#include "device.h"
+//------------------------------------------------------------------------------
+//
+//    Specify scmRTOS Process Count. Must be less than 31
+//
+//
+#define  scmRTOS_PROCESS_COUNT                  7
+
+//-----------------------------------------------------------------------------
+//
+//    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
+//-----------------------------------------------------------------------------
+