CooCox 1.1.4 on mbed with simple blinky example

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
electronix79
Date:
Fri Jul 29 03:01:03 2011 +0000
Commit message:
CooCox 1.1.4

Changed in this revision

CoOS/kernel/CoOS.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsConfig.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsCore.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsError.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsEvent.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsFlag.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsKernelHeap.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsMM.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsMutex.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsQueue.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsServiceReq.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsTask.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsTime.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/OsTimer.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/coocox.h Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/core.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/event.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/flag.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/hook.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/kernelHeap.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/mbox.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/mm.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/mutex.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/queue.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/sem.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/serviceReq.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/task.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/time.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/timer.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/utility.c Show annotated file Show diff for this revision Revisions of this file
CoOS/kernel/utility.h Show annotated file Show diff for this revision Revisions of this file
CoOS/portable/Keil/port.c Show annotated file Show diff for this revision Revisions of this file
CoOS/portable/OsArch.h Show annotated file Show diff for this revision Revisions of this file
CoOS/portable/arch.c 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/CoOS.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,222 @@
+/**
+ *******************************************************************************
+ * @file       CoOS.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      API header file of CooCox CoOS.
+ * @details    This file including all API functions's declare of CooCox CoOS.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+#ifndef _CCRTOS_H
+#define _CCRTOS_H
+#include "OsConfig.h"
+/*---------------------------- Type Define  ----------------------------------*/
+typedef signed   char      S8;              
+typedef unsigned char      U8;	
+typedef short              S16;
+typedef unsigned short     U16;
+typedef int                S32;
+typedef unsigned int       U32;
+typedef long long          S64;
+typedef unsigned long long U64;
+typedef unsigned char      BIT;
+typedef unsigned char      BOOL;
+typedef unsigned int       OS_STK;
+typedef U8                 OS_TID;
+typedef U8                 OS_TCID;
+typedef U8                 OS_MutexID;
+typedef U8                 OS_EventID;
+typedef U8                 OS_FlagID;
+typedef U8                 OS_MMID;
+typedef U8                 StatusType;
+typedef U16                OS_VER;
+typedef void               (*FUNCPtr)(void*);
+typedef void               (*vFUNCPtr)(void);
+
+
+/*---------------------------- Constant Define -------------------------------*/
+#ifndef Co_NULL
+#define Co_NULL          ((void *)0)
+#endif
+
+#ifndef Co_FALSE
+#define Co_FALSE         (0)
+#endif
+
+#ifndef Co_TRUE
+#define Co_TRUE          (1)
+#endif
+
+
+/*---------------------------- Error Codes   ---------------------------------*/
+#define E_CREATE_FAIL         (StatusType)-1
+#define E_OK                  (StatusType)0
+#define E_INVALID_ID          (StatusType)1
+#define E_INVALID_PARAMETER   (StatusType)2
+#define E_CALL                (StatusType)3
+#define E_TASK_WAITING        (StatusType)4
+#define E_TIMEOUT             (StatusType)5
+#define E_SEM_FULL            (StatusType)6
+#define E_MBOX_FULL           (StatusType)7
+#define E_QUEUE_FULL          (StatusType)8
+#define E_SEM_EMPTY           (StatusType)9
+#define E_MBOX_EMPTY          (StatusType)10
+#define E_QUEUE_EMPTY         (StatusType)11
+#define E_FLAG_NOT_READY      (StatusType)12
+#define E_ALREADY_IN_WAITING  (StatusType)13
+#define E_TASK_NOT_WAITING    (StatusType)14
+#define E_TASK_WAIT_OTHER     (StatusType)15
+#define E_EXCEED_MAX_NUM      (StatusType)16
+#define E_NOT_IN_DELAY_LIST   (StatusType)17
+#define E_SEV_REQ_FULL        (StatusType)18	
+#define E_NOT_FREE_ALL        (StatusType)19	
+#define E_PROTECTED_TASK      (StatusType)20 
+#define E_OS_IN_LOCK          (StatusType)21												
+
+
+/*---------------------------- Wait Opreation type  --------------------------*/
+#define OPT_WAIT_ALL          0         /*!< Wait for all flags.              */
+#define OPT_WAIT_ANY          1         /*!< Wait for any one of flags.       */
+#define OPT_WAIT_ONE          2         /*!< Waot for one flag.               */	
+
+
+/*---------------------------- Delete Opreation type  ------------------------*/
+#define OPT_DEL_NO_PEND       0         /*!< Delete when no task waitting for */
+#define OPT_DEL_ANYWAY        1         /*!< Delete always.                   */
+
+
+/*---------------------------- Timer Types  ----------------------------------*/
+#if CFG_TMR_EN >0
+#define TMR_TYPE_ONE_SHOT     0         /*!< Timer counter type: One-shot     */
+#define TMR_TYPE_PERIODIC     1         /*!< Timer counter type: Periodic     */
+#endif
+
+
+/*---------------------------- Event Control ---------------------------------*/
+#if CFG_EVENT_EN >0
+#define EVENT_SORT_TYPE_FIFO  (U8)0x01  /*!< Insert a event by FIFO           */
+#define EVENT_SORT_TYPE_PRIO  (U8)0x02  /*!< Insert a event by prio           */
+#endif
+
+
+/*---------------------------- Function declare-------------------------------*/
+
+/* Implement in file "core.c"      */
+extern void    CoInitOS(void);          /*!< Initialize OS                    */
+extern void    CoStartOS(void);         /*!< Start multitask                  */
+extern void    CoEnterISR(void);        /*!< Enter a ISR                      */
+extern void    CoExitISR(void);         /*!< Exit a ISR                       */
+extern void    CoSchedLock(void);
+extern void    CoSchedUnlock(void);
+extern OS_VER  CoGetOSVersion(void);    /*!< Get OS version value             */
+
+
+/* Implement in file "task.c"      */
+#define CoCreateTask(task,argv,prio,stk,stkSz)              \
+            CreateTask(task,argv,(prio)|(((stkSz)<<8) &0x000FFF00 ),stk)
+
+
+#define CoCreateTaskEx(task,argv,prio,stk,stkSz,timeSlice,isWaitting)  \
+           CreateTask(task,argv,(prio)|(((stkSz)<<8)&0x000FFF00)|(((timeSlice)<<20)&0x7FF00000)|((isWaitting<<31)&0x80000000),stk)
+
+extern void        CoExitTask(void);
+extern OS_TID      CoGetCurTaskID(void);
+extern StatusType  CoDelTask(OS_TID taskID);
+extern StatusType  CoActivateTask(OS_TID taskID,void *argv);
+extern StatusType  CoAwakeTask(OS_TID taskID);
+extern StatusType  CoSuspendTask(OS_TID taskID);
+extern StatusType  CoSetPriority(OS_TID taskID,U8 priority);
+extern OS_TID      CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk);
+
+/* Implement in file "time.c"      */
+extern U64         CoGetOSTime(void);
+extern StatusType  CoTickDelay(U32 ticks);
+extern StatusType  CoResetTaskDelayTick(OS_TID taskID,U32 ticks);
+extern StatusType  CoTimeDelay(U8 hour,U8 minute,U8 sec,U16 millsec);
+
+
+/* Implement in file "timer.c"     */ 
+extern StatusType  CoDelTmr(OS_TCID tmrID);
+extern StatusType  CoStopTmr(OS_TCID tmrID);
+extern StatusType  CoStartTmr(OS_TCID tmrID);
+extern U32         CoGetCurTmrCnt(OS_TCID tmrID,StatusType* perr);
+extern StatusType  CoSetTmrCnt(OS_TCID tmrID,U32 tmrCnt,U32 tmrReload);
+extern OS_TCID     CoCreateTmr(U8 tmrType, U32 tmrCnt, U32 tmrReload, vFUNCPtr func);
+
+
+/* Implement in file "kernelHeap.c"*/
+extern void*       CoKmalloc(U32 size);
+extern void        CoKfree(void* memBuf);
+
+
+/* Implement in file "mm.c"        */
+extern void*       CoGetMemoryBuffer(OS_MMID mmID);
+extern StatusType  CoDelMemoryPartition(OS_MMID mmID);
+extern StatusType  CoFreeMemoryBuffer(OS_MMID mmID,void* buf);
+extern U32         CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr);
+extern OS_MMID     CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum);
+
+/* Implement in file "mutex.c"     */
+extern OS_MutexID  CoCreateMutex(void);
+extern StatusType  CoEnterMutexSection(OS_MutexID mutexID);
+extern StatusType  CoLeaveMutexSection(OS_MutexID mutexID);
+
+
+/* Implement in file "sem.c"       */
+extern StatusType  CoPostSem(OS_EventID id);
+extern StatusType  CoAcceptSem(OS_EventID id);
+extern StatusType  isr_PostSem(OS_EventID id);
+extern StatusType  CoDelSem(OS_EventID id,U8 opt);
+extern StatusType  CoPendSem(OS_EventID id,U32 timeout);
+extern OS_EventID  CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType);
+
+
+/* Implement in file "mbox.c"      */
+extern OS_EventID  CoCreateMbox(U8 sortType);
+extern StatusType  CoDelMbox(OS_EventID id,U8 opt);
+extern StatusType  CoPostMail(OS_EventID id,void* pmail);
+extern StatusType  isr_PostMail(OS_EventID id,void* pmail);
+extern void*       CoAcceptMail(OS_EventID id,StatusType* perr);
+extern void*       CoPendMail(OS_EventID id,U32 timeout,StatusType* perr);
+
+
+/* Implement in file "queue.c"     */
+extern StatusType  CoDelQueue(OS_EventID id,U8 opt);
+extern StatusType  CoPostQueueMail(OS_EventID id,void* pmail);
+extern StatusType  isr_PostQueueMail(OS_EventID id,void* pmail);
+extern void*       CoAcceptQueueMail(OS_EventID id,StatusType* perr);
+extern OS_EventID  CoCreateQueue(void **qStart, U16 size ,U8 sortType);
+extern void*       CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr);
+
+
+
+/* Implement in file "flag.c"      */
+extern StatusType  CoSetFlag (OS_FlagID id);
+extern StatusType  CoClearFlag (OS_FlagID id);
+extern StatusType  isr_SetFlag (OS_FlagID id);
+extern StatusType  CoDelFlag (OS_FlagID id,U8 opt);
+extern StatusType  CoAcceptSingleFlag (OS_FlagID id);
+extern StatusType  CoWaitForSingleFlag (OS_FlagID id,U32 timeout);
+extern OS_FlagID   CoCreateFlag (BOOL bAutoReset,BOOL bInitialState);
+extern U32         CoAcceptMultipleFlags (U32 flags,U8 waitType,StatusType *perr);
+extern U32         CoWaitForMultipleFlags (U32 flags,U8 waitType,U32 timeout,StatusType *perr);
+
+
+/* Implement in file "utility.c"   */
+extern StatusType  CoTimeToTick(U8 hour,U8 minute,U8 sec,U16 millsec,U32* ticks);
+extern void        CoTickToTime(U32 ticks,U8* hour,U8* minute,U8* sec,U16* millsec);
+
+
+/* Implement in file "hook.c"      */
+extern void        CoIdleTask(void* pdata);
+extern void        CoStkOverflowHook(OS_TID taskID);
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsConfig.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,276 @@
+/**
+ *******************************************************************************
+ * @file       config.h
+ * @version    V1.1.4
+ * @date       2011.04.20
+ * @brief      This file use by user to configuration CooCox CoOS.
+ * @note       Ensure you have knew every item before modify this file. 
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef  _CONFIG_H
+#define  _CONFIG_H
+
+
+/*!< 
+Defines chip type,cortex-m3(1),cortex-m0(2)      
+*/
+#define CFG_CHIP_TYPE           (1)
+
+/*!< 
+Defines the lowest priority that be assigned.       
+*/
+#define CFG_LOWEST_PRIO         (64)
+
+/*!< 
+Max number of tasks that can be running.             
+*/            
+#define CFG_MAX_USER_TASKS      (5)     
+
+/*!< 
+Idle task stack size(word).                                 
+*/    
+#define CFG_IDLE_STACK_SIZE     (25)    
+
+/*!< 
+System frequency (Hz).                                  
+*/    
+#define CFG_CPU_FREQ            (96000000)  
+
+/*!< 
+systick frequency (Hz).                             
+*/
+#define CFG_SYSTICK_FREQ        (1000)
+
+/*!< 
+max systerm api call num in ISR.                             
+*/
+#define CFG_MAX_SERVICE_REQUEST (3) 
+
+/*!< 
+Enable(1) or disable(0) order list schedule.
+If disable(0),CoOS use Binary-Scheduling Algorithm. 
+*/
+#if (CFG_MAX_USER_TASKS) <15
+#define CFG_ORDER_LIST_SCHEDULE_EN  (1)
+#else 
+#define CFG_ORDER_LIST_SCHEDULE_EN  (0)
+#endif    
+
+
+/*!< 
+Enable(1) or disable(0) Round-Robin Task switching. 
+*/
+#define CFG_ROBIN_EN            (0)         
+
+/*!< 
+Default slice of task.                                 
+*/
+#if    CFG_ROBIN_EN > 0
+#define CFG_TIME_SLICE          (10)              
+#endif
+
+
+/*----------------------- Schedule model Config -----------------------------*/
+/*!< 
+Enable(1) or disable(0) all waiting function.
+Include sem,mailbox,queue,flag,mutex,delay modules.    
+If CFG_TASK_WAITTING_EN=0,all these modules are disable.          
+*/
+#define CFG_TASK_WAITTING_EN     (1)
+
+/*!< 
+Dynamic task scheduling(1) or Static Task Scheduling(0) model.
+If in Static Task Scheduling model(0),cannot creat task and change task priority
+after coocox os start running. In Dynamic Task Scheduling model(1), all these can.
+When task terminated, if in Static Task Scheduling model(0), 
+CoOS do not recovered task resources, and you can activate it again.
+But in Dynamic Task Scheduling model(1),task resources will be recovered.
+If in Static Task Scheduling model(0),mutex module can not be used, as this model don't
+support to change task priority while CoOS running. 
+*/
+#define CFG_TASK_SCHEDULE_EN     (1)
+
+
+/*---------------------- Task Management Config -----------------------------*/
+/*!< 
+Enable(1) or disable(0) CoSetPriority() API.              
+*/
+#if CFG_TASK_SCHEDULE_EN >0
+#define CFG_PRIORITY_SET_EN       (0)    
+#endif
+
+/*!< 
+Enable(1) or disable(0) CoAwakeTask() and CoSuspendTask() API.              
+*/
+#define CFG_TASK_SUSPEND_EN       (0)
+
+
+/*---------------------- Debug Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) parameter checkout .          
+*/
+#define CFG_PAR_CHECKOUT_EN     (0)    
+
+/*!< 
+Enable(1) or disable(0) stack overflow checkout .        
+*/        
+#define CFG_STK_CHECKOUT_EN     (0)        
+
+
+
+/*---------------------- Memory Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) memory management.          
+*/
+#define CFG_MM_EN               (0)   
+
+/*!< 
+Max number of memory.(must be less than 32).      
+*/ 
+#if CFG_MM_EN >0
+#define CFG_MAX_MM              (2)            
+#endif 
+
+
+
+/*-------------------- Kernel heap Management Config -------------------------*/
+/*!< 
+Enable(1) or disable(0) kernel heap management.          
+*/
+#define CFG_KHEAP_EN            (0)          
+
+/*!< 
+Kernel heap size(word).      
+*/ 
+#if CFG_KHEAP_EN >0
+#define KHEAP_SIZE              (50)            
+#endif   
+
+
+        
+/*---------------------- Time Management Config -----------------------------*/
+/*!< 
+Enable(1) or disable(0) TimeDelay() API.              
+*/
+#if CFG_TASK_WAITTING_EN >0
+#define CFG_TIME_DELAY_EN       (1)    
+#endif
+
+
+/*---------------------- Timer Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) timer management.              
+*/
+#define CFG_TMR_EN              (0)        
+
+/*!< 
+Specify max number timer.(must be less than 32)      
+*/    
+#if CFG_TMR_EN >0
+#define CFG_MAX_TMR             (2)            
+#endif
+
+
+/*---------------------- Event Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) events management,             
+events including semaphore,mailbox,queue.             
+*/
+#if CFG_TASK_WAITTING_EN > 0
+#define  CFG_EVENT_EN           (1) 
+#endif
+           
+#if CFG_EVENT_EN > 0
+/*!< 
+Event sort type.(1)FIFO (2)PRI (3)FIFO+PRI           
+*/
+#define CFG_EVENT_SORT          (3)        
+
+/*!< 
+Max number of event.(must be less than 255)           
+Event = semaphore + mailbox + queue;                  
+*/
+#define CFG_MAX_EVENT           (5)    
+
+/*!< 
+Enable(1) or disable(0) semaphore management.          
+*/
+#define CFG_SEM_EN              (1)    
+
+/*!< 
+Enable(1) or disable(0) mailbox management.          
+*/        
+#define CFG_MAILBOX_EN          (1)
+
+/*!< 
+Enable(1) or disable(0) queue management.              
+*/        
+#define CFG_QUEUE_EN            (0)    
+
+/*!< 
+Max number of queue.(less than CFG_MAX_EVENT).       
+*/
+#if    CFG_QUEUE_EN >0    
+#define CFG_MAX_QUEUE           (2)        
+#endif   // CFG_QUEUE_EN
+    
+#endif   // CFG_EVENT_EN
+    
+
+
+/*----------------------- Flag Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) flag management.             
+Max number of flag is 32.                              
+*/
+#if CFG_TASK_WAITTING_EN > 0
+#define  CFG_FLAG_EN           (1)
+#endif        
+
+
+/*---------------------- Mutex Management Config ----------------------------*/
+/*!< 
+Enable(1) or disable(0) mutex management.          
+*/
+#if CFG_TASK_WAITTING_EN > 0
+#if CFG_TASK_SCHEDULE_EN > 0
+#define  CFG_MUTEX_EN           (1)
+#endif
+#endif
+
+ 
+/*!< 
+Max number of mutex.(must be less than 255).      
+*/ 
+#if CFG_MUTEX_EN >0
+#define CFG_MAX_MUTEX           (10)            
+#endif
+
+/*---------------------- Utility Management Config --------------------------*/
+/*!< 
+Enable(1) or disable(0) utility management.          
+*/
+#define CFG_UTILITY_EN          (0)      
+   
+#if CFG_UTILITY_EN >0
+
+/*!< 
+Enable(1) or disable(0) TickToTime() utility    
+*/
+#define    CFG_TICK_TO_TIME_EN     (1)        
+/*!< 
+Enable(1) or disable(0) TimeToTick() utility    
+*/    
+#define    CFG_TIME_TO_TICK_EN     (1)        
+#endif
+
+
+#endif     // _CONFIG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsCore.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,27 @@
+/**
+ *******************************************************************************
+ * @file       OsCore.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file	related to kernel	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _CORE_H
+#define _CORE_H
+
+#include <CoOS.h>
+
+
+#define  OsSchedLock()  OSSchedLock++;      /*!< Lock schedule                */
+extern   void OsSchedUnlock(void);
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsError.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,84 @@
+/**
+ *******************************************************************************
+ * @file       OsError.h	
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      rror dispose header file	
+ * @details    This file use to dispose error which from error configure for OS.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+#if (CFG_SYSTICK_FREQ > 1000) ||(CFG_SYSTICK_FREQ < 1) 
+    #error " OsConfig.h System Tick time must between 1ms and 1s!"
+#endif
+
+#if CFG_MAX_USER_TASKS > 253
+    #error " OsConfig.h, CFG_MAX_USER_TASKS must be <= 253! "
+#endif
+
+#if CFG_LOWEST_PRIO > 254
+    #error " OsConfig.h, CFG_LOWEST_PRIO must be <= 254! "
+#endif
+
+#if CFG_IDLE_STACK_SIZE <25
+	#error " OsConfig.h, CFG_IDLE_STACK_SIZE must be >= 25! "
+#endif
+
+
+#if CFG_ROBIN_EN > 0
+    #if CFG_TIME_SLICE > 4095
+    #error " OsConfig.h, CFG_TIME_SLICE must be <= 4095! "
+    #endif
+#endif
+
+#if CFG_TMR_EN > 0
+    #if CFG_MAX_TMR > 32
+    #error " OsConfig.h, CFG_MAX_TMR must be <= 32! "
+    #endif
+#endif
+
+
+#if CFG_MM_EN > 0
+    #if CFG_MAX_MM > 32
+    #error " config.h, CFG_MAX_MM must be <= 32! "
+    #endif
+#endif
+
+
+#if CFG_KHEAP_EN > 0
+    #if KHEAP_SIZE < 0x20
+    #error " config.h, CFG_MAX_MM must be >= 0x20! "
+    #endif
+#endif
+
+#if CFG_MUTEX_EN > 0
+    #if CFG_MAX_MUTEX > 254
+    #error " config.h, CFG_MAX_MUTEX must be <= 254! "
+    #endif
+#endif
+
+
+#if CFG_EVENT_EN > 0
+    #if (CFG_MAX_EVENT > 254 || CFG_MAX_EVENT <= 0)
+    #error " config.h, CFG_MAX_EVENT must be <= 254 && > 0! "
+    #endif
+
+
+    #if CFG_QUEUE_EN > 0 
+        #if CFG_MAX_QUEUE > CFG_MAX_EVENT
+        #error " config.h, CFG_MAX_QUEUE must be <= CFG_MAX_EVENT! "	
+        #endif
+    #endif	
+#endif      /* CFG_EVENT_EN  */
+
+#endif      /* _ERROR_H      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsEvent.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,58 @@
+/**
+ *******************************************************************************
+ * @file       OsEvent.h	
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Event management header file
+ * @details    This file including some defines and declares related to event 
+ *             (semaphore,mailbox,queque) management.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _EVENT_H
+#define _EVENT_H
+
+#define EVENT_TYPE_SEM        (U8)0x01      /*!< Event type:Semaphore.        */
+#define EVENT_TYPE_MBOX       (U8)0x02      /*!< Event type:Mailbox.          */
+#define EVENT_TYPE_QUEUE      (U8)0x03      /*!< Event type:Queue.            */
+#define EVENT_TYPE_INVALID    (U8)0x04      /*!< Invalid event type.          */
+
+
+/**
+ * @struct  EventCtrBlk  event.h	  	
+ * @brief   Event control block
+ * @details This struct is use to manage event,
+ *          e.g. semaphore,mailbox,queue.	
+ */
+typedef struct EventCtrBlk
+{
+    void*   eventPtr;                   /*!< Point to mailbox or queue struct */
+    U8      id;                         /*!< ECB id                           */
+    U8      eventType:4;                /*!< Type of event                    */
+    U8      eventSortType:4;            /*!< 0:FIFO 1: Preemptive by prio     */
+    U16     eventCounter;               /*!< Counter of semaphore.            */
+    U16     initialEventCounter;        /*!< Initial counter of semaphore.    */
+    P_OSTCB eventTCBList;               /*!< Task waitting list.              */
+}ECB,*P_ECB;
+
+/*---------------------------- Variable declare ------------------------------*/
+extern ECB  EventTbl[CFG_MAX_EVENT];    /*!< Table use to save TCB.           */
+
+/*---------------------------- Function declare ------------------------------*/
+/*!< Create a event   */
+extern P_ECB      CreatEvent(U8 eventType,U8 eventSortType,void* eventPtr);
+
+/*!< Remove a task from wait list */	
+extern void       EventTaskToWait(P_ECB pecb,P_OSTCB ptcb);
+extern StatusType DeleteEvent(P_ECB pecb,U8 opt);   /*!< Delete a event.      */
+extern void       EventTaskToRdy(P_ECB pecb); /*!< Insert a task to ready list*/
+extern void       CreateEventList(void);    /*!< Create a event list.         */			
+extern void       RemoveEventWaittingList(P_OSTCB ptcb);
+#endif  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsFlag.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,57 @@
+/**
+ *******************************************************************************
+ * @file       OsFlag.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Evnet flag management header file
+ * @details    This file including some defines and declares about flag management.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _FLAG_H
+#define _FLAG_H
+
+/**
+ * @struct  FlagNode  flag.h 	
+ * @brief   Flag node struct
+ * @details 	 	
+ */
+typedef struct FlagNode
+{
+    struct FlagNode*  nextNode;         /*!< A pointer to next flag node      */
+    struct FlagNode*  prevNode;         /*!< A pointer to prev flag node      */
+    U32               waitFlags;        /*!< Flag value                       */
+    P_OSTCB           waitTask;         /*!< A pointer to task waitting flag  */
+    U8                waitType;         /*!< Wait type                        */
+}FLAG_NODE,*P_FLAG_NODE;
+
+
+/**
+ * @struct  Flag    flag.h  	
+ * @brief   Flag control block
+ * @details This struct use to mange event flag.	
+ */
+typedef struct Flag
+{
+    U32           flagRdy;              /*!< Ready flag                       */
+    U32           resetOpt;             /*!< Reset option                     */
+    U32           flagActive;           /*!< Active flag                      */
+    P_FLAG_NODE   headNode;             /*!< Head node                        */
+    P_FLAG_NODE   tailNode;             /*!< Tail node                        */
+}FCB,*P_FCB;
+
+
+/*---------------------------- Variable declare ------------------------------*/
+extern FCB FlagCrl;					
+
+/*---------------------------- Function declare ------------------------------*/
+extern void        RemoveLinkNode(P_FLAG_NODE pnode);
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsKernelHeap.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,48 @@
+/**
+ *******************************************************************************
+ * @file       OsKernelHeap.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file related to memory management	
+ * @details    This file including some defines and function declare related to 
+ *             kernel heap management. 
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef  _KERNELHEAP_H
+#define  _KERNELHEAP_H
+
+
+typedef struct KennelHeap
+{
+  U32   startAddr;
+  U32   endAddr;
+}KHeap,*P_KHeap;
+
+
+typedef struct UsedMemBlk
+{
+  void* nextMB;
+  void* preMB;	
+}UMB,*P_UMB;
+
+
+typedef struct FreeMemBlk
+{
+  struct FreeMemBlk* nextFMB;
+  struct UsedMemBlk* nextUMB;
+  struct UsedMemBlk* preUMB;
+}FMB,*P_FMB;
+
+/*---------------------------- Function Declare ------------------------------*/
+extern void   CoCreateKheap(void);
+
+#endif  /* _KERNELHEAP_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsMM.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,41 @@
+/**
+ *******************************************************************************
+ * @file       OsMm.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file	related to memory management 
+ * @details    This file including some defines and function declare related to 
+ *             memory management. 	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef  _MM_H
+#define  _MM_H
+
+
+typedef struct Memory
+{
+    U8*   memAddr;
+    U8*   freeBlock;
+    U32   blockSize;
+    U32   blockNum;			
+}MM,*P_MM;
+
+
+typedef struct MemoryBlock
+{
+    struct MemoryBlock* nextBlock;
+}MemBlk,*P_MemBlk;
+
+
+extern U32  MemoryIDVessel;
+
+#endif   /* _MM_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsMutex.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,57 @@
+/**
+ *******************************************************************************
+ * @file       OsMutex.h	
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Mutex management header file
+ * @details    This file including some defines and declare related to mutex
+ *             management.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _MUTEX_H
+#define _MUTEX_H
+
+#include <coocox.h>
+
+#if CFG_MUTEX_EN > 0
+
+/*---------------------------- Resource status -------------------------------*/
+#define   MUTEX_FREE        0           /*!< Mutex is free                    */
+#define   MUTEX_OCCUPY      1           /*!< Mutex is occupy                  */
+#define   WAITING_MUTEX     0x80
+
+/**
+ * @struct   Mutex  mutex.h 	
+ * @brief    Mutex control block
+ * @details  This struct is use to mutex management.	
+ */
+typedef struct Mutex
+{
+    U8       originalPrio;              /*!< Mutex priority.                  */
+    U8       mutexFlag;                 /*!< Mutex flag.                      */
+    OS_TID   taskID;                    /*!< Task ID.                         */	
+    OS_TID   hipriTaskID;               /*!< Mutex ID.                        */
+    P_OSTCB  waittingList;              /*!< waitting the Mutex.              */
+}MUTEX,*P_MUTEX;
+
+
+/*---------------------------- Variable declare ------------------------------*/
+/*!< Table use to save mutex control block.                                   */
+extern MUTEX      MutexTbl[CFG_MAX_MUTEX];
+extern OS_MutexID MutexFreeID;      /*!< A pointer to next vliad resource ID. */
+
+
+/*---------------------------- Function declare ------------------------------*/
+extern void   RemoveMutexList(P_OSTCB ptcb);
+
+#endif    /* CFG_MUTEX_EN  */
+
+#endif    /* _MUTEX_H      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsQueue.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,39 @@
+/**
+ *******************************************************************************
+ * @file       OsQueue.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Queue management header file	
+ * @details    This file including some defines and declares about queue management.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+
+/**
+ * @struct   Queue  queue.h	
+ * @brief    Queue struct
+ * @details  This struct use to manage queue.
+ *	
+ */
+typedef struct Queue
+{
+    void    **qStart;                   /*!<                                  */
+    U8      id;                         /*!<                                  */
+    U16     head;                       /*!< The header of queue              */
+    U16     tail;                       /*!< The end of queue                 */
+    U16     qMaxSize;                   /*!< The max size of queue            */
+    U16     qSize;                      /*!< Current size of queue            */
+}QCB,*P_QCB;
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsServiceReq.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,53 @@
+
+/**
+ *******************************************************************************
+ * @file       OsServiceReq.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file	related to service request	
+ * @details    This file including some defines and function declare related to
+ *             service request.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _SERVICEREQ_H
+#define _SERVICEREQ_H
+
+#if CFG_MAX_SERVICE_REQUEST > 0
+#define   SEM_REQ       (U8)0x1
+#define   MBOX_REQ      (U8)0x2
+#define   FLAG_REQ      (U8)0x3
+#define   QUEUE_REQ     (U8)0x4
+
+
+typedef struct ServiceReqCell
+{
+    U8      type;
+    U8      id;
+    void*   arg;
+}SQC,*P_SQC;
+
+typedef struct ServiceReqQueue
+{
+    U8    cnt;
+    U8    head;    
+    SQC   cell[CFG_MAX_SERVICE_REQUEST];
+}SRQ,*P_SRQ;
+
+
+extern SRQ  ServiceReq;
+extern BOOL InsertInSRQ(U8 type,U8 id,void* arg);
+#endif
+
+extern void RespondSRQ(void);
+extern BOOL TimeReq;
+extern BOOL TimerReq;
+extern BOOL IsrReq;
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsTask.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,112 @@
+/**
+ *******************************************************************************
+ * @file       OsTask.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file	related to task.
+ * @details    This file including some defines and function declare related to task.  	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+#ifndef _TASK_H
+#define _TASK_H
+
+#define  SYS_TASK_NUM   (1)             /*!< System task number.              */
+
+/*---------------------------- Task Status -----------------------------------*/
+#define  TASK_READY     0               /*!< Ready status of task.            */	 				
+#define  TASK_RUNNING   1               /*!< Running status of task.          */
+#define  TASK_WAITING   2               /*!< Waitting status of task.         */
+#define  TASK_DORMANT   3               /*!< Dormant status of task.          */ 
+
+
+#define  INVALID_ID     (U8)0xff
+#define  INVALID_VALUE  (U32)0xffffffff
+#define  MAGIC_WORD     (U32)0x5a5aa5a5
+
+
+/**
+ * @struct  TCB  task.h  	
+ * @brief   Task control blcok.
+ * @details This struct use to manage task.	 	
+ */
+typedef  struct TCB
+{
+    OS_STK      *stkPtr;                /*!< The current point of task.       */
+    U8          prio;                   /*!< Task priority.                   */
+    U8          state;                  /*!< TaSk status.                     */
+    OS_TID      taskID;                 /*!< Task ID.                         */
+
+#if CFG_MUTEX_EN > 0
+    OS_MutexID  mutexID;                /*!< Mutex ID.                        */
+#endif
+   
+#if CFG_EVENT_EN > 0
+    OS_EventID  eventID;                /*!< Event ID.                        */
+#endif
+    
+#if CFG_ROBIN_EN >0
+    U16         timeSlice;              /*!< Task time slice                  */
+#endif
+    
+#if CFG_STK_CHECKOUT_EN >0
+    OS_STK      *stack;                 /*!< The top point of task.           */
+#endif
+    
+#if CFG_EVENT_EN > 0
+    void*       pmail;                  /*!< Mail to task.                    */
+    struct TCB  *waitNext;  /*!< Point to next TCB in the Event waitting list.*/
+    struct TCB  *waitPrev;  /*!< Point to prev TCB in the Event waitting list.*/
+#endif
+
+#if CFG_TASK_SCHEDULE_EN == 0
+	FUNCPtr     taskFuc;
+	OS_STK      *taskStk;
+#endif  
+
+    
+#if CFG_FLAG_EN > 0
+    void*       pnode;                  /*!< Pointer to node of event flag.   */
+#endif   
+
+#if CFG_TASK_WAITTING_EN >0
+    U32         delayTick;              /*!< The number of ticks which delay. */
+#endif    
+    struct TCB  *TCBnext;               /*!< The pointer to next TCB.         */
+    struct TCB  *TCBprev;               /*!< The pointer to prev TCB.         */
+
+}OSTCB,*P_OSTCB;
+
+
+/*---------------------------- Variable declare ------------------------------*/
+// save tcb ptr that created
+extern P_OSTCB  FreeTCB;      /*!< A pointer to free TCB.                     */
+extern OSTCB    TCBTbl[CFG_MAX_USER_TASKS+SYS_TASK_NUM];
+extern P_OSTCB  TCBRdy;       /*!< A pointer to TCB that is ready status      */
+extern P_OSTCB  TCBNext;      /*!< A pointer to TCB next be scheduled.        */	
+extern P_OSTCB  TCBRunning;   /*!< A pointer to TCB that is running.          */
+
+extern U64      OSCheckTime;
+extern volatile U8   OSIntNesting; /*!< Use to indicate interrupt nesting level.*/   				
+extern volatile U8   OSSchedLock;  /*!< Schedule is lock(LOCK) or unlock(UN_LOCK).*/  	
+extern volatile BOOL TaskSchedReq;
+extern OS_STK   idle_stk[CFG_IDLE_STACK_SIZE];
+
+
+void  Schedule(void);         /*!< Schedule function                          */
+void  IdleTask(void* pdata);  /*!< IDLE task code                             */
+void  InsertToTCBRdyList  (P_OSTCB tcbInser);	
+void  RemoveFromTCBRdyList(P_OSTCB ptcb);
+void  CreateTCBList(void);
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+void  ActiveTaskPri(U8 pri);
+void  DeleteTaskPri(U8 pri);
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsTime.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,28 @@
+/**
+ *******************************************************************************
+ * @file       OsTime.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Header file related to time management
+ * @details    Thie file including some data declare related to time managment. 	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+  
+#ifndef _TIME_H
+#define _TIME_H
+
+/*---------------------------- Variable declare ------------------------------*/
+extern P_OSTCB  DlyList;            /*!< A pointer to ther delay list.        */
+
+/*---------------------------- Function declare ------------------------------*/
+extern void  TimeDispose(void);     /*!< Time dispose function.               */
+extern void  isr_TimeDispose(void);
+extern void  RemoveDelayList(P_OSTCB ptcb);
+extern void  InsertDelayList(P_OSTCB ptcb,U32 ticks);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/OsTimer.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,49 @@
+/**
+ *******************************************************************************
+ * @file       OsTimer.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Timer manage header file	
+ * @details    This file including some declares and defines related to timer 
+ *             management.
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+#ifndef _TIMER_H
+#define _TIMER_H
+
+#define   TMR_STATE_RUNNING     0       /*!< Timer State: Running             */
+#define   TMR_STATE_STOPPED     1       /*!< Timer State: Stopped             */
+
+/**
+ * @struct   tmrCtrl  timer.h  	
+ * @brief    Timer control block 
+ * @details  This struct is use to manage user timer. 
+ *	
+ */
+typedef struct tmrCtrl                  /* Timer Control Block Define.        */
+{
+    OS_TCID          tmrID;             /*!< Timer ID.                        */
+    U8               tmrType;           /*!< Timer Type.                      */
+    U8               tmrState;          /*!< Timer State.                     */
+    U32              tmrCnt;            /*!< Timer Counter.                   */
+    U32              tmrReload;         /*!< Timer Reload Counter Value.      */	
+    vFUNCPtr         tmrCallBack; /*!< Call-back Function When Timer overrun. */	
+    struct tmrCtrl*  tmrNext;       /*!< Point to Next Timer Control Block.   */
+    struct tmrCtrl*  tmrPrev;       /*!< Point to Previous Timer Control Block*/
+
+}TmrCtrl,*P_TmrCtrl;
+
+/*---------------------------- Variable declare ------------------------------*/
+extern P_TmrCtrl  TmrList;              /*!< A pointer to the timer list.     */ 
+extern U32        TmrIDVessel;
+/*---------------------------- Function declare ------------------------------*/
+extern void  TmrDispose(void);          /*!< Timer counter function.          */
+extern void  isr_TmrDispose(void);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/coocox.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,60 @@
+/**
+ *******************************************************************************
+ * @file       coocox.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Gather for all header file of CooCox CoOS.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef _COOCOX_H
+#define _COOCOX_H
+
+#define  OS_VERSION       (U16)0x0114   /*!< OS version.(format: Vx.xx),     
+                                            e.g. value 0x0114 is version V1.14*/
+/*---------------------------- Include ---------------------------------------*/
+#include "CoOS.h"
+#include "OsArch.h"
+#include "OsCore.h"
+#include "OsTask.h"
+#include "OsServiceReq.h"
+#include "OsError.h"
+#include "OsTime.h"
+
+
+#if CFG_TMR_EN > 0
+    #include "OsTimer.h"
+#endif
+
+#if CFG_KHEAP_EN > 0
+    #include "OsKernelHeap.h"
+#endif
+
+#if CFG_MM_EN >0
+    #include "OsMM.h"
+#endif
+
+#if CFG_EVENT_EN > 0
+    #include "OsEvent.h"
+#endif
+
+#if CFG_MUTEX_EN > 0
+    #include "OsMutex.h"
+#endif
+
+#if CFG_QUEUE_EN > 0
+    #include "OsQueue.h"
+#endif
+
+#if CFG_FLAG_EN     > 0
+    #include "OsFlag.h"
+#endif
+
+#endif    /* _COOCOX_H    */  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/core.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,238 @@
+ /**
+ *******************************************************************************
+ * @file       core.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Core implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+/*---------------------------- Variable Define -------------------------------*/
+volatile U8     OSIntNesting  = 0;         /*!< Use to indicate interrupt nesting level*/
+volatile U8     OSSchedLock   = 0;         /*!< Task Switch lock.                      */
+volatile BOOL   TaskSchedReq  = Co_FALSE;
+
+
+/**
+ *******************************************************************************
+ * @brief      Enter a ISR.						   
+ * @param[in]  None	 
+ * @param[out] None   
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to notify OS when enter to an ISR.
+ *
+ * @note       When you call API in ISR,you must call CoEnterISR() before your
+ *             interrupt handler code,and call CoExitISR() after your handler
+ *             code and before exiting from ISR.	 
+ *******************************************************************************
+ */
+void CoEnterISR(void)
+{
+    Inc8(&OSIntNesting);                /* OSIntNesting increment             */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Exit a ISR.	 
+ * @param[in]  None	 
+ * @param[out] None   
+ * @retval     None		 
+ *
+ * @par Description
+ * @details    This function is called when exit from a ISR.	  	
+ *
+ * @note 
+ *******************************************************************************
+ */
+void CoExitISR(void)
+{
+    Dec8(&OSIntNesting);                /* OSIntNesting decrease              */
+    if( OSIntNesting == 0)              /* Is OSIntNesting == 0?              */
+    {
+        if(TaskSchedReq == Co_TRUE)
+        {
+			OSSchedLock++;
+            Schedule();                 /* Call task schedule                 */
+			OSSchedLock--;
+        }
+    }
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Unlock schedule 	  
+ * @param[in]  None		 
+ * @param[out] None   
+ * @retval     None		 
+ *
+ * @par Description
+ * @details   This function is called to unlock schedule(i.e.enable schedule again) 		 
+ *
+ * @note 
+ *******************************************************************************
+ */
+void OsSchedUnlock(void)
+{
+    if(OSSchedLock == 1)                /* Is OSSchedLock == 0?               */
+    {
+#if CFG_TASK_WAITTING_EN > 0
+        if(IsrReq == Co_TRUE)
+        {
+            RespondSRQ();               /* Respond service request            */	
+        }
+#endif
+        /* Judge task state change or higher PRI task coming in               */
+        if(TaskSchedReq == Co_TRUE)
+        {
+            Schedule();                 /* Call task schedule                 */
+        }
+		OSSchedLock = 0;
+    }
+	else
+	{
+		OSSchedLock--; 	
+	}
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Lock schedule 	 
+ * @param[in]  None		 
+ * @param[out] None   
+ * @retval     None		 
+ *
+ * @par Description
+ * @details    This function is called in application code to lock schedule.		 
+ *
+ * @note 
+ *******************************************************************************
+ */
+void CoSchedLock(void)
+{									    
+    OsSchedLock();                      /* Lock schedule                      */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Unlock schedule 	  
+ * @param[in]  None		 
+ * @param[out] None   
+ * @retval     None		 
+ *
+ * @par Description
+ * @details    This function is called in APP to unlock schedule.		 
+ *
+ * @note 
+ *******************************************************************************
+ */
+void CoSchedUnlock(void)
+{
+    OsSchedUnlock();                    /* Unlock schedule                    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Initialize OS	  
+ * @param[in]  None 	 
+ * @param[out] None 
+ * @retval     None 
+ *
+ * @par Description
+ * @details   This function is called to initialize OS.
+ *
+ * @note      You must call this function first,before any other OS API function
+ *					
+ * @code      There is a example for useage of this function,as follows: 
+ *        e.g.															 
+ *            ...                   // Your target initial code. 
+ *				
+ *            OsInit();             // Initial OS. 				
+ *            CreateTask(...);      // Create tasks.				
+ *            ...
+ *            OsStart();            // Start multitask.
+ * @endcode	
+ *******************************************************************************		
+ */
+void CoInitOS(void)
+{
+    InitSysTick();                /* Initialize system tick.                  */
+    InitInt();                    /* Initialize PendSV,SVC,SysTick interrupt  */	
+    CreateTCBList();              /* Create TCB list.                         */   
+#if CFG_EVENT_EN > 0				    
+    CreateEventList();            /* Create event control list.               */
+#endif  
+#if CFG_KHEAP_EN > 0
+    CoCreateKheap();              /* Create kernel heap within user define    */
+#endif   
+    OsSchedLock();                /* Lock Schedule                            */ 
+                                  /* Create first task -- IDLE task.          */ 
+    CoCreateTask(                      CoIdleTask,
+                                             Co_NULL,
+                                  CFG_LOWEST_PRIO,
+                 &idle_stk[CFG_IDLE_STACK_SIZE-1],
+                              CFG_IDLE_STACK_SIZE
+                 );
+				                  /* Set PSP for CoIdleTask coming in */ 
+	SetEnvironment(&idle_stk[CFG_IDLE_STACK_SIZE-1]);
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Start multitask	 
+ * @param[in]  None 	 
+ * @param[out] None 	 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to start multitask.After it is called,
+ *             OS start schedule task by priority or/and time slice.	
+ * @note       This function must be called to start OS when you use CoOS,and must
+ *             call after CoOsInit().
+ *******************************************************************************
+ */
+void CoStartOS(void)
+{
+    TCBRunning  = &TCBTbl[0];           /* Get running task                     */
+    TCBNext     = TCBRunning;           /* Set next scheduled task as running task */
+    TCBRunning->state = TASK_RUNNING;   /* Set running task status to RUNNING   */
+    RemoveFromTCBRdyList(TCBRunning);   /* Remove running task from READY list  */
+    OsSchedUnlock();					/* Enable Schedule,call task schedule   */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get OS version	   
+ * @param[in]  None	 
+ * @param[out] None  
+ * @retval     The value is version of OS mutipled by 100.		 
+ *
+ * @par Description
+ * @details    This function is used to return the version number of CooCox OS.
+ *             the return value corresponds to CooCox's version number multiplied
+ *             by 100. In other words, version 1.02 would be returned as 102.         
+ *******************************************************************************
+ */
+OS_VER CoGetOSVersion(void)
+{
+    return OS_VERSION;                  /* Get CooCox CoOS version            */
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/event.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,410 @@
+/**
+ *******************************************************************************
+ * @file       event.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      event management implementation code of CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+/*---------------------------- Variable Define -------------------------------*/
+#if CFG_EVENT_EN > 0
+
+ECB    EventTbl[CFG_MAX_EVENT]= {{0}};/*!< Table which save event control block.*/
+P_ECB  FreeEventList = 0;        /*!< Pointer to free event control block. */
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a empty list of event control block        
+ * @param[in]  None      
+ * @param[out] None       
+ * @retval     None     
+ *
+ * @par Description
+ * @details    This function is called by OSInit() API to create a ECB list,supply
+ *             a  pointer to next event control block that not used.                     
+ *******************************************************************************
+ */
+void CreateEventList(void)
+{    
+    U8  i;
+    P_ECB pecb1;
+#if CFG_MAX_EVENT > 1
+    P_ECB pecb2;
+#endif
+    i=0;
+    pecb1 = &EventTbl[0];               /* Get first item                     */
+#if CFG_MAX_EVENT == 1                  /* Build event list for only one item */                                       
+    pecb1->eventPtr  = Co_NULL;
+    pecb1->id        = i;               /* Assign ID.                         */
+    pecb1->eventType = EVENT_TYPE_INVALID;  /* Sign that not to use.          */
+#endif
+    
+#if CFG_MAX_EVENT > 1             /* Build event list for more than one item  */                                   
+    pecb2 = &EventTbl[1];
+    for(;i< (CFG_MAX_EVENT-1);i++ )
+    {
+        pecb1->eventPtr  = (void*)pecb2;      /* Set link for list            */
+        pecb1->id        = i;                 /* Assign ID.                   */
+        pecb1->eventType = EVENT_TYPE_INVALID;/* Sign that not to use.        */
+        pecb1++;                              /* Get next item                */
+        pecb2++;    
+    }
+    pecb1->eventType = EVENT_TYPE_INVALID;    /* Sign that not to use.        */
+    pecb1->eventPtr  = Co_NULL;                  /* Set link for last item       */
+    pecb1->id        = i;    
+#endif
+    
+    FreeEventList    = &EventTbl[0];          /* Set free event item          */    
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Release a ECB     
+ * @param[in]  pecb     A pointer to event control block which be released.     
+ * @param[out] None 
+ * @retval     None     
+ *
+ * @par Description
+ * @details    This function is called to release a event control block when a 
+ *             event be deleted.
+ *******************************************************************************
+ */
+static void ReleaseECB(P_ECB pecb)
+{
+    pecb->eventType = EVENT_TYPE_INVALID;     /* Sign that not to use.        */ 
+    OsSchedLock();                            /* Lock schedule                */
+    pecb->eventPtr  = FreeEventList;          /* Release ECB that event hold  */
+    FreeEventList   = pecb;                   /* Reset free event item        */
+    OsSchedUnlock();                          /* Unlock schedule              */
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a event      
+ * @param[in]  eventType       The type of event which    being created.
+ * @param[in]  eventSortType   Event sort type.
+ * @param[in]  eventCounter    Event counter,ONLY for EVENT_TYPE_SEM.
+ * @param[in]  eventPtr        Event struct pointer,ONLY for Queue.Co_NULL for other
+ *                             event type.        
+ * @param[out] None  
+ * @retval     Co_NULL     Invalid pointer,create event fail.
+ * @retval     others   Pointer to event control block which had assigned right now.
+ *
+ * @par Description
+ * @details    This function is called by CreateSem(),...
+ *             to get a event control block and initial the event content. 
+ *
+ * @note       This is a internal function of CooCox CoOS,User can't call.
+ *******************************************************************************
+ */
+P_ECB CreatEvent(U8 eventType,U8 eventSortType,void* eventPtr)
+{
+    P_ECB pecb;
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    if(FreeEventList == Co_NULL)           /* Is there no free evnet item        */
+    {
+        OsSchedUnlock();                /* Yes,unlock schedule                */
+        return 0;                    /* Return error                       */
+    }
+    pecb          = FreeEventList;/* Assign the free event item to this event */
+    FreeEventList = (P_ECB)FreeEventList->eventPtr;  /* Reset free event item        */
+    OsSchedUnlock();                    /* Unlock schedul                     */
+    
+    pecb->eventType     = eventType;    /* Initialize event item as user set  */
+    pecb->eventSortType = eventSortType;
+    pecb->eventPtr      = eventPtr;
+    pecb->eventTCBList  = 0;
+    return pecb;                        /* Return event item pointer          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a event      
+ * @param[in]  pecb     Pointer to event control block which will be deleted. 
+ * @param[in]  opt      Delete option.
+ * @arg        == OPT_DEL_ANYWAY     Delete event always   
+ * @arg        == OPT_DEL_NO_PEND     Delete event only when no task pending on.
+ * @param[out] None       
+ * @retval     E_INVALID_PARAMETER   Parameter passed is invalid,deleted fail.
+ * @retval     E_TASK_WAITTING       These are one more tasks waitting event.  
+ * @retval     E_OK                  Delete event control block successful.
+ *              
+ * @par Description
+ * @details    This function is called to delete a event from the event wait list
+ *             use specify option.
+ *
+ * @note       This is a internal function of Coocox CoOS,user can't call.        
+ *******************************************************************************
+ */
+StatusType DeleteEvent(P_ECB pecb,U8 opt)
+{
+    P_OSTCB ptcb;
+    if(opt == OPT_DEL_NO_PEND)          /* Do delete event when no task pend? */
+    {
+        if(pecb->eventTCBList != Co_NULL)  /* Yes,is there task pend this event? */
+        {
+            return E_TASK_WAITING;      /* Yes,error return                   */
+        }
+        else
+        {
+            ReleaseECB(pecb);           /* No,release resource that event hold*/
+        }
+    }
+    else if(opt == OPT_DEL_ANYWAY)      /* Do delete event anyway?            */
+    {
+        OsSchedLock();                      /* Lock schedule                  */
+        while(pecb->eventTCBList != Co_NULL)   /* Is there task pend this event? */
+        {                                   /* Yes,remove it                  */
+            ptcb = pecb->eventTCBList;/* Get first task in event waiting list */
+            if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list?    */
+            {
+                RemoveDelayList(ptcb);    /* Yes,remove task from delay list  */
+            }
+
+            /* Set next item as event waiting list head */
+            pecb->eventTCBList = ptcb->waitNext; 
+            ptcb->waitNext     = 0;  /* Clear link for event waiting list  */
+            ptcb->eventID      = INVALID_ID;  /* Sign that not to use.        */
+
+            InsertToTCBRdyList(ptcb);         /* Insert task into ready list  */
+        }
+        OsSchedUnlock();                  /* Unlock schedule                  */
+        ReleaseECB(pecb);                 /* Release resource that event hold */
+    }
+    return E_OK;                          /* Return OK                        */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Insert a task to event wait list                                 
+ * @param[in]  pecb    Pointer to event control block corresponding to the event.     
+ * @param[in]  ptcb    Pointer to task that will be insert to event wait list.     
+ * @param[out] None   
+ * @retval     None     
+ *
+ * @par Description
+ * @details   This function is called to insert a task by fllowing manner:
+ *            opt == EVENT_SORT_TYPE_FIFO   By FIFO.
+ *            opt == EVENT_SORT_TYPE_PRIO   By priority order,hghest priority 
+ *                                          as head,lowest priority as end.
+ *                                          (Highest-->...-->Lowest-->Co_NULL)
+ *******************************************************************************
+ */
+void EventTaskToWait(P_ECB pecb,P_OSTCB ptcb)
+{
+    P_OSTCB ptcb1;
+#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
+    P_OSTCB ptcb2;
+#endif
+    
+    OsSchedLock();                  /* Lock schedule                          */
+    ptcb1 = pecb->eventTCBList;     /* Get first task in event waiting list   */
+    ptcb->eventID = pecb->id;       /* Set event ID for task                  */
+    
+#if CFG_EVENT_SORT == 3             /* Does event waiting list sort as FIFO?  */
+                              
+    if(pecb->eventSortType == EVENT_SORT_TYPE_FIFO)    
+#endif
+    
+#if (CFG_EVENT_SORT == 1) || (CFG_EVENT_SORT == 3)
+    {
+        if(ptcb1 == Co_NULL)                 /* Is no item in event waiting list?*/
+        {
+            pecb->eventTCBList = ptcb;    /* Yes,set task as first item       */
+        }
+        else
+        {                                
+            while(ptcb1->waitNext != Co_NULL)/* No,insert task in last           */
+            {
+                ptcb1 = ptcb1->waitNext;    
+            }    
+            ptcb1->waitNext = ptcb;       /* Set link for list                */
+            ptcb->waitPrev  = ptcb1;    
+        }
+    }
+#endif
+    
+#if CFG_EVENT_SORT ==3 /* Does event waiting list sort as preemptive priority?*/                           
+    else if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
+#endif  
+#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
+    {
+        if(ptcb1 == Co_NULL)               /* Is no item in event waiting list?  */
+        {
+            pecb->eventTCBList = ptcb;  /* Yes,set task as first item         */
+        }
+        /* Is PRI of task higher than list first item?                        */
+        else if(ptcb1->prio > ptcb->prio) 
+        {
+            pecb->eventTCBList = ptcb;  /* Reset task as first item           */
+            ptcb->waitNext     = ptcb1; /* Set link for list                  */
+            ptcb1->waitPrev    = ptcb;    
+        }
+        else                            /* No,find correct place to insert    */
+        {                                
+            ptcb2 = ptcb1->waitNext;
+            while(ptcb2 != Co_NULL)        /* Is last item?                      */
+            {                              
+                if(ptcb2->prio > ptcb->prio)  /* No,is correct place?         */
+                { 
+                    break;                    /* Yes,break Circulation        */
+                }
+                ptcb1 = ptcb2;                /* Save current item            */
+                ptcb2 = ptcb2->waitNext;      /* Get next item                */
+            }
+            ptcb1->waitNext = ptcb;           /* Set link for list            */
+            ptcb->waitPrev  = ptcb1;
+            ptcb->waitNext  = ptcb2;
+            if(ptcb2 != Co_NULL)
+            {
+                ptcb2->waitPrev = ptcb;    
+            }
+        }        
+    }
+#endif
+    ptcb->state = TASK_WAITING;     /* Set task status to TASK_WAITING state  */
+    TaskSchedReq = Co_TRUE;
+    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Move a task from event WAITING list to the DELAY list      
+ * @param[in]  pecb    Pointer to event control block corresponding to the event.                
+ * @param[out] None  
+ * @retval     None     
+ *
+ * @par Description
+ * @details    This function is called to remove a task from event wait list,and     
+ *             then insert it into the READY list.
+ *******************************************************************************
+ */
+void EventTaskToRdy(P_ECB pecb)
+{
+    P_OSTCB ptcb;
+#if CFG_QUEUE_EN >0
+    P_QCB   pqcb;
+#endif
+    ptcb = pecb->eventTCBList;
+    if(ptcb == 0)
+        return;
+    
+    pecb->eventTCBList = ptcb->waitNext;/* Get first task in event waiting list*/
+    if(pecb->eventTCBList != Co_NULL)      /* Is no item in event waiting list?  */
+    {
+        pecb->eventTCBList->waitPrev = 0; /* No,clear link for first item  */
+    }
+    
+    ptcb->waitNext = 0;                /* Clear event waiting link for task*/
+    ptcb->eventID  = INVALID_ID;          /* Sign that not to use.            */
+    
+    if(ptcb->delayTick != INVALID_VALUE)  /* Is task in delay list?           */                 
+    {
+        RemoveDelayList(ptcb);            /* Yes,remove task from DELAY list  */
+    }
+    if(pecb->eventType == EVENT_TYPE_MBOX)/* Is it a mailbox event?           */
+    {
+        ptcb->pmail    = pecb->eventPtr;  /* Yes,send mail to task            */
+        pecb->eventPtr = Co_NULL;            /* Clear event sign                 */
+        pecb->eventCounter--;
+    }
+#if CFG_QUEUE_EN >0
+    else if(pecb->eventType == EVENT_TYPE_QUEUE)  /* Is it a queue event?     */
+    {                                           
+        pqcb        = (P_QCB)pecb->eventPtr;      /* Yes,get queue pointer    */
+        ptcb->pmail = *(pqcb->qStart + pqcb->head);   /* Send mail to task    */
+        pqcb->head++;                             /* Clear event sign         */
+        pqcb->qSize--;
+        if(pqcb->head == pqcb->qMaxSize)
+        {
+            pqcb->head = 0;    
+        }
+    }
+#endif
+
+#if CFG_MAILBOX_EN >0
+    else if(pecb->eventType == EVENT_TYPE_SEM)/* Is it a semaphore event?     */
+    {
+        pecb->eventCounter--;                 /* Yes,clear event sign         */
+        ptcb->pmail = (void*)0xffffffff;      /* Indicate task woke by event  */
+    }
+#endif
+    if(ptcb == TCBRunning)
+    {
+        ptcb->state = TASK_RUNNING;
+    } 
+    else
+    {
+        InsertToTCBRdyList(ptcb);            /* Insert task into ready list  */
+    }
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Move a task from event wait list to the ready list      
+ * @param[in]  pecb    Pointer to event control block corresponding to the event.                
+ * @param[out] None  
+ * @retval     None     
+ *
+ * @par Description
+ * @details    This function is called to remove a task from event wait list,and     
+ *             then insert it to the ready list.
+ *******************************************************************************
+ */
+void RemoveEventWaittingList(P_OSTCB ptcb)
+{
+    P_ECB pecb;
+    pecb = &EventTbl[ptcb->eventID];    /* Get event control block            */
+    
+    /* Is there only one item in event waiting list?                          */
+    if((ptcb->waitNext == 0) && (ptcb->waitPrev == 0))
+    {
+        pecb->eventTCBList = 0;      /* Yes,set event waiting list as Co_NULL */
+    }
+    else if(ptcb->waitPrev == 0)/* Is the first item in event waiting list?*/
+    {
+        /* Yes,remove task from list,and reset event waiting list             */
+        ptcb->waitNext->waitPrev = 0;
+        pecb->eventTCBList = ptcb->waitNext;    
+        ptcb->waitNext = 0;
+    }
+    else if(ptcb->waitNext == 0)/* Is the last item in event waiting list? */
+    {
+        ptcb->waitPrev->waitNext = 0;  /* Yes,remove task form list        */
+        ptcb->waitPrev = 0;
+    }
+    else                                  /* No, remove task from list        */
+    {                                        
+        ptcb->waitPrev->waitNext = ptcb->waitNext;
+        ptcb->waitNext->waitPrev = ptcb->waitPrev;
+        ptcb->waitPrev = 0;
+        ptcb->waitNext = 0;
+    }
+    ptcb->eventID  = INVALID_ID;          /* Sign that not to use.            */
+}
+
+#endif     //CFG_EVENT_EN
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/flag.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,712 @@
+/**
+ *******************************************************************************
+ * @file       flag.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Flag management implementation code of coocox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+#if CFG_FLAG_EN > 0
+/*---------------------------- Variable Define -------------------------------*/
+#define FLAG_MAX_NUM  32                /*!< Define max flag number.          */
+FCB     FlagCrl = {0};                  /*!< Flags list struct                */
+
+
+/*---------------------------- Function Declare ------------------------------*/
+static  void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType);
+static  P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode);
+
+/**
+ *******************************************************************************
+ * @brief      Create a flag     
+ * @param[in]  bAutoReset      Reset mode,Co_TRUE(Auto Reset)  FLASE(Manual Reset).
+ * @param[in]  bInitialState   Initial state.     
+ * @param[out] None  
+ * @retval     E_CREATE_FAIL   Create flag fail.
+ * @retval     others          Create flag successful.             
+ *
+ * @par Description
+ * @details    This function use to create a event flag.     
+ * @note 
+ *******************************************************************************
+ */
+OS_FlagID CoCreateFlag(BOOL bAutoReset,BOOL bInitialState)
+{
+    U8  i;
+    OsSchedLock();
+    
+    for(i=0;i<FLAG_MAX_NUM;i++)
+    {
+        /* Assign a free flag control block                                   */
+        if((FlagCrl.flagActive&(1<<i)) == 0 )
+        {
+            FlagCrl.flagActive |= (1<<i);         /* Initialize active flag   */
+            FlagCrl.flagRdy    |= (bInitialState<<i);/* Initialize ready flag */
+            FlagCrl.resetOpt   |= (bAutoReset<<i);/* Initialize reset option  */
+            OsSchedUnlock();
+            return i ;                  /* Return Flag ID                     */
+        }    
+    }
+    OsSchedUnlock();
+    
+    return E_CREATE_FAIL;               /* There is no free flag control block*/    
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a flag
+ * @param[in]  id      Flag ID.     
+ * @param[in]  opt     Delete option. 
+ * @param[out] None          
+ * @retval     E_CALL            Error call in ISR.
+ * @retval     E_INVALID_ID      Invalid event ID.
+ * @retval     E_TASK_WAITTING   Tasks waitting for the event,delete fail.
+ * @retval     E_OK              Event deleted successful.   
+ *
+ * @par Description
+ * @details    This function is called to delete a event flag.
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoDelFlag(OS_FlagID id,U8 opt)
+{
+    P_FLAG_NODE pnode;
+    P_FCB pfcb;
+    pfcb  = &FlagCrl;
+    if(OSIntNesting > 0)                /* If be called from ISR              */
+    {
+        return E_CALL;
+    }
+#if CFG_PAR_CHECKOUT_EN >0
+    if((pfcb->flagActive&(1<<id)) == 0) /* Flag is valid or not               */
+    {
+        return E_INVALID_ID;    
+    }
+#endif
+    OsSchedLock();
+    pnode = pfcb->headNode;
+    
+    while(pnode != Co_NULL)                /* Ready all tasks waiting for flags  */
+    {
+        if((pnode->waitFlags&(1<<id)) != 0) /* If no task is waiting on flags */
+          {
+            if(opt == OPT_DEL_NO_PEND)      /* Delete flag if no task waiting */
+            {
+                  OsSchedUnlock();
+                   return E_TASK_WAITING;
+            }
+            else if (opt == OPT_DEL_ANYWAY) /* Always delete the flag         */
+            {
+                if(pnode->waitType == OPT_WAIT_ALL)
+                {
+                    /* If the flag is only required by NODE                   */
+                    if( pnode->waitFlags == (1<<id) )    
+                    {
+                        /* Remove the NODE from waiting list                  */
+                        pnode = RemoveFromLink(pnode);     
+                        continue;    
+                    }    
+                    else
+                    {
+                        pnode->waitFlags &= ~(1<<id);   /* Update waitflags   */
+                    }        
+                }
+                else                               
+                {
+                    pnode = RemoveFromLink(pnode);
+                    continue;    
+                }    
+            }
+        }    
+        pnode = pnode->nextNode;        
+    }
+    
+    /* Remove the flag from the flags list */
+    pfcb->flagActive &= ~(1<<id);            
+    pfcb->flagRdy    &= ~(1<<id);
+    pfcb->resetOpt   &= ~(1<<id);
+    OsSchedUnlock();
+    return E_OK;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      AcceptSingleFlag  
+ * @param[in]  id     Flag ID.
+ * @param[out] None
+ * @retval     E_INVALID_ID      Invalid event ID.
+ * @retval     E_FLAG_NOT_READY  Flag is not in ready state.
+ * @retval     E_OK              The call was successful and your task owns the Flag.
+ *
+ * @par Description
+ * @details    This fucntion is called to accept single flag
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoAcceptSingleFlag(OS_FlagID id)
+{
+    P_FCB pfcb;
+    pfcb  = &FlagCrl;
+#if CFG_PAR_CHECKOUT_EN >0    
+    if(id >= FLAG_MAX_NUM)              
+    {
+        return E_INVALID_ID;            /* Invalid 'id',return error          */
+    }
+    if((pfcb->flagActive&(1<<id)) == 0) 
+    {
+        return E_INVALID_ID;            /* Flag is deactive,return error      */
+    }    
+#endif
+    if((pfcb->flagRdy&(1<<id)) != 0)    /* If the required flag is set        */
+    {
+        OsSchedLock()
+        pfcb->flagRdy &= ~((FlagCrl.resetOpt)&(1<<id)); /* Clear the flag     */
+        OsSchedUnlock();
+        return E_OK;
+    }
+    else                                /* If the required flag is not set    */
+    {
+        return E_FLAG_NOT_READY;
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      AcceptMultipleFlags 
+ * @param[in]  flags      Flags that waiting to active task.
+ * @param[in]  waitType   Flags wait type.
+ * @param[out] perr       A pointer to error code.
+ * @retval     0
+ * @retval     springFlag
+ *
+ * @par Description
+ * @details    This fucntion is called to accept multiple flags. 
+ * @note 
+ *******************************************************************************
+ */
+U32 CoAcceptMultipleFlags(U32 flags,U8 waitType,StatusType *perr)
+{
+    U32  springFlag;
+    P_FCB pfcb;
+    pfcb  = &FlagCrl;
+    
+#if CFG_PAR_CHECKOUT_EN >0    
+    if((flags&pfcb->flagActive) != flags )  /* Judge flag is active or not?   */    
+    {
+        *perr = E_INVALID_PARAMETER;        /* Invalid flags                  */
+        return 0;
+    }
+#endif
+    
+    springFlag = flags & pfcb->flagRdy;
+    
+    OsSchedLock();
+    /* If any required flags are set */
+    if( (springFlag != 0) && (waitType == OPT_WAIT_ANY) )    
+    {
+        
+        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);  /* Clear the flags  */
+        OsSchedUnlock();
+        *perr = E_OK;
+        return springFlag;
+    }
+    
+    /* If all required flags are set */
+    if((springFlag == flags) && (waitType == OPT_WAIT_ALL))
+    {
+        pfcb->flagRdy &= ~(springFlag&pfcb->resetOpt);    /* Clear the flags  */
+        OsSchedUnlock();    
+        *perr = E_OK;                    
+        return springFlag;             
+    }
+    OsSchedUnlock();
+    *perr = E_FLAG_NOT_READY;        
+    return 0;
+}
+
+
+
+
+/**
+ *******************************************************************************
+ * @brief      WaitForSingleFlag 
+ * @param[in]  id        Flag ID.
+ * @param[in]  timeout   The longest time for writting flag.
+ * @param[out] None   
+ * @retval     E_CALL         Error call in ISR.   
+ * @retval     E_INVALID_ID   Invalid event ID.    
+ * @retval     E_TIMEOUT      Flag wasn't received within 'timeout' time.
+ * @retval     E_OK           The call was successful and your task owns the Flag,
+ *                            or the event you are waiting for occurred.     
+ *
+ * @par Description
+ * @details    This function is called to wait for only one flag,
+ *             (1) if parameter "timeout" == 0,waiting until flag be set;
+ *             (2) when "timeout" != 0,if flag was set or wasn't set but timeout 
+ *                 occured,the task will exit the waiting list,convert to READY 
+ *                 or RUNNING state.  
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoWaitForSingleFlag(OS_FlagID id,U32 timeout)
+{
+    FLAG_NODE flagNode;
+    P_FCB     pfcb;
+    P_OSTCB   curTCB;
+    
+    if(OSIntNesting > 0)                /* See if the caller is ISR           */
+    {
+        return E_CALL;
+    }
+    if(OSSchedLock != 0)                /* Schedule is lock?                  */
+    {                                 
+        return E_OS_IN_LOCK;            /* Yes,error return                   */
+    }    
+    
+#if CFG_PAR_CHECKOUT_EN >0    
+    if(id >= FLAG_MAX_NUM)              /* Judge id is valid or not?          */  
+    {
+        return E_INVALID_ID;            /* Invalid 'id'                       */          
+    }
+    if((FlagCrl.flagActive&(1<<id)) == 0 )/* Judge flag is active or not?       */
+    {
+        return E_INVALID_ID;            /* Flag is deactive ,return error     */
+    }    
+#endif
+
+       OsSchedLock();
+    pfcb = &FlagCrl;
+    /* See if the required flag is set */
+    if((pfcb->flagRdy&(1<<id)) != 0)    /* If the required flag is set        */
+    {
+        pfcb->flagRdy &= ~((pfcb->resetOpt&(1<<id))); /* Clear the flag       */
+        OsSchedUnlock();
+    }
+    else                                /* If the required flag is not set    */
+    {
+        curTCB = TCBRunning;
+        if(timeout == 0)                /* If time-out is not configured      */
+        {
+            /* Block task until the required flag is set                      */
+            FlagBlock (&flagNode,(1<<id),OPT_WAIT_ONE);  
+            curTCB->state  = TASK_WAITING;    
+            TaskSchedReq   = Co_TRUE;
+            OsSchedUnlock();
+            
+            /* The required flag is set and the task is in running state      */
+            curTCB->pnode  = Co_NULL;
+            OsSchedLock();
+            
+            /* Clear the required flag or not                                 */    
+            pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt)); 
+            OsSchedUnlock();
+        }
+        else                            /* If time-out is configured          */
+        {
+            /* Block task until the required flag is set or time-out occurs   */
+            FlagBlock(&flagNode,(1<<id),OPT_WAIT_ONE);
+            InsertDelayList(curTCB,timeout);
+            
+            OsSchedUnlock();
+            if(curTCB->pnode == Co_NULL)     /* If time-out occurred             */
+            {
+                return E_TIMEOUT;        
+            }
+            else                          /* If flag is set                   */
+            {
+                curTCB->pnode = Co_NULL;
+                OsSchedLock();
+                
+                /* Clear the required flag or not                             */
+                pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));     
+                OsSchedUnlock();
+            }    
+        }
+    }
+    return E_OK;    
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      WaitForMultipleFlags 
+ * @param[in]  flags      Flags that waiting to active task.
+ * @param[in]  waitType   Flags wait type.
+ * @param[in]  timeout    The longest time for writting flag.
+ * @param[out] perr       A pointer to error code.
+ * @retval     0
+ * @retval     springFlag     
+ *
+ * @par Description
+ * @details    This function is called to pend a task for waitting multiple flag. 
+ * @note 
+ *******************************************************************************
+ */
+U32 CoWaitForMultipleFlags(U32 flags,U8 waitType,U32 timeout,StatusType *perr)
+{
+    U32       springFlag;      
+    P_FCB     pfcb;
+    FLAG_NODE flagNode;
+    P_OSTCB   curTCB;
+    
+   
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        *perr = E_CALL;
+        return 0;
+    }
+    if(OSSchedLock != 0)                /* Schedule is lock?                  */
+    {    
+        *perr = E_OS_IN_LOCK;                             
+        return 0;                       /* Yes,error return                   */
+    }
+#if CFG_PAR_CHECKOUT_EN >0  
+    if( (flags&FlagCrl.flagActive) != flags )
+    {
+        *perr = E_INVALID_PARAMETER;    /* Invalid 'flags'                    */
+        return 0;
+    }
+#endif
+    OsSchedLock();
+    pfcb = &FlagCrl;
+    springFlag = flags & pfcb->flagRdy;
+    
+    /* If any required flags are set  */
+    if((springFlag != 0) && (waitType == OPT_WAIT_ANY))
+    {
+        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);  /* Clear the flag   */
+        OsSchedUnlock();
+        *perr = E_OK;
+        return springFlag;
+    }
+    
+    /* If all required flags are set */
+    if( (springFlag == flags) && (waitType == OPT_WAIT_ALL) )  
+    {
+        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);  /* Clear the flags  */
+        OsSchedUnlock();    
+        *perr = E_OK;
+        return springFlag;             
+    }
+    
+    curTCB = TCBRunning;
+    if(timeout == 0)                    /* If time-out is not configured      */
+    {
+        /* Block task until the required flag are set                         */
+        FlagBlock(&flagNode,flags,waitType);
+        curTCB->state  = TASK_WAITING;    
+        TaskSchedReq   = Co_TRUE;
+        OsSchedUnlock();
+        
+        curTCB->pnode  = Co_NULL;
+        OsSchedLock();                 
+        springFlag     = flags & pfcb->flagRdy;        
+        pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);/* Clear the flags    */    
+        OsSchedUnlock();
+        *perr = E_OK;
+        return springFlag;
+    }
+    else                                /* If time-out is configured          */
+    {
+        /* Block task until the required flag are set or time-out occurred    */
+        FlagBlock(&flagNode,flags,waitType);
+        InsertDelayList(curTCB,timeout);
+        
+        OsSchedUnlock();
+        if(curTCB->pnode == Co_NULL)       /* If time-out occurred               */
+        {
+            *perr = E_TIMEOUT;
+            return 0;    
+        }
+        else                            /* If the required flags are set      */
+        {
+            curTCB->pnode = Co_NULL;
+            OsSchedLock();
+            springFlag    = flags & FlagCrl.flagRdy;
+            
+            /* Clear the required ready flags or not */
+            pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);    
+            OsSchedUnlock();
+            *perr = E_OK;
+            return springFlag;    
+        }    
+    }    
+}
+
+
+/**
+ *******************************************************************************
+ * @brief       Clear a Flag     
+ * @param[in]   id     Flag ID.
+ * @param[out]  None
+ * @retval      E_OK           Event deleted successful.      
+ * @retval      E_INVALID_ID   Invalid event ID.      
+ *
+ * @par Description
+ * @details     This function is called to clear a flag. 
+ *
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoClearFlag(OS_FlagID id)
+{
+    P_FCB pfcb;
+    pfcb = &FlagCrl;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= FLAG_MAX_NUM)                  
+    {
+        return E_INVALID_ID;                /* Invalid id                     */    
+    }
+    if((pfcb->flagActive&(1<<id)) == 0)     
+    {
+        return E_INVALID_ID;                /* Invalid flag                   */
+    }
+#endif
+
+    pfcb->flagRdy &= ~(1<<id);              /* Clear the flag                 */
+    return E_OK;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Set a flag       
+ * @param[in]  id     Flag ID.
+ * @param[out] None
+ * @retval     E_INVALID_ID   Invalid event ID.
+ * @retval     E_OK           Event deleted successful.      
+ *
+ * @par Description
+ * @details    This function is called to set a flag. 
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoSetFlag(OS_FlagID id)
+{
+    P_FLAG_NODE pnode;
+    P_FCB pfcb;
+    pfcb  = &FlagCrl;
+    
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= FLAG_MAX_NUM)              /* Flag is valid or not               */                            
+    {
+        return E_INVALID_ID;            /* Invalid flag id                    */          
+    }
+    if((pfcb->flagActive&(1<<id)) == 0)  
+    {
+        return E_INVALID_ID;            /* Flag is not exist                  */
+    }
+#endif
+    
+    if((pfcb->flagRdy&(1<<id)) != 0)    /* Flag had already been set          */
+    {
+        return E_OK;
+    }
+    
+    pfcb->flagRdy |= (1<<id);           /* Update the flags ready list        */
+    
+    OsSchedLock();
+    pnode = pfcb->headNode;              
+    while(pnode != Co_NULL)
+    {
+        if(pnode->waitType == OPT_WAIT_ALL)   /* Extract all the bits we want */
+          {            
+            if((pnode->waitFlags&pfcb->flagRdy) == pnode->waitFlags)
+            {
+               /* Remove the flag node from the wait list                    */
+                pnode = RemoveFromLink(pnode);        
+                if((pfcb->resetOpt&(1<<id)) != 0)/* If the flags is auto-reset*/    
+                {
+                    break;                            
+                }
+                continue;    
+            }    
+          }
+        else                           /* Extract only the bits we want       */    
+          {
+            if( (pnode->waitFlags & pfcb->flagRdy) != 0)
+            {
+                /* Remove the flag node from the wait list                    */
+                pnode = RemoveFromLink(pnode);         
+                if((pfcb->resetOpt&(1<<id)) != 0)
+                {
+                    break;              /* The flags is auto-reset            */    
+                }
+                continue;
+            }    
+          }
+          pnode = pnode->nextNode;                    
+    }
+    OsSchedUnlock();
+    return E_OK;
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Set a flag    in ISR 
+ * @param[in]  id     Flag ID.
+ * @param[out] None 
+ * @retval     E_INVALID_ID   Invalid event ID.
+ * @retval     E_OK           Event deleted successful.      
+ *
+ * @par Description
+ * @details    This function is called in ISR to set a flag. 
+ * @note 
+ *******************************************************************************
+ */
+#if CFG_MAX_SERVICE_REQUEST > 0
+StatusType isr_SetFlag(OS_FlagID id)
+{
+    if(OSSchedLock > 0)         /* If scheduler is locked,(the caller is ISR) */
+    {
+        /* Insert the request into service request queue                      */
+        if(InsertInSRQ(FLAG_REQ,id,Co_NULL) == Co_FALSE)
+        {
+            return E_SEV_REQ_FULL;      /* The service requst queue is full   */
+        }            
+        else
+        {
+            return E_OK;                               
+        }
+    }
+    else
+    {
+        return(CoSetFlag(id));          /* The caller is not ISR, set the flag*/
+    }
+}
+#endif
+
+/**
+ *******************************************************************************
+ * @brief      Block a task to wait a flag event  
+ * @param[in]  pnode       A node that will link into flag waiting list.
+ * @param[in]  flags       Flag(s) that the node waiting for.
+ * @param[in]  waitType    Waiting type of the node.
+ * @param[out] None     
+ * @retval     None
+ *
+ * @par Description
+ * @details    This function is called to block a task to wait a flag event.     
+ * @note 
+ *******************************************************************************
+ */
+static void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType)
+{
+    P_FCB     pfcb;
+    pfcb  = &FlagCrl;
+    
+    TCBRunning->pnode = pnode;    
+    pnode->waitTask   = TCBRunning;
+    pnode->waitFlags  = flags;      /* Save the flags that we need to wait for*/
+    pnode->waitType   = waitType;   /* Save the type of wait                  */
+        
+    if(pfcb->tailNode == 0)      /* If this is the first NODE to insert?   */
+    {
+        pnode->nextNode = 0;
+        pnode->prevNode = 0;
+        pfcb->headNode  = pnode;    /* Insert the NODE to the head            */    
+    }
+    else                            /* If it is not the first NODE to insert? */
+    {
+        pfcb->tailNode->nextNode = pnode;   /* Insert the NODE to the tail    */
+        pnode->prevNode          = pfcb->tailNode;
+        pnode->nextNode          = 0;
+    }
+    pfcb->tailNode = pnode;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Remove a flag node from list
+ * @param[in]  pnode    A node that will remove from flag waiting list.
+ * @param[out] None   
+ * @retval     pnode    Next node of the node that have removed out.
+ *
+ * @par Description
+ * @details   This function is called to remove a flag node from the wait list.             
+ * @note 
+ *******************************************************************************
+ */
+static P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode)
+{
+    P_OSTCB ptcb;
+    
+    RemoveLinkNode(pnode);            /* Remove the flag node from wait list. */             
+    ptcb = pnode->waitTask;
+    
+    /* The task in the delay list */
+    if(ptcb->delayTick != INVALID_VALUE)/* If the task is in tick delay list  */                     
+    {
+        RemoveDelayList(ptcb);        /* Remove the task from tick delay list */    
+    }
+    
+    ptcb->pnode = (void*)0xffffffff;
+
+    if(ptcb == TCBRunning)
+    {
+        ptcb->state = TASK_RUNNING;
+    } 
+    else
+    {
+        InsertToTCBRdyList(ptcb);         /* Insert the task to ready list        */    
+    }   
+    return (pnode->nextNode);    
+}
+
+/**
+ *******************************************************************************
+ * @brief      Remove a flag node from list  
+ * @param[in]  pnode     A node that will remove from flag waiting list.
+ * @param[out] None   
+ * @retval     None        
+ *
+ * @par Description
+ * @details    This function is called to remove a flag node from the wait list.             
+ * @note 
+ *******************************************************************************
+ */
+void RemoveLinkNode(P_FLAG_NODE pnode)
+{
+    /* If only one NODE in the list*/
+    if((pnode->nextNode == 0) && (pnode->prevNode == 0))
+    {
+        FlagCrl.headNode = 0;
+        FlagCrl.tailNode = 0;
+    }
+    else if(pnode->nextNode == 0)      /* If the NODE is tail              */
+    {
+        FlagCrl.tailNode          = pnode->prevNode;
+        pnode->prevNode->nextNode = 0;
+    }
+    else if(pnode->prevNode == 0)      /* If the NODE is head              */
+    {
+        FlagCrl.headNode          = pnode->nextNode;
+        pnode->nextNode->prevNode = 0;
+    }
+    else                                  /* The NODE is in the middle        */
+    {
+        pnode->nextNode->prevNode = pnode->prevNode;
+        pnode->prevNode->nextNode = pnode->nextNode;
+    }
+    pnode->waitTask->pnode = 0;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/hook.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,65 @@
+/**
+ *******************************************************************************
+ * @file       hook.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      hook management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Inlcude --------------------------------------*/
+#include <coocox.h>
+
+/**
+ *******************************************************************************
+ * @brief      IDLE task of OS	 
+ * @param[in]  pdata	The parameter passed to IDLE task.		 
+ * @param[out] None 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is system IDLE task code.	 
+ *******************************************************************************
+ */
+void CoIdleTask(void* pdata)
+{
+    /* Add your codes here */
+    for(; ;) 
+    {
+        /* Add your codes here */
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Hook for stack overflow	 
+ * @param[in]  taskID	Piont to the task which lead to stack overflow.		 
+ * @param[out] None 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is a hook for stack overflow.	 
+ *******************************************************************************
+ */
+void CoStkOverflowHook(OS_TID taskID)
+{
+    /* Process stack overflow  here */
+    for(; ;) 
+    {
+      
+    }
+}
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/kernelHeap.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,409 @@
+/**
+ *******************************************************************************
+ * @file       kernelHeap.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      kernel heap management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+#if CFG_KHEAP_EN >0
+/*---------------------------- Variable Define -------------------------------*/
+U32     KernelHeap[KHEAP_SIZE] = {0};   /*!< Kernel heap                      */
+P_FMB   FMBlist = Co_NULL;                 /*!< Free memory block list           */
+KHeap   Kheap   = {0};                  /*!< Kernel heap control              */
+
+
+/*---------------------------- Function Declare ------------------------------*/
+static P_FMB  GetPreFMB(P_UMB usedMB);
+/**
+ *******************************************************************************
+ * @brief      Create kernel heap	 
+ * @param[in]  None
+ * @param[out] None
+ * @retval     None			 
+ *
+ * @par Description
+ * @details    This function is called to create kernel heap.
+ *******************************************************************************
+ */
+void CoCreateKheap(void)
+{
+    Kheap.startAddr  = (U32)(KernelHeap); /* Initialize kernel heap control   */
+    Kheap.endAddr    = (U32)(KernelHeap) + KHEAP_SIZE*4;
+    FMBlist          = (P_FMB)KernelHeap; /* Initialize free memory block list*/
+    FMBlist->nextFMB = Co_NULL;
+    FMBlist->nextUMB = Co_NULL;
+    FMBlist->preUMB  = Co_NULL;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Allocation size bytes of memory block from kernel heap.
+ * @param[in]  size     Length of menory block.	
+ * @param[out] None
+ * @retval     Co_NULL     Allocate fail.
+ * @retval     others   Pointer to memory block.		 
+ *
+ * @par Description
+ * @details    This function is called to allocation size bytes of memory block.
+ *******************************************************************************
+ */
+void* CoKmalloc(U32 size)
+{
+    P_FMB freeMB,newFMB,preFMB;
+    P_UMB usedMB,tmpUMB;
+    U8*   memAddr;
+    U32   freeSize;
+    U32   kheapAddr;
+    
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if( size == 0 )
+    {
+        return Co_NULL;
+    }
+#endif
+
+    /* Word alignment,and add used memory head size */
+    size      = (((size+3)>>2)<<2) + 8;
+    kheapAddr = Kheap.endAddr;        /* Get the end address of kernel heap   */
+    OsSchedLock();                    /* Lock schedule                        */
+    freeMB = FMBlist;                 /* Get first item of free memory list   */
+    preFMB = Co_NULL;
+    while(freeMB != Co_NULL )            /* Is out of free memory list?          */
+    {                                 /* No                                   */
+        if(freeMB->nextUMB == Co_NULL)   /* Is last item of free memory list?    */
+        {                             /* Yes,get size for this free item      */
+            freeSize = kheapAddr - (U32)(freeMB);
+        }
+        else                          /* No,get size for this free item       */
+        {							   
+            freeSize = (U32)(freeMB->nextUMB) -1 - (U32)(freeMB);	
+        }
+        if(freeSize >= size)        /* If the size equal or greater than need */
+        {                           /* Yes,assign in this free memory         */
+            usedMB=(P_UMB)freeMB;/* Get the address for used memory block head*/
+            
+            /* Get the address for used memory block                          */
+            memAddr = (U8*)((U32)(usedMB) + 8);	
+            
+            /* Is left size of free memory smaller than 12?                   */	 
+            if((freeSize-size) < 12)	 
+            {		
+                /* Yes,malloc together(12 is the size of the header information 
+                   of free memory block ).                                    */
+                if(preFMB != Co_NULL)/* Is first item of free memory block list? */
+                {                             /* No,set the link for list     */
+                    preFMB->nextFMB = freeMB->nextFMB;
+                }
+                else                          /* Yes,reset the first item     */
+                {						
+                    FMBlist = freeMB->nextFMB;		
+                }
+                
+                if(freeMB->nextUMB != Co_NULL)   /* Is last item?                */
+                {                             /* No,set the link for list     */
+                    tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1); 
+                    tmpUMB->preMB = (void*)((U32)usedMB|0x1);
+                }
+                
+                usedMB->nextMB = freeMB->nextUMB;/* Set used memory block link*/
+                usedMB->preMB  = freeMB->preUMB;
+            }
+            else                            /* No,the left size more than 12  */
+            {		
+                /* Get new free memory block address                          */
+                newFMB = (P_FMB)((U32)(freeMB) + size);
+                
+                if(preFMB != Co_NULL)/* Is first item of free memory block list? */
+                {						
+                    preFMB->nextFMB = newFMB; /* No,set the link for list     */		
+                }	
+                else
+                {					    
+                    FMBlist = newFMB;         /* Yes,reset the first item     */	
+                }
+                
+                /* Set link for new free memory block                         */
+                newFMB->preUMB  = (P_UMB)((U32)usedMB|0x1);
+                newFMB->nextUMB = freeMB->nextUMB;
+                newFMB->nextFMB = freeMB->nextFMB;
+                
+                if(freeMB->nextUMB != Co_NULL) /* Is last item?                  */
+                {                           /* No,set the link for list       */
+                    tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1); 
+                    tmpUMB->preMB = newFMB;
+                }
+                
+                usedMB->nextMB = newFMB;    /* Set used memory block link     */
+                usedMB->preMB  = freeMB->preUMB;
+            }
+          
+            if(freeMB->preUMB != Co_NULL)      /* Is first item?                 */
+            {                               /* No,set the link for list       */
+                tmpUMB = (P_UMB)((U32)(freeMB->preUMB)-1); 
+                tmpUMB->nextMB = (void*)((U32)usedMB|0x1);
+            }
+          
+            OsSchedUnlock();              /* Unlock schedule                  */
+            return memAddr;               /* Return used memory block address */
+        }
+        preFMB = freeMB;        /* Save current free memory block as previous */
+        freeMB = freeMB->nextFMB;         /* Get the next item as current item*/
+    }
+    OsSchedUnlock();                      /* Unlock schedule                  */
+    return Co_NULL;                          /* Error return                     */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Release memory block to kernel heap.  
+ * @param[in]  memBuf    Pointer to memory block.
+ * @param[out] None
+ * @retval     None  		 
+ *
+ * @par Description
+ * @details    This function is called to release memory block.
+ *******************************************************************************
+ */
+void CoKfree(void* memBuf)
+{
+    P_FMB    curFMB,nextFMB,preFMB;
+    P_UMB    usedMB,nextUMB,preUMB;
+
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(memBuf == Co_NULL)
+    {
+        return;
+    }
+#endif
+    
+    usedMB = (P_UMB)((U32)(memBuf)-8);
+    
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if((U32)(memBuf) < Kheap.startAddr)
+    {
+        return;
+    }
+    if((U32)(memBuf) > Kheap.endAddr)
+    {
+        return;
+    }
+#endif
+    
+    
+    OsSchedLock();                      /* Lock schedule                      */
+
+#if CFG_PAR_CHECKOUT_EN >0              /* Check UMB in list                  */ 
+    if((U32)(usedMB) < (U32)(FMBlist))
+    {
+        preUMB = (P_UMB)((U32)(FMBlist->preUMB)-1);
+        while(preUMB != usedMB)	
+        {
+            if(preUMB == Co_NULL)
+            {
+                OsSchedUnlock();
+                return;
+            }
+            preUMB = (P_UMB)((U32)(preUMB->preMB)-1);	
+        }
+    }
+    else
+    {
+        if(FMBlist == Co_NULL)
+        {
+            nextUMB = (P_UMB)(Kheap.startAddr);	
+        }
+        else
+        {
+            if(FMBlist->nextUMB != Co_NULL)
+            {
+                nextUMB = (P_UMB)((U32)(FMBlist->nextUMB)-1);	
+            }
+            else
+            {
+                nextUMB = Co_NULL;
+            }
+        }
+    	
+        while(nextUMB != usedMB)	
+        {
+            if(nextUMB == Co_NULL)
+            {
+                OsSchedUnlock();
+                return;
+            }	
+            if(((U32)(nextUMB->nextMB)&0x1) == 0)		
+            {
+                nextFMB = (P_FMB)(nextUMB->nextMB);
+                nextUMB = (P_UMB)((U32)(nextFMB->nextUMB)-1);		
+            }
+            else
+            {
+                nextUMB = (P_UMB)((U32)(nextUMB->nextMB)-1);	
+            }
+        }		
+    }
+#endif
+    
+    
+    /* Is between two free memory block? */	 
+    if( (((U32)(usedMB->nextMB)&0x1) == 0) && (((U32)(usedMB->preMB)&0x1)==0) )	
+    {                             /* Yes,is the only one item in kernel heap? */
+        if((usedMB->nextMB == Co_NULL) && (usedMB->preMB == Co_NULL))
+        {
+            curFMB = (P_FMB)usedMB;       /* Yes,release this item            */
+            curFMB->nextFMB = Co_NULL;
+            curFMB->nextUMB = Co_NULL;
+            curFMB->preUMB  = Co_NULL;
+            FMBlist = curFMB;	
+        }
+        else if(usedMB->preMB == Co_NULL)    /* Is the first item in kernel heap */
+        {		
+            /* Yes,release this item,and set link for list                    */						
+            curFMB  = (P_FMB)usedMB; 
+            nextFMB = (P_FMB)usedMB->nextMB;
+            
+            curFMB->nextFMB = nextFMB->nextFMB;	
+            curFMB->nextUMB = nextFMB->nextUMB;
+            curFMB->preUMB  = Co_NULL;
+            FMBlist         = curFMB;
+        }
+        else if(usedMB->nextMB == Co_NULL)   /* Is the last item in kernel heap  */
+        {                      /* Yes,release this item,and set link for list */
+            curFMB = (P_FMB)(usedMB->preMB);	
+            curFMB->nextFMB = Co_NULL;
+            curFMB->nextUMB = Co_NULL;
+        }							    
+        else                  /* All no,show this item between two normal FMB */
+        {		
+            /* release this item,and set link for list                        */						  
+            nextFMB = (P_FMB)usedMB->nextMB;
+            curFMB  = (P_FMB)(usedMB->preMB);	
+            
+            curFMB->nextFMB = nextFMB->nextFMB;
+            curFMB->nextUMB = nextFMB->nextUMB;
+        }
+    }
+    else if(((U32)(usedMB->preMB)&0x1) == 0)  /* Is between FMB and UMB?      */
+    {								   
+        if(usedMB->preMB == Co_NULL)   /* Yes,is the first item in kernel heap?  */
+        {
+            /* Yes,release this item,and set link for list                    */
+            curFMB          = (P_FMB)usedMB;      
+            nextUMB         = (P_UMB)usedMB->nextMB;		
+            curFMB->nextUMB = nextUMB;
+            curFMB->preUMB  = Co_NULL;
+            curFMB->nextFMB = FMBlist;
+            FMBlist         = curFMB;
+        }
+        else                    /* No,release this item,and set link for list */
+        {							      
+            curFMB          = (P_FMB)usedMB->preMB;
+            nextUMB         = (P_UMB)usedMB->nextMB;
+            curFMB->nextUMB = nextUMB;
+        }
+    
+    }
+    else if(((U32)(usedMB->nextMB)&0x1) == 0)   /* Is between UMB and FMB?    */
+    {                                           /* Yes                        */
+        preUMB = (P_UMB)(usedMB->preMB);        /* Get previous UMB           */
+        curFMB = (P_FMB)(usedMB);               /* new FMB                    */
+        preFMB = GetPreFMB(usedMB);             /* Get previous FMB           */
+        if(preFMB == Co_NULL)                      /* Is previous FMB==Co_NULL?     */
+        {	
+            nextFMB = FMBlist;                  /* Yes,get next FMB           */ 
+            FMBlist = curFMB;   /* Reset new FMB as the first item of FMB list*/
+        }
+        else
+        {
+            nextFMB = preFMB->nextFMB;          /* No,get next FMB            */
+            preFMB->nextFMB  = curFMB;          /* Set link for FMB list      */
+        }
+        
+        if(nextFMB == Co_NULL)           /* Is new FMB as last item of FMB list? */
+        {	
+            curFMB->preUMB  = preUMB;           /* Yes,set link for list      */
+            curFMB->nextUMB = Co_NULL;
+            curFMB->nextFMB = Co_NULL;
+        }	
+        else
+        {
+            curFMB->preUMB  = preUMB;           /* No,set link for list       */
+            curFMB->nextUMB = nextFMB->nextUMB;
+            curFMB->nextFMB = nextFMB->nextFMB;	
+        }
+    }
+    else                                    /* All no,show UMB between two UMB*/
+    {									  
+        curFMB  = (P_FMB)(usedMB);          /* new FMB                        */
+        preFMB  = GetPreFMB(usedMB);        /* Get previous FMB               */
+        preUMB  = (P_UMB)(usedMB->preMB);   /* Get previous UMB               */
+        nextUMB = (P_UMB)(usedMB->nextMB);  /* Get next UMB                   */
+        
+        if(preFMB == Co_NULL )                 /* Is previous FMB==Co_NULL?         */
+        {
+            nextFMB = FMBlist;              /* Yes,get next FMB               */
+            FMBlist = curFMB;  /* Reset new FMB as the first item of FMB list */
+      	}
+      	else
+      	{
+            nextFMB = preFMB->nextFMB;      /* No,get next FMB                */
+            preFMB->nextFMB = curFMB;       /* Set link for FMB list          */
+      	}
+      	
+        curFMB->preUMB  = preUMB;           /* Set current FMB link for list  */
+        curFMB->nextUMB = nextUMB;
+        curFMB->nextFMB = nextFMB;
+    }
+    
+    if(curFMB->preUMB != Co_NULL)/* Is current FMB as first item in kernel heap? */
+    {                         /* No,set link for list                         */
+      	preUMB = (P_UMB)((U32)(curFMB->preUMB)-1); 
+      	preUMB->nextMB = (void*)curFMB;
+    }
+    if(curFMB->nextUMB != Co_NULL)/* Is current FMB as last item in kernel heap? */
+    {                          /* No,set link for list                        */
+      	nextUMB = (P_UMB)((U32)(curFMB->nextUMB)-1); 
+      	nextUMB->preMB = (void*)curFMB;		
+    }
+    OsSchedUnlock();           /* Unlock schedule                             */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get previous free memory block pointer.  
+ * @param[in]  usedMB    Current used memory block.
+ * @param[out] None
+ * @retval     Previous free memory block pointer.		 
+ *
+ * @par Description
+ * @details    This function is called to get previous free memory block pointer.
+ *******************************************************************************
+ */
+static P_FMB GetPreFMB(P_UMB usedMB)
+{
+    P_UMB preUMB;
+    preUMB = usedMB;
+    while(((U32)(preUMB->preMB)&0x1))   /* Is previous MB as FMB?             */
+    {                                   /* No,get previous MB                 */
+        preUMB = (P_UMB)((U32)(preUMB->preMB)-1);
+    }	
+    return (P_FMB)(preUMB->preMB);      /* Yes,return previous MB             */
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/mbox.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,325 @@
+/**
+ *******************************************************************************
+ * @file       mbox.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Mailbox management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+#if CFG_MAILBOX_EN > 0
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a mailbox	 
+ * @param[in]  sortType     Mail box waiting list sort type.			 
+ * @param[out] None  
+ * @retval     E_CREATE_FAIL   Create mailbox fail.
+ * @retval     others          Create mailbox successful.		 
+ *
+ * @par Description
+ * @details    This function is called to create a mailbox. 
+ * @note 
+ *******************************************************************************
+ */
+OS_EventID CoCreateMbox(U8 sortType)
+{
+    P_ECB pecb;
+    
+    /* Create a mailbox type event control block                              */
+    pecb = CreatEvent(EVENT_TYPE_MBOX,sortType,Co_NULL);
+    if(pecb == Co_NULL)                    /* If failed to create event block    */
+    {
+        return E_CREATE_FAIL;
+    }
+    pecb->eventCounter = 0;
+    return (pecb->id);      /* Create a mailbox successfully, return event ID */		
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a mailbox	   
+ * @param[in]  id     Event ID.
+ * @param[in]  opt    Delete option.	 
+ * @param[out] None   	 
+ * @retval     E_INVALID_ID         Invalid event ID.
+ * @retval     E_INVALID_PARAMETER  Invalid parameter.
+ * @retval     E_TASK_WAITTING      Tasks waitting for the event,delete fail.
+ * @retval     E_OK                 Event deleted successful. 
+ *
+ * @par Description
+ * @details    This function is called to delete a mailbox.	 
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoDelMbox(OS_EventID id,U8 opt)
+{
+    P_ECB pecb;
+    
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)               /* Judge id is valid or not?        */ 
+    {
+        return E_INVALID_ID;              /* Id is invalid ,return error      */
+    }
+#endif
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/    
+    {
+        return E_INVALID_ID;              /* The event is not mailbox         */	
+    }
+#endif	
+    return (DeleteEvent(pecb,opt)); /* Delete the mailbox event control block */
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Accept a mailbox	 
+ * @param[in]  id    Event ID.  	 
+ * @param[out] perr  A pointer to error code.  
+ * @retval     Co_NULL
+ * @retval     A pointer to mailbox accepted.			 
+ *
+ * @par Description
+ * @details    This function is called to accept a mailbox. 
+ * @note 
+ *******************************************************************************
+ */
+void* CoAcceptMail(OS_EventID id,StatusType* perr)
+{
+    P_ECB pecb;
+    void* pmail;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	                
+    {
+        *perr = E_INVALID_ID;             /* Invalid 'id'                     */
+        return Co_NULL;
+    }
+#endif
+    pecb = &EventTbl[id];
+    
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_MBOX)/* Invalid event control block type */
+    {
+        *perr = E_INVALID_ID;	
+        return Co_NULL;
+    }
+#endif
+	OsSchedLock();
+    if(pecb->eventCounter == 1)             /* If there is already a message  */
+    {
+        *perr = E_OK;
+        pmail = pecb->eventPtr;             /* Get the message                */
+        pecb->eventPtr     = Co_NULL;          /* Clear the mailbox              */
+        pecb->eventCounter = 0;
+		OsSchedUnlock();
+        return pmail;                       /* Return the message received    */		
+    }
+    else                                    /* If the mailbox is empty        */
+    {	
+		OsSchedUnlock();
+        *perr = E_MBOX_EMPTY;               /* Mailbox is empty,return Co_NULL   */
+        return Co_NULL;
+    }
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Wait for a mailbox	 
+ * @param[in]  id       Event ID.	 
+ * @param[in]  timeout  The longest time for writting mail.	    
+ * @param[out] perr     A pointer to error code.	  
+ * @retval     Co_NULL
+ * @retval     A pointer to mailbox accept.
+ *
+ * @par Description
+ * @details    This function is called to wait a mailbox.	 
+ * @note 
+ *******************************************************************************
+ */
+void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr)
+{
+    P_ECB pecb;
+    void* pmail;
+    P_OSTCB  curTCB;
+     
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        *perr = E_CALL;
+        return Co_NULL;
+    }
+    
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)              
+    {
+        *perr = E_INVALID_ID;           /* Invalid 'id',retrun error          */
+        return Co_NULL;
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_MBOX)
+    {
+        *perr = E_INVALID_ID;       /* Invalid event type,not EVENT_TYPE_MBOX */
+        return Co_NULL;
+    }
+#endif
+
+    if(OSSchedLock != 0)                /* Judge schedule is locked or not?   */
+    {	
+        *perr = E_OS_IN_LOCK;           /* Schedule is locked                 */								 
+        return Co_NULL;                    /* return Co_NULL                        */
+    }
+    OsSchedLock();
+    if( pecb->eventCounter == 1)        /* If there is already a message      */
+    {
+        *perr = E_OK;
+        pmail = pecb->eventPtr;         /* Get the message                    */
+        pecb->eventPtr     = Co_NULL;      /* Clear the mailbox                  */
+        pecb->eventCounter = 0;
+        OsSchedUnlock();
+        return pmail;                   /* Return the message received        */
+    }
+    else                       /* If message is not available, task will pend */ 
+    {
+    	OsSchedUnlock();
+        curTCB = TCBRunning;
+        if(timeout == 0)                /* If time-out is not configured      */
+        {
+            EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */
+            *perr = E_OK;
+            
+            /* Have recived a message or the mailbox have been deleted        */
+            pmail = curTCB->pmail;          
+            curTCB->pmail = Co_NULL;
+            return pmail;               /* Return received message or Co_NULL    */
+        }
+        else                            /* If time-out is configured          */
+        {
+            OsSchedLock();
+            
+            /* Block task until event or timeout occurs                       */
+            EventTaskToWait(pecb,curTCB);   
+            InsertDelayList(curTCB,timeout);
+            OsSchedUnlock();
+            if( curTCB->pmail == Co_NULL)  /* Time-out occurred                  */
+            {
+                *perr = E_TIMEOUT;
+                return Co_NULL;
+            }
+            else    /* Have recived a message or the mailbox have been deleted*/
+            {
+                *perr = E_OK;
+                pmail = curTCB->pmail;
+                curTCB->pmail = Co_NULL;
+                return pmail;           /* Return received message or Co_NULL    */
+            }			
+        }	
+    }
+}
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Post a mailbox	  
+ * @param[in]  id      Event ID.
+ * @param[in]  pmail   Pointer to mail that want to send.		 
+ * @param[out] None   
+ * @retval     E_INVALID_ID	
+ * @retval     E_OK		 
+ *
+ * @par Description
+ * @details    This function is called to post a mail. 
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoPostMail(OS_EventID id,void* pmail)
+{
+    P_ECB pecb;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	                
+    {
+        return E_INVALID_ID;            /* Invalid id,return error            */
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/
+    {
+        return E_INVALID_ID;              /* Event is not mailbox,return error*/
+    }
+#endif
+
+    if(pecb->eventCounter == 0)   /* If mailbox doesn't already have a message*/	
+    {
+        OsSchedLock();
+        pecb->eventPtr     = pmail;       /* Place message in mailbox         */
+        pecb->eventCounter = 1;
+        EventTaskToRdy(pecb);             /* Check waiting list               */
+        OsSchedUnlock();
+        return E_OK;	
+    }
+    else                          /* If there is already a message in mailbox */              
+    {
+        return E_MBOX_FULL;       /* Mailbox is full,and return "E_MBOX_FULL" */
+    }
+}
+
+/**
+ *******************************************************************************
+ * @brief      Post a mailbox in ISR	    
+ * @param[in]  id      Event ID.
+ * @param[in]  pmail   Pointer to mail that want to send.		 
+ * @param[out] None   
+ * @retval     E_INVALID_ID	
+ * @retval     E_OK		 
+ *
+ * @par Description
+ * @details    This function is called to post a mail in ISR. 
+ * @note 
+ *******************************************************************************
+ */
+#if CFG_MAX_SERVICE_REQUEST > 0
+StatusType isr_PostMail(OS_EventID id,void* pmail)
+{
+    if(OSSchedLock > 0)         /* If scheduler is locked,(the caller is ISR) */
+    {
+        /* Insert the request into service request queue                      */
+        if(InsertInSRQ(MBOX_REQ,id,pmail) == Co_FALSE)
+        {
+            return E_SEV_REQ_FULL;        /* If service request queue is full */
+        }			
+        else                              /* Operate successfully             */
+        {
+            return E_OK;
+        }
+    }
+    else
+    {
+        return(CoPostMail(id,pmail));     /* Sends the message to the mailbox */ 
+    }
+}
+#endif
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/mm.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,275 @@
+/**
+ *******************************************************************************
+ * @file       mm.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      memory management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+#if  CFG_MM_EN > 0
+/*---------------------------- Variable Define -------------------------------*/
+MM    MemoryTbl[CFG_MAX_MM] = {{0}};/*!< Table which save memory control block. */
+U32   MemoryIDVessel = 0;         /*!< Memory ID container.                   */
+
+/**
+ *******************************************************************************
+ * @brief      Create a memory partition	 
+ * @param[in]  memBuf       Specify memory partition head address.		 
+ * @param[in]  blockSize    Specify memory block size.  
+ * @param[in]  blockNum     Specify memory block number.
+ * @param[out] None
+ * @retval     E_CREATE_FAIL  Create memory partition fail.
+ * @retval     others         Create memory partition successful.			 
+ *
+ * @par Description
+ * @details    This function is called to create a memory partition.
+ *******************************************************************************
+ */
+OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum)
+{
+    U8        i,j;
+    U8        *memory;
+    P_MemBlk  memBlk;
+    memory = memBuf;
+	
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(memBuf == Co_NULL)
+    {
+        return 	E_CREATE_FAIL;
+    }
+    if(blockSize == 0)
+    {
+        return 	E_CREATE_FAIL;	
+    }
+    if((blockSize&0x3) != 0)
+    {
+        return 	E_CREATE_FAIL;	
+    }
+    if(blockNum<=1)
+    {
+        return 	E_CREATE_FAIL;
+    }
+#endif
+
+    OsSchedLock();                      /* Lock schedule                      */
+    for(i = 0; i < CFG_MAX_MM; i++)
+    {
+        if((MemoryIDVessel & (1 << i)) == 0)  /* Is free memory ID?           */
+        {
+            MemoryIDVessel |= (1<<i);   /* Yes,assign ID to this memory block */
+            OsSchedUnlock();            /* Unlock schedule                    */
+            MemoryTbl[i].memAddr   = memory;/* Initialize memory control block*/
+            MemoryTbl[i].freeBlock = memory;  	
+            MemoryTbl[i].blockSize = blockSize;
+            MemoryTbl[i].blockNum  = blockNum;
+            memBlk  = (P_MemBlk)memory;     /* Bulid list in this memory block*/ 
+            for(j=0;j<blockNum-1;j++)
+            {
+                memory = memory+blockSize;
+                memBlk->nextBlock = (P_MemBlk)memory;
+                memBlk = memBlk->nextBlock;
+            }
+            memBlk->nextBlock = Co_NULL;
+            return i;                   /* Return memory block ID             */
+        }
+    }
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    return E_CREATE_FAIL;               /* Error return                       */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a memory partition	  
+ * @param[in]  mmID     Specify	memory partition that want to delete.	
+ * @param[out] None
+ * @retval     E_INVALID_ID   The memory partition id passed was invalid,delete fail.
+ * @retval     E_OK           Delete successful.			 
+ *
+ * @par Description
+ * @details    This function is called to Delete a memory partition.
+ *******************************************************************************
+ */
+StatusType CoDelMemoryPartition(OS_MMID mmID)
+{
+    P_MM  memCtl;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(mmID >= CFG_MAX_MM)
+    {
+        return E_INVALID_ID;
+    }
+    if( ((1<<mmID)&MemoryIDVessel) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif	
+    OsSchedLock();                      /* Lock schedule                      */
+    memCtl = &MemoryTbl[mmID];          /* Release memory control block       */
+    MemoryIDVessel &= ~(1<<mmID);
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    
+    memCtl->memAddr   = Co_NULL;
+    memCtl->freeBlock = Co_NULL;
+    memCtl->blockSize = 0;
+    memCtl->blockNum  = 0;	
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get free block number in a memory partition	  
+ * @param[in]  mmID    Specify memory partition.	
+ *
+ * @param[out] E_INVALID_ID  Invalid ID was passed and get counter failure.	  
+ * @param[out] E_OK          Get current counter successful.
+ * @retval     fbNum         The number of free block.	
+ *
+ * @par Description
+ * @details    This function is called to get free block number in a memory 
+ *             partition.
+ *******************************************************************************
+ */
+U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr)
+{
+    U32       fbNum;	
+    P_MM      memCtl;
+    P_MemBlk  memBlk;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(mmID >= CFG_MAX_MM)
+    {
+        *perr = E_INVALID_ID;
+        return 0;
+    }
+    if( ((1<<mmID)&MemoryIDVessel) == 0)
+    {
+        *perr = E_INVALID_ID;           /* Invalid memory id,return 0         */
+        return 0;
+    }
+#endif	
+    memCtl = &MemoryTbl[mmID];
+    OsSchedLock();                      /* Lock schedule                      */
+    memBlk = (P_MemBlk)(memCtl->freeBlock);/* Get the free item in memory list*/
+    fbNum  = 0;
+    while(memBlk != Co_NULL)               /* Get counter of free item           */
+    {
+        fbNum++;
+        memBlk = memBlk->nextBlock;     /* Get next free iterm                */
+    }
+    OsSchedUnlock();                    /* Unlock schedul                     */
+    *perr = E_OK;							   
+    return fbNum;                       /* Return the counter of free item    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get a memory buffer from memory partition	    
+ * @param[in]  mmID     Specify	memory partition that want to assign buffer.	
+ * @param[out] None
+ * @retval     Co_NULL     Assign buffer fail.
+ * @retval     others   Assign buffer successful,and return the buffer pointer.	
+ *		 
+ * @par Description
+ * @details    This function is called to Delete a memory partition.
+ *******************************************************************************
+ */
+void* CoGetMemoryBuffer(OS_MMID mmID)
+{
+    P_MM      memCtl;
+    P_MemBlk  memBlk;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(mmID >= CFG_MAX_MM)
+    {
+        return Co_NULL;
+    }
+    if( ((1<<mmID)&MemoryIDVessel)  == 0)
+    {
+        return Co_NULL;
+    }
+#endif
+    memCtl = &MemoryTbl[mmID];	
+    OsSchedLock();                      /* Lock schedule                      */	        
+    if(memCtl->freeBlock == Co_NULL )    /* Is there no free item in memory list */
+    {
+        OsSchedUnlock();                /* Unlock schedule                    */
+        return Co_NULL;                    /* Yes,error return                   */
+    }
+    memBlk = (P_MemBlk)memCtl->freeBlock;       /* Get free memory block      */
+    memCtl->freeBlock = (U8*)memBlk->nextBlock; /* Reset the first free item  */
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    return memBlk;                      /* Return free memory block address   */
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Free a memory buffer to memory partition	 
+ * @param[in]  mmID    Specify	memory partition.
+ * @param[in]  buf     Specify	memory buffer that want to free.	
+ * @param[out] None
+ * @retval     E_INVALID_ID          The memory partition id passed was invalid.
+ * @retval     E_INVALID_PARAMETER   The parameter passed was invalid.	
+ * @retval     E_OK                  Free successful.	 
+ *
+ * @par Description
+ * @details    This function is called to Delete a memory partition.
+ *******************************************************************************
+ */
+StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf)
+{
+    P_MM      memCtl;
+    P_MemBlk  memBlk;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(mmID >= CFG_MAX_MM)
+    {
+        return E_INVALID_ID;
+    }
+    if( ((1<<mmID)&MemoryIDVessel) == 0)
+    {
+        return E_INVALID_ID;
+    }
+    if(buf == Co_NULL)
+    {
+        return E_INVALID_PARAMETER;
+    }
+#endif	
+
+    memCtl = &MemoryTbl[mmID];
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if((U32)buf < (U32)(memCtl->memAddr))
+    {
+        return E_INVALID_PARAMETER;
+    }
+    if((U32)buf > (U32)(memCtl->memAddr + memCtl->blockSize*memCtl->blockNum))
+    {
+        return E_INVALID_PARAMETER;
+    }
+    if(((U32)buf - (U32)(memCtl->memAddr))%(memCtl->blockSize) != 0)
+    {	
+        return E_INVALID_PARAMETER;	
+    }
+#endif
+    memBlk = (P_MemBlk)buf;             /* Reset the first free item          */
+    OsSchedLock();
+    memBlk->nextBlock = (P_MemBlk)memCtl->freeBlock;
+    memCtl->freeBlock = buf;
+    OsSchedUnlock();
+    return E_OK;                        /* Return OK                          */
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/mutex.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,349 @@
+/**
+ *******************************************************************************
+ * @file       mutex.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Mutex management implementation code of CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+/*---------------------------- Variable Define -------------------------------*/
+#if CFG_MUTEX_EN > 0
+
+OS_MutexID MutexFreeID = 0;               /*!< Point to next vliad mutex ID.  */
+MUTEX      MutexTbl[CFG_MAX_MUTEX] = {{0}}; /*!< Mutex struct array             */
+    
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a mutex     
+ * @param[in]  None          
+ * @param[out] None  
+ * @retval     E_CREATE_FAIL  Create mutex fail.
+ * @retval     others         Create mutex successful.         
+ *
+ * @par Description                      
+ * @details    This function is called to create a mutex. 
+ * @note          
+ *******************************************************************************
+ */
+OS_MutexID CoCreateMutex(void)
+{
+    OS_MutexID id;
+    P_MUTEX pMutex;
+    OsSchedLock();
+    
+    /* Assign a free mutex control block */
+    if(MutexFreeID < CFG_MAX_MUTEX )
+    {
+        id  = MutexFreeID++;
+        OsSchedUnlock();
+        pMutex = &MutexTbl[id];
+        pMutex->hipriTaskID  = INVALID_ID;
+        pMutex->originalPrio = 0xff;
+        pMutex->mutexFlag    = MUTEX_FREE;  /* Mutex is free,not was occupied */
+        pMutex->taskID       = INVALID_ID;
+        pMutex->waittingList = 0;
+        return id;                      /* Return mutex ID                    */            
+    }    
+    
+    OsSchedUnlock();     
+    return E_CREATE_FAIL;               /* No free mutex control block        */    
+}
+
+
+
+/**    
+ *******************************************************************************             
+ * @brief      Enter a critical area  
+ * @param[in]  mutexID    Specify mutex.      
+ * @param[out] None   
+ * @retval     E_INVALID_ID  Invalid mutex id.     
+ * @retval     E_CALL        Error call in ISR.
+ * @retval     E_OK          Enter critical area successful.
+ *
+ * @par Description
+ * @details    This function is called when entering a critical area.     
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoEnterMutexSection(OS_MutexID mutexID)
+{
+    P_OSTCB ptcb,pCurTcb;
+    P_MUTEX pMutex;
+
+#if CFG_EVENT_EN >0
+    P_ECB pecb;
+#endif
+
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        return E_CALL;
+    }
+    if(OSSchedLock != 0)                /* Is OS lock?                        */
+    {                                 
+        return E_OS_IN_LOCK;            /* Yes,error return                   */
+    }    
+
+#if CFG_PAR_CHECKOUT_EN >0
+    if(mutexID >= MutexFreeID)          /* Invalid 'mutexID'                  */
+    {
+        return E_INVALID_ID;    
+    }
+#endif
+
+    OsSchedLock();
+    pCurTcb = TCBRunning;
+    pMutex  = &MutexTbl[mutexID];
+    
+    pCurTcb->mutexID = mutexID;
+    if(pMutex->mutexFlag == MUTEX_FREE)       /* If mutex is available        */     
+    {
+        pMutex->originalPrio = pCurTcb->prio; /* Save priority of owning task */   
+        pMutex->taskID       = pCurTcb->taskID;   /* Acquire the resource     */
+        pMutex->hipriTaskID  = pCurTcb->taskID;
+        pMutex->mutexFlag    = MUTEX_OCCUPY;      /* Occupy the mutex resource*/
+    }
+    /* If the mutex resource had been occupied                                */
+    else if(pMutex->mutexFlag == MUTEX_OCCUPY)         
+    {    
+        ptcb = &TCBTbl[pMutex->taskID];
+        if(ptcb->prio > pCurTcb->prio)  /* Need to promote priority of owner? */
+        {
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+            DeleteTaskPri(ptcb->prio);
+            ActiveTaskPri(pCurTcb->prio);
+#endif    
+            ptcb->prio = pCurTcb->prio;        /* Promote prio of owner          */
+            
+            /* Upgarde the highest priority about the mutex                   */
+            pMutex->hipriTaskID    = pCurTcb->taskID;    
+            if(ptcb->state == TASK_READY)   /* If the task is ready to run    */
+            {
+                RemoveFromTCBRdyList(ptcb); /* Remove the task from READY list*/
+                InsertToTCBRdyList(ptcb);   /* Insert the task into READY list*/
+            }
+#if CFG_EVENT_EN >0
+            /* If the task is waiting on a event                              */
+            else if(ptcb->eventID != INVALID_ID) 
+            {
+                pecb = &EventTbl[ptcb->eventID];
+                
+                /* If the event waiting type is preemptive Priority           */
+                if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)    
+                {
+                    /* Remove the task from event waiting list                */
+                    RemoveEventWaittingList(ptcb);
+                    
+                    /* Insert the task into event waiting list                */     
+                    EventTaskToWait(pecb,ptcb);        
+                }    
+            }
+#endif    
+        }
+        
+        pCurTcb->state   = TASK_WAITING;    /* Block current task             */
+        TaskSchedReq     = Co_TRUE;
+        pCurTcb->TCBnext = 0;
+        pCurTcb->TCBprev = 0;
+        
+        ptcb = pMutex->waittingList;
+        if(ptcb == 0)               /* If the event waiting list is empty  */
+        {
+            pMutex->waittingList = pCurTcb; /* Insert the task to head        */
+        }
+        else                        /* If the event waiting list is not empty */
+        {                
+            while(ptcb->TCBnext != 0)    /* Insert the task to tail        */
+            {
+                ptcb = ptcb->TCBnext;        
+            }
+            ptcb->TCBnext    = pCurTcb;
+            pCurTcb->TCBprev = ptcb;
+            pCurTcb->TCBnext = 0;
+        }
+    }
+    OsSchedUnlock();
+    return E_OK;            
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Leave from a critical area     
+ * @param[in]  mutexID     Specify mutex id.     
+ * @param[out] None 
+ * @retval     E_INVALID_ID  Invalid mutex id.
+ * @retval     E_CALL        Error call in ISR.
+ * @retval     E_OK          Exit a critical area successful.
+ *
+ * @par Description         
+ * @details    This function must be called when exiting from a critical area.    
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoLeaveMutexSection(OS_MutexID mutexID)
+{
+    P_OSTCB ptcb;
+    P_MUTEX pMutex;
+    U8      prio;
+    U8      taskID;
+    
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        return E_CALL;
+    }
+
+#if CFG_PAR_CHECKOUT_EN >0
+    if(mutexID >= MutexFreeID)
+    {
+        return E_INVALID_ID;            /* Invalid mutex id, return error     */
+    }
+#endif    
+    OsSchedLock();
+    pMutex = &MutexTbl[mutexID];        /* Obtain point of mutex control block*/   
+    ptcb = &TCBTbl[pMutex->taskID];
+    ptcb->mutexID = INVALID_ID;
+    if(pMutex->waittingList == 0)    /* If the mutex waiting list is empty */
+    {
+        pMutex->mutexFlag = MUTEX_FREE; /* The mutex resource is available    */
+        pMutex->taskID    = INVALID_ID;
+        OsSchedUnlock();
+    }    
+    else              /* If there is at least one task waitting for the mutex */
+    { 
+        taskID = pMutex->taskID;        /* Get task ID of mutex owner         */
+        
+                                /* we havn't promoted current task's priority */
+        if(pMutex->hipriTaskID == taskID)   
+        {
+            ptcb = pMutex->waittingList;/* Point to mutex first waiting task  */        
+            prio = ptcb->prio; 
+            while(ptcb != 0)         /* Find the highest priority task     */
+            {
+                if(ptcb->prio < prio)          
+                {
+                    prio = ptcb->prio;
+                    pMutex->hipriTaskID = ptcb->taskID;
+                }
+                ptcb = ptcb->TCBnext;                    
+            }
+        }
+        else                     /* we have promoted current task's priority  */
+        {
+            prio = TCBTbl[taskID].prio;
+        }
+        
+        /* Reset the task priority */
+        pMutex->taskID = INVALID_ID;    
+        CoSetPriority(taskID,pMutex->originalPrio);
+        
+        /* Find first task in waiting list ready to run  */    
+        ptcb                 = pMutex->waittingList;         
+        pMutex->waittingList = ptcb->TCBnext;    
+        pMutex->originalPrio = ptcb->prio;
+        pMutex->taskID       = ptcb->taskID;
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        if(prio != ptcb->prio)
+        {
+            DeleteTaskPri(ptcb->prio);
+            ActiveTaskPri(prio);            
+        }
+#endif    
+
+        ptcb->prio           = prio;    /* Raise the task's priority          */       
+                           
+        /* Insert the task which acquire the mutex into ready list.           */
+        ptcb->TCBnext = 0;
+        ptcb->TCBprev = 0;
+
+        InsertToTCBRdyList(ptcb);     /* Insert the task into the READY list  */
+        OsSchedUnlock();
+    }
+    return E_OK;            
+}
+
+/**
+ *******************************************************************************
+ * @brief      Remove a task from mutex waiting list       
+ * @param[in]  ptcb   TCB which will remove out.     
+ * @param[out] None      
+ * @retval     None
+ *
+ * @par Description         
+ * @details   This function be called when delete a task.    
+ * @note 
+ *******************************************************************************
+ */
+void RemoveMutexList(P_OSTCB ptcb)
+{
+    U8 prio;
+    OS_TID taskID;
+    P_MUTEX pMutex;
+    pMutex = &MutexTbl[ptcb->mutexID];
+    
+    /* If only one task waiting on mutex                                      */    
+    if((ptcb->TCBnext ==0) && (ptcb->TCBprev == 0))
+    {
+        pMutex->waittingList = 0;     /* Waiting list is empty             */
+    }
+    else if(ptcb->TCBnext == 0)  /* If the task is the last of waiting list*/
+    {
+        /* Remove task from mutex waiting list                                */
+        ptcb->TCBprev->TCBnext = 0;
+        ptcb->TCBprev = 0;
+    }    
+    else if(ptcb->TCBprev ==  0)/* If the task is the first of waiting list*/
+    {
+        /* Remove task from waiting list                                      */
+        ptcb->TCBnext->TCBprev = 0;
+        ptcb->TCBnext = 0;
+    }
+    else                      /* If the task is in the middle of waiting list */
+    {
+        /* Remove task from wait list */
+        ptcb->TCBnext->TCBprev = ptcb->TCBprev;
+        ptcb->TCBprev->TCBnext = ptcb->TCBnext;
+        ptcb->TCBprev          = 0;
+        ptcb->TCBnext          = 0;
+    }
+    
+    ptcb->mutexID = INVALID_ID;
+    
+    /* If the task have highest priority in mutex waiting list                */    
+    if(pMutex->hipriTaskID == ptcb->taskID)                        
+    {
+        ptcb = pMutex->waittingList;
+        prio = pMutex->originalPrio; 
+        pMutex->hipriTaskID = pMutex->taskID;
+        while(ptcb != 0)           /* Find task ID of highest priority task*/
+        {
+            if(ptcb->prio < prio)
+            {
+                prio = ptcb->prio;
+                pMutex->hipriTaskID = ptcb->taskID;
+            }
+            ptcb = ptcb->TCBnext;            
+        }
+        taskID = pMutex->taskID;
+        pMutex->taskID = INVALID_ID;
+        CoSetPriority(taskID,prio);         /* Reset the mutex ower priority  */
+        pMutex->taskID = taskID;
+    }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/queue.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,393 @@
+/**
+ *******************************************************************************
+ * @file       queue.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Queue management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+#if CFG_QUEUE_EN > 0										 
+/*---------------------------- Variable Define -------------------------------*/
+QCB   QueueTbl[CFG_MAX_QUEUE] = {{0}};    /*!< Queue control block table        */
+U32   QueueIDVessel = 0;                /*!< Queue list mask                  */
+
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Create a queue	 
+ * @param[in]  qStart    Pointer to mail pointer buffer.
+ * @param[in]  size      The length of queue.
+ * @param[in]  sortType  Mail queue waiting list sort type.
+ * @param[out] None  
+ * @retval     E_CREATE_FAIL  Create queue fail.
+ * @retval     others         Create queue successful.
+ *
+ * @par Description
+ * @details    This function is called to create a queue. 
+ * @note 
+ *******************************************************************************
+ */			 		   
+OS_EventID CoCreateQueue(void **qStart, U16 size ,U8 sortType)
+{
+    U8    i;  
+    P_ECB pecb;
+
+#if CFG_PAR_CHECKOUT_EN >0	
+    if((qStart == Co_NULL) || (size == 0))
+    {
+        return E_CREATE_FAIL;
+    }
+#endif
+
+    OsSchedLock();
+    for(i = 0; i < CFG_MAX_QUEUE; i++)
+    {
+        /* Assign a free QUEUE control block                                  */
+        if((QueueIDVessel & (1 << i)) == 0)	
+        {
+            QueueIDVessel |= (1<<i);		
+            OsSchedUnlock();
+            
+            QueueTbl[i].qStart   = qStart;  /* Initialize the queue           */
+            QueueTbl[i].id       = i;
+            QueueTbl[i].head     = 0;
+            QueueTbl[i].tail     = 0;
+            QueueTbl[i].qMaxSize = size; 
+            QueueTbl[i].qSize    = 0;
+            
+            /* Get a event control block and initial the event content        */
+            pecb = CreatEvent(EVENT_TYPE_QUEUE,sortType,&QueueTbl[i]);
+            
+            if(pecb == Co_NULL )       /* If there is no free EVENT control block*/
+            {
+                return E_CREATE_FAIL;
+            }
+            return (pecb->id);		
+        }
+    }
+    
+    OsSchedUnlock();
+    return E_CREATE_FAIL;             /* There is no free QUEUE control block */	
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a queue	  
+ * @param[in]  id     Event ID. 	
+ * @param[in]  opt    Delete option. 	 
+ * @param[out] None   
+ * @retval     E_INVALID_ID         Invalid event ID.
+ * @retval     E_INVALID_PARAMETER  Invalid parameter.
+ * @retval     E_TASK_WAITTING      Tasks waitting for the event,delete fail.
+ * @retval     E_OK                 Event deleted successful. 
+ *
+ * @par Description
+ * @details    This function is called to delete a queue. 
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoDelQueue(OS_EventID id,U8 opt)
+{
+    P_ECB   pecb;
+    P_QCB   pqcb;
+    StatusType err;
+#if CFG_PAR_CHECKOUT_EN >0      
+    if(id >= CFG_MAX_EVENT)	                     
+    {
+        return E_INVALID_ID;            /* Invalid id,return error            */
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if( pecb->eventType != EVENT_TYPE_QUEUE)
+    {
+        return E_INVALID_ID;            /* The event is not queue,return error*/	
+    }
+#endif
+    pqcb = (P_QCB)pecb->eventPtr;       /* Point at queue control block       */
+    err  = DeleteEvent(pecb,opt);       /* Delete the event control block     */
+    if(err == E_OK)                   /* If the event block have been deleted */
+    {
+        QueueIDVessel &= ~((U32)(1<<(pqcb->id)));   /* Update free queue list             */
+        pqcb->qStart   = Co_NULL;
+		    pqcb->id       = 0;
+        pqcb->head     = 0;
+        pqcb->tail     = 0;
+        pqcb->qMaxSize = 0;
+        pqcb->qSize    = 0;
+    }
+    return err;	
+}
+
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Accept a mail from queue   
+ * @param[in]  id     Event ID.	 	 
+ * @param[out] perr   A pointer to error code.  
+ * @retval     Co_NULL
+ * @retval     A pointer to mail accepted.
+ *
+ * @par Description
+ * @details    This function is called to accept a mail from queue.
+ * @note 
+ *******************************************************************************
+ */
+void* CoAcceptQueueMail(OS_EventID id,StatusType* perr)
+{
+  P_ECB pecb;
+  P_QCB pqcb;
+  void* pmail;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)             
+    {
+        *perr = E_INVALID_ID;           /* Invalid id,return error            */
+        return Co_NULL;
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_QUEUE)/* Invalid event control block type*/          		
+    {
+        *perr = E_INVALID_ID;
+        return Co_NULL;
+    }
+#endif	
+    pqcb = (P_QCB)pecb->eventPtr;       /* Point at queue control block       */
+	OsSchedLock();
+    if(pqcb->qSize != 0)            /* If there are any messages in the queue */
+    {
+        /* Extract oldest message from the queue */
+        pmail = *(pqcb->qStart + pqcb->head);  
+        pqcb->head++;                   /* Update the queue head              */ 
+        pqcb->qSize--;          /* Update the number of messages in the queue */  
+        if(pqcb->head == pqcb->qMaxSize)
+        {
+            pqcb->head = 0;	
+        }
+		OsSchedUnlock();
+        *perr = E_OK;
+        return pmail;                   /* Return message received            */
+    }
+    else                                /* If there is no message in the queue*/
+    {
+		OsSchedUnlock();
+        *perr = E_QUEUE_EMPTY;                 
+        return Co_NULL;                    /* Return Co_NULL                        */
+    }	
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Pend for a mail	 
+ * @param[in]  id       Event ID.	 
+ * @param[in]  timeout  The longest time for writting mail.	
+ * @param[out] perr     A pointer to error code.   
+ * @retval     Co_NULL
+ * @retval     A pointer to mail accept.	 
+ *
+ * @par Description
+ * @details    This function is called to wait for a mail.		   	
+ * @note 
+ *******************************************************************************
+ */
+void* CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr)
+{
+    P_ECB   pecb;
+    P_QCB   pqcb;
+    P_OSTCB curTCB;
+    void*   pmail;
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        *perr = E_CALL;
+        return Co_NULL;
+    }
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	         
+    {
+        *perr = E_INVALID_ID;           /* Invalid event id,return error      */
+        return Co_NULL;
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_QUEUE) /* The event type is not queue    */
+    {
+        *perr = E_INVALID_ID;
+        return Co_NULL;
+    }
+#endif	
+    if(OSSchedLock != 0)                /* Judge schedule is locked or not?   */
+    {	
+        *perr = E_OS_IN_LOCK;           /* Schedule is locked,return error    */								 
+        return Co_NULL;
+    }	
+    pqcb = (P_QCB)pecb->eventPtr;       /* Point at queue control block       */
+    OsSchedLock();
+    if(pqcb->qSize != 0)            /* If there are any messages in the queue */
+    {
+        /* Extract oldest message from the queue                              */
+        pmail = *(pqcb->qStart + pqcb->head);   
+        pqcb->head++;                   /* Update the queue head              */ 
+        pqcb->qSize--;          /* Update the number of messages in the queue */  
+        if(pqcb->head == pqcb->qMaxSize)/* Check queue head                   */
+        {
+            pqcb->head = 0;	
+        }
+        OsSchedUnlock();
+        *perr = E_OK;
+        return pmail;                   /* Return message received            */
+    }
+    else                                /* If there is no message in the queue*/
+    {
+    	OsSchedUnlock();
+        curTCB = TCBRunning;
+        if(timeout == 0)                /* If time-out is not configured      */
+        {
+            /* Block current task until the event occur                       */
+            EventTaskToWait(pecb,curTCB); 
+            
+            /* Have recived message or the queue have been deleted            */
+            pmail = curTCB->pmail;              
+            curTCB->pmail = Co_NULL;
+            *perr = E_OK;
+            return pmail;               /* Return message received or Co_NULL    */
+        }
+        else                            /* If time-out is configured          */
+        {
+            OsSchedLock(); 
+            
+            /* Block current task until event or timeout occurs               */           
+            EventTaskToWait(pecb,curTCB);       
+            InsertDelayList(curTCB,timeout);
+            OsSchedUnlock();
+            if(curTCB->pmail == Co_NULL)   /* If time-out occurred               */
+            {
+                *perr = E_TIMEOUT;
+                return Co_NULL;
+            }
+            else                        /* If event occured                   */
+            {
+                pmail = curTCB->pmail;
+                curTCB->pmail = Co_NULL;
+                *perr = E_OK;
+                return pmail;           /* Return message received or Co_NULL    */
+            }				
+        }	
+    }
+}
+
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Post a mail to queue	   
+ * @param[in]  id      Event ID.
+ * @param[in]  pmail   Pointer to mail that want to send.	 	 
+ * @param[out] None   
+ * @retval     E_OK
+ * @retval     E_INVALID_ID
+ * @retval     E_QUEUE_FULL		 
+ *
+ * @par Description
+ * @details    This function is called to post a mail to queue.
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoPostQueueMail(OS_EventID id,void* pmail)
+{	
+    P_ECB pecb;
+    P_QCB pqcb;
+#if CFG_PAR_CHECKOUT_EN >0                     
+    if(id >= CFG_MAX_EVENT)	
+    {
+        return E_INVALID_ID;          
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_QUEUE)   
+    {
+        return E_INVALID_ID;            /* The event type isn't queue,return  */	
+    }	
+#endif
+    pqcb = (P_QCB)pecb->eventPtr;	
+    if(pqcb->qSize == pqcb->qMaxSize)   /* If queue is full                   */
+    {
+        return E_QUEUE_FULL;
+    }
+    else                                /* If queue is not full               */
+    {
+        OsSchedLock();
+        *(pqcb->qStart + pqcb->tail) = pmail;   /* Insert message into queue  */
+        pqcb->tail++;                           /* Update queue tail          */
+        pqcb->qSize++;          /* Update the number of messages in the queue */
+        if(pqcb->tail == pqcb->qMaxSize)        /* Check queue tail           */   
+        {
+            pqcb->tail = 0;	
+        }
+        EventTaskToRdy(pecb);           /* Check the event waiting list       */
+        OsSchedUnlock();
+        return E_OK;
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Post a mail to queue in ISR	 
+ * @param[in]  id      Event ID.
+ * @param[in]  pmail   Pointer to mail that want to send.	 	 
+ * @param[out] None   
+ * @retval     E_OK
+ * @retval     E_INVALID_ID
+ * @retval     E_QUEUE_FULL		 
+ *
+ * @par Description
+ * @details    This function is called in ISR to post a mail to queue.
+ * @note 				   
+ *******************************************************************************
+ */
+#if CFG_MAX_SERVICE_REQUEST > 0
+StatusType isr_PostQueueMail(OS_EventID id,void* pmail)
+{
+    if(OSSchedLock > 0)         /* If scheduler is locked,(the caller is ISR) */
+    {
+        /* Insert the request into service request queue                      */
+        if(InsertInSRQ(QUEUE_REQ,id,pmail) == Co_FALSE)
+        {
+            return E_SEV_REQ_FULL;      /* If service request queue is full   */          
+        }			
+        else  /* If the request have been inserted into service request queue */
+        {
+            return E_OK;
+        }
+    }
+    else                                /* The scheduler is unlocked          */
+    {
+        return(CoPostQueueMail(id,pmail));    /* Send the message to the queue*/ 
+    }
+}
+#endif
+							   	 
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/sem.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,322 @@
+/**
+ *******************************************************************************
+ * @file       sem.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Semaphore management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+#if CFG_SEM_EN >0
+
+/**
+ *******************************************************************************
+ * @brief      Create a semaphore	  
+ * @param[in]  initCnt   Semaphore valid counter.
+ * @param[in]  maxCnt    Semaphore max initialize counter.
+ * @param[in]  sortType  Semaphore sort type.		 
+ * @param[out] None
+ * @retval     E_CREATE_FAIL   Create semaphore fail.
+ * @retval     others          Create semaphore successful.
+ *
+ * @par Description
+ * @details    This function is called to create a semaphore. 
+ *******************************************************************************
+ */
+OS_EventID CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType)
+{
+    P_ECB pecb;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(initCnt > maxCnt)    
+    {
+        return E_CREATE_FAIL;           /* Invalid 'initCnt' or 'maxCnt'      */	
+    }
+    
+    if ((sortType != EVENT_SORT_TYPE_FIFO) && (sortType != EVENT_SORT_TYPE_PRIO))
+    {
+        return E_CREATE_FAIL;           /* Illegal sort type,return error     */
+    }
+#endif	
+    
+    /* Create a semaphore type event control block                            */
+    pecb = CreatEvent(EVENT_TYPE_SEM,sortType,Co_NULL);
+    if(pecb == Co_NULL)                    /* If failed to create event block    */
+    {
+        return E_CREATE_FAIL;
+    }
+    pecb->eventCounter        = initCnt;/* Initialize event block             */
+    pecb->initialEventCounter = maxCnt;
+    return (pecb->id);                  /* Return event id                    */
+}
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Delete a semaphore	   
+ * @param[in]  id    Event ID which to be deleted.
+ * @param[in]  opt   Delete option.	 
+ * @arg        == OPT_DEL_ANYWAY    Delete semaphore always   
+ * @arg        == OPT_DEL_NO_PEND	Delete semaphore only when no task pending on.
+ * @param[out] None   
+ * @retval     E_INVALID_ID         Invalid event ID.
+ * @retval     E_INVALID_PARAMETER  Invalid parameter.
+ * @retval     E_TASK_WAITTING      Tasks waitting for the event,delete fail.
+ * @retval     E_OK                 Event deleted successful. 	 
+ *
+ * @par Description
+ * @details    This function is called to delete a semaphore. 
+ *
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoDelSem(OS_EventID id,U8 opt)
+{
+    P_ECB pecb;
+
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	                 
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+    pecb = &EventTbl[id];
+
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_SEM)  
+    {
+        return E_INVALID_ID;             /* The event type is not semaphore   */	
+    }	
+#endif
+
+    return (DeleteEvent(pecb,opt));/* Delete the semaphore event control block*/
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Accept a semaphore without waitting 	  
+ * @param[in]  id      Event ID   	 
+ * @param[out] None  
+ * @retval     E_INVALID_ID    Invalid event ID.
+ * @retval     E_SEM_EMPTY     No semaphore exist.
+ * @retval     E_OK            Get semaphore successful. 	
+ *
+ * @par Description
+ * @details    This function is called accept a semaphore without waitting. 
+ *******************************************************************************
+ */
+StatusType CoAcceptSem(OS_EventID id)
+{
+    P_ECB pecb;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	                 
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+	pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if( pecb->eventType != EVENT_TYPE_SEM)   
+    {
+        return E_INVALID_ID;	
+    }
+#endif
+	OsSchedLock();
+    if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */
+    {	
+		OsSchedUnlock();
+        pecb->eventCounter--;         /* Decrement semaphore only if positive */
+        return E_OK;	
+    }
+    else                                /* Resource is not available          */
+    {	
+		OsSchedUnlock();
+        return E_SEM_EMPTY;
+    }	
+}
+
+ 
+/**
+ *******************************************************************************
+ * @brief       wait for a semaphore	   
+ * @param[in]   id       Event ID.	
+ * @param[in]   timeout  The longest time for writting semaphore.
+ * @para        0        
+ * @para        0x1~0xff 	 
+ * @param[out]  None  
+ * @retval      E_CALL         Error call in ISR.   
+ * @retval      E_INVALID_ID   Invalid event ID.	
+ * @retval      E_TIMEOUT      Semaphore was not received within the specified 
+ *                             'timeout' time.
+ * @retval      E_OK           The call was successful and your task owns the 
+ *                             resource,or the event you are waiting for occurred.	
+ * 
+ * @par Description
+ * @details    This function is called to waits for a semaphore. 
+ * @note       IF this function is called in ISR,nothing to do and return immediately.
+ *******************************************************************************
+ */
+StatusType CoPendSem(OS_EventID id,U32 timeout)
+{
+    P_ECB 	 pecb;
+    P_OSTCB  curTCB;
+    if(OSIntNesting > 0)                /* If the caller is ISR               */
+    {
+        return E_CALL;
+    }
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	            
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+	  pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_SEM)     
+    {
+       return E_INVALID_ID;	
+    }
+#endif
+    if(OSSchedLock != 0)                /* Schdule is locked?                 */
+    {
+        return E_OS_IN_LOCK;            /* Yes,error return                   */
+    }
+    OsSchedLock();
+    if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */       
+    {	
+        pecb->eventCounter--;         /* Decrement semaphore only if positive */
+        OsSchedUnlock();
+        return E_OK;	
+    }
+    else                                /* Resource is not available          */
+    {
+    	OsSchedUnlock();
+        curTCB = TCBRunning;
+        if(timeout == 0)                /* If time-out is not configured      */
+        {
+            EventTaskToWait(pecb,curTCB); /* Block task until event occurs    */
+            curTCB->pmail = Co_NULL;
+            return E_OK;
+        }
+        else                            /* If time-out is configured          */
+        {
+            OsSchedLock();
+            
+            /* Block task until event or timeout occurs                       */
+            EventTaskToWait(pecb,curTCB);
+            InsertDelayList(curTCB,timeout);
+            
+            OsSchedUnlock();
+            if (curTCB->pmail == Co_NULL)  /* If pmail is Co_NULL, time-out occurred*/
+            {
+              return E_TIMEOUT;	
+            }                               
+            else                  /* Event occurred or event have been deleted*/    
+            {
+                curTCB->pmail = Co_NULL;
+                return E_OK;	
+            }				
+        }		
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief       Post a semaphore	 
+ * @param[in]   id   id of event control block associated with the desired semaphore.	 	 
+ * @param[out]  None   
+ * @retval      E_INVALID_ID   Parameter id passed was invalid event ID.
+ * @retval      E_SEM_FULL     Semaphore full. 
+ * @retval      E_OK           Semaphore had post successful.
+ *
+ * @par Description
+ * @details    This function is called to post a semaphore to corresponding event. 
+ *
+ * @note 
+ *******************************************************************************
+ */
+StatusType CoPostSem(OS_EventID id)
+{
+    P_ECB pecb;
+#if CFG_PAR_CHECKOUT_EN >0
+    if(id >= CFG_MAX_EVENT)	                  
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+    pecb = &EventTbl[id];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(pecb->eventType != EVENT_TYPE_SEM) /* Invalid event control block type */
+    {
+        return E_INVALID_ID;	
+    }
+#endif
+
+    /* Make sure semaphore will not overflow */
+    if(pecb->eventCounter == pecb->initialEventCounter) 
+    {
+        return E_SEM_FULL;    /* The counter of Semaphore reach the max number*/
+    }
+    OsSchedLock();
+    pecb->eventCounter++;     /* Increment semaphore count to register event  */
+    EventTaskToRdy(pecb);     /* Check semaphore event waiting list           */
+    OsSchedUnlock();
+    return E_OK;
+		
+}
+
+
+/**
+ *******************************************************************************
+ * @brief       Post a semaphore in ISR	 
+ * @param[in]   id    identifier of event control block associated with the 
+ *                    desired semaphore.	 	 
+ * @param[out]  None  
+ * @retval      E_INVALID_ID        Parameter id passed was invalid event ID.
+ * @retval      E_NO_TASK_WAITTING  There are one more tasks waitting for the event. 
+ * @retval      E_OK                Semaphore had signaled successful.
+ *
+ * @par Description
+ * @details    This function is called in ISR to post a semaphore to corresponding
+ *             event. 
+ * @note 
+ *******************************************************************************
+ */
+#if CFG_MAX_SERVICE_REQUEST > 0
+StatusType isr_PostSem(OS_EventID id)
+{
+    if(OSSchedLock > 0)         /* If scheduler is locked,(the caller is ISR) */      
+    {
+        /* Initiate a post service handling request */
+        if(InsertInSRQ(SEM_REQ,id,Co_NULL) == Co_FALSE)
+        {
+            return E_SEV_REQ_FULL;        /* If service request queue is full */
+        }			
+        else                              /* Operate successfully             */
+        {
+            return E_OK;                        
+        }
+    }
+    else
+    {
+        return(CoPostSem(id));            /* Post semaphore                   */
+    }
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/serviceReq.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,165 @@
+/**
+ *******************************************************************************
+ * @file       serviceReq.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      servive request management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+#if (CFG_TASK_WAITTING_EN > 0) || (CFG_TMR_EN >0)
+
+#if CFG_MAX_SERVICE_REQUEST > 0
+/*---------------------------- Variable Define -------------------------------*/
+SRQ   ServiceReq = {0,0};             /*!< ISR server request queue         */		     
+#endif       
+BOOL  IsrReq   = Co_FALSE;
+#if (CFG_TASK_WAITTING_EN > 0)
+BOOL  TimeReq  = Co_FALSE;                 /*!< Time delay dispose request       */
+#endif
+
+#if CFG_TMR_EN  > 0
+BOOL  TimerReq = Co_FALSE;                 /*!< Timer dispose request            */
+#endif
+
+/**
+ *******************************************************************************
+ * @brief      Insert into service requst queue	 
+ * @param[in]  type     Service request type.	
+ * @param[in]  id       Service request event id,event id/flag id.
+ * @param[in]  arg      Service request argument. 
+ * @param[out] None 
+ * 	 
+ * @retval     Co_FALSE    Successfully insert into service request queue.
+ * @retval     Co_TRUE     Failure to insert into service request queue.
+ *
+ * @par Description		 
+ * @details    This function be called to insert a requst into service request	
+ *             queue.
+ * @note 
+ *******************************************************************************
+ */
+#if (CFG_MAX_SERVICE_REQUEST > 0)
+BOOL InsertInSRQ(U8 type,U8 id,void* arg)
+{
+    P_SQC   pcell;
+	U8 cnt;
+	U8 heed;
+    IRQ_DISABLE_SAVE();
+    if (ServiceReq.cnt >= CFG_MAX_SERVICE_REQUEST)
+    {
+        IRQ_ENABLE_RESTORE ();
+
+        return Co_FALSE;                   /* Error return                       */
+    }
+	cnt = Inc8(&ServiceReq.cnt);
+	heed = ServiceReq.head;
+    IsrReq = Co_TRUE;
+    pcell = &ServiceReq.cell[((cnt+heed)%CFG_MAX_SERVICE_REQUEST)];/*the tail */
+    pcell->type = type;                 /* Save service request type,         */
+    pcell->id   = id;                   /* event id                           */
+    pcell->arg  = arg;                  /* and parameter                      */
+    IRQ_ENABLE_RESTORE ();
+
+    return Co_TRUE;                        /* Return OK                          */
+}
+#endif
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Respond the request in the service request queue.	 
+ * @param[in]  None
+ * @param[out] None 
+ * @retval     None  
+ *
+ * @par Description		 
+ * @details    This function be called to respond the request in the service  
+ *             request queue.
+ * @note 
+ *******************************************************************************
+ */
+void RespondSRQ(void)
+{
+
+#if CFG_MAX_SERVICE_REQUEST > 0
+    SQC cell;
+
+#endif
+
+#if (CFG_TASK_WAITTING_EN > 0)
+    if(TimeReq == Co_TRUE)                 /* Time delay request?                */
+    {
+        TimeDispose();                  /* Yes,call handler                   */
+        TimeReq = Co_FALSE;                /* Reset time delay request Co_FALSE     */
+    }
+#endif
+#if CFG_TMR_EN  > 0
+    if(TimerReq == Co_TRUE)                /* Timer request?                     */
+    {
+        TmrDispose();                   /* Yes,call handler                   */
+        TimerReq = Co_FALSE;               /* Reset timer request Co_FALSE          */
+    }
+#endif
+
+#if CFG_MAX_SERVICE_REQUEST > 0
+
+    while (ServiceReq.cnt != 0)
+    {
+        IRQ_DISABLE_SAVE ();            /* need to protect the following      */
+        cell = ServiceReq.cell[ServiceReq.head];  /* extract one cell         */
+        ServiceReq.head = (ServiceReq.head + 1) % /* move head (pop)          */
+                     CFG_MAX_SERVICE_REQUEST;
+        ServiceReq.cnt--;
+        IRQ_ENABLE_RESTORE ();          /* now use the cell copy              */
+
+        switch(cell.type)               /* Judge service request type         */
+        {
+#if CFG_SEM_EN > 0
+        case SEM_REQ:                   /* Semaphore post request,call handler*/
+            CoPostSem(cell.id);
+            break;
+#endif
+#if CFG_MAILBOX_EN > 0
+        case MBOX_REQ:                  /* Mailbox post request,call handler  */
+            CoPostMail(cell.id, cell.arg);
+            break;
+#endif
+#if CFG_FLAG_EN > 0
+        case FLAG_REQ:                  /* Flag set request,call handler      */
+            CoSetFlag(cell.id);
+            break;
+#endif
+#if CFG_QUEUE_EN > 0
+        case QUEUE_REQ:                 /* Queue post request,call handler    */
+            CoPostQueueMail(cell.id, cell.arg);
+            break;
+#endif
+        default:                        /* Others,break                       */
+            break;
+        }
+    }
+#endif
+    IRQ_DISABLE_SAVE ();                /* need to protect the following      */
+
+    if (ServiceReq.cnt == 0)            /* another item in the queue already? */
+    {
+        IsrReq = Co_FALSE;                 /* queue still empty here             */
+    }
+    IRQ_ENABLE_RESTORE ();              /* now it is done and return          */
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/task.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,1260 @@
+/**
+ *******************************************************************************
+ * @file       task.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      task management implementation code of CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+/*---------------------------- Variable Define -------------------------------*/
+
+/*!< Table use to save TCB pointer.              */
+OSTCB    TCBTbl[CFG_MAX_USER_TASKS+SYS_TASK_NUM] = {{0}};
+
+/*!< The stack of IDLE task.                     */
+OS_STK   idle_stk[CFG_IDLE_STACK_SIZE] = {0};
+
+P_OSTCB  FreeTCB     = 0;  /*!< pointer to free TCB                        */
+P_OSTCB  TCBRdy      = 0;  /*!< Pointer to the READY list.                 */
+P_OSTCB  TCBNext     = 0;  /*!< Poniter to task that next scheduled by OS  */
+P_OSTCB  TCBRunning  = 0;  /*!< Pointer to TCB that current running task.  */
+U64      OSCheckTime = 0;     /*!< The counter of system tick.                */
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+OS_TID   PriNum;
+U8       ActivePri[CFG_MAX_USER_TASKS+SYS_TASK_NUM];
+U8       TaskNumPerPri[CFG_MAX_USER_TASKS+SYS_TASK_NUM];
+OS_TID   RdyTaskPri[CFG_MAX_USER_TASKS+SYS_TASK_NUM] = {0};    
+U32      RdyTaskPriInfo[(CFG_MAX_USER_TASKS+SYS_TASK_NUM+31)/32];
+#endif
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a TCB list.      
+ * @param[in]  None      
+ * @param[out] None    
+ * @retval     None         
+ *
+ * @par Description
+ * @details    This function is called by CoOSInit() to initial the empty list     
+ *             of OS_TCBS,supply a pointer to free TCB.
+ *******************************************************************************
+ */
+void CreateTCBList(void)
+{    
+    U8  i;
+    P_OSTCB ptcb1,ptcb2;
+    
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    PriNum = 0;
+#endif
+
+    ptcb1 = &TCBTbl[0];                    /* Build the free TCB list            */
+    ptcb2 = &TCBTbl[1];  
+    for(i=0;i< (CFG_MAX_USER_TASKS+SYS_TASK_NUM-1);i++ )
+    {
+        ptcb1->taskID    = i;
+        ptcb1->state     = TASK_DORMANT;
+        ptcb1->TCBnext   = ptcb2;
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        RdyTaskPri[i]    = INVALID_ID;
+        ActivePri[i]     = INVALID_ID;
+#endif
+        ptcb1++;
+        ptcb2++;    
+    }
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        ActivePri[i]     = INVALID_ID;
+#endif
+
+    ptcb1->taskID    = i;    
+    ptcb1->TCBnext   = 0;
+    FreeTCB = &TCBTbl[0];         /* Initialize FreeTCB as head item of list  */            
+}
+
+
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+
+/**
+ *******************************************************************************
+ * @brief      Get sequence number for Assign priority      
+ * @param[in]  pri            Assign priority     
+ * @param[out] SequenceNum    priority number 
+ * @retval     Co_TRUE           Assign priority in priority queue.
+ *             Co_FALSE          Assign priority not in priority queue.
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to get sequence number for Assign priority.     
+ *******************************************************************************
+ */
+static BOOL  GetPriSeqNum(U8 pri,OS_TID* SequenceNum)
+{
+    OS_TID  seqNum;
+    OS_TID  num,tmpNum;
+    num = 0;
+    seqNum = PriNum;
+    while(num != seqNum)
+    {
+        tmpNum = num;
+        num = (num+seqNum)/2;
+        if(pri == ActivePri[num])
+        {
+            *SequenceNum = num;
+            return Co_TRUE;
+        }
+        else if (pri < ActivePri[num])
+        {
+            seqNum = num;
+            num = tmpNum;
+        }
+        else
+        {
+            num++;
+        }
+    }
+    *SequenceNum = num;
+    return Co_FALSE;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get the nearest ready priority sequence number for Assign number      
+ * @param[in]  seqNum         Assign sequence number     
+ * @param[out] None
+ * @retval     INVALID_ID     Cannot find higher ready priority.   
+ *             Others         Nearest ready priority sequence number          
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to get the nearest ready priority sequence number.    
+ *******************************************************************************
+ */
+static U8 GetRdyPriSeqNum(U8 seqNum)
+{
+    U32 tmp;
+    U8  i,j,num;
+    S8  cnt;
+    i = seqNum/32;
+    j = seqNum%32;
+
+    do
+    {
+          tmp = RdyTaskPriInfo[i];
+        if(tmp != 0)
+        {
+            num = j/8;
+            do
+            {
+                if((tmp&(0xff<<(num*8))) !=0 )
+                {
+                    if((tmp&(0xf0<<(num*8))) !=0)
+                    {
+                        for(cnt=j; cnt >=(num*8+4); cnt--)    
+                        {
+                            if( (tmp&(1<<cnt)) !=0)
+                            {
+                                return (32*i+cnt);
+                            }    
+                        }            
+                    }
+
+                    if((j&0x4)==4)
+                        j = (j|0x3) -4;
+                    
+                    for(cnt=j; cnt >=num*8; cnt--)    
+                    {
+                        if( (tmp&(1<<cnt)) !=0)
+                        {
+                            return (32*i+cnt);
+                        }    
+                    }
+                }
+                j = num*8 -1;
+            }while((num--)!=0);
+        }
+        j=31;
+    }while((i--)!=0);
+    return INVALID_ID;                                            
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Remap the ready status of priority queue from Assign sequence number 
+ * @param[in]  seqNum         Assign sequence number     
+ * @param[out] None
+ * @retval     None             
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to Remap the ready status for priority queue.    
+ *******************************************************************************
+ */
+static void PrioRemap(OS_TID  seqNum)
+{
+    U8 i,j;
+    U32 tmp;
+    tmp = j = 0;
+    j = seqNum/32;
+    for(i=0;i<seqNum%32;i++)
+    {
+        tmp |= 1<<i;
+    }
+    tmp &= RdyTaskPriInfo[j];
+    
+    for(i=seqNum; i<PriNum; i++)
+    {
+        if((i%32==0)&&(i!=seqNum))
+        {
+            RdyTaskPriInfo[j++] = tmp;
+            tmp = 0;
+        }
+        if(RdyTaskPri[i] != INVALID_ID)
+        {
+            tmp = tmp | (1<<(i%32));
+        }
+    }
+    RdyTaskPriInfo[j++] = tmp;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Get the ready status for assign sequence number 
+ * @param[in]  seqNum      Assign sequence number     
+ * @param[out] None
+ * @retval     Co_TRUE        This priority has ready task
+ *             Co_FALSE       This priority doesn't have ready task
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to get the ready status for assign sequence number.    
+ *******************************************************************************
+ */
+static BOOL GetPrioSeqNumStatus(U8 seqNum)
+{
+    if( (RdyTaskPriInfo[seqNum/32] & (1<<(seqNum%32))) == 0)
+    {
+        return Co_FALSE;
+    }
+    return Co_TRUE;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Set the ready status for assign sequence number 
+ * @param[in]  seqNum      Assign sequence number
+ * @param[in]  isRdy       Ready statues for assign sequence number      
+ * @param[out] None
+ * @retval     None          
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to set the ready status for assign sequence number.    
+ *******************************************************************************
+ */
+static void SetPrioSeqNumStatus(U8 seqNum, BOOL isRdy)
+{
+    U32 tmp;
+    tmp = RdyTaskPriInfo[seqNum/32];
+    tmp    &= ~(1<<(seqNum%32));
+    tmp |= isRdy<<(seqNum%32);
+    RdyTaskPriInfo[seqNum/32] = tmp;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Active priority in queue 
+ * @param[in]  pri       Task priority
+ * @param[in]  None     
+ * @param[out] None
+ * @retval     None          
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to active priority in queue, if this priority had been in activation,
+ *             increate the task num for this priority.    
+ *******************************************************************************
+ */
+void ActiveTaskPri(U8 pri)
+{
+    OS_TID  seqNum,num;
+    if(GetPriSeqNum(pri,&seqNum) == Co_FALSE)
+    {
+        for(num=PriNum;num>seqNum;num--)
+        {
+            ActivePri[num]     = ActivePri[num-1];
+            TaskNumPerPri[num] = TaskNumPerPri[num-1];
+            RdyTaskPri[num]    = RdyTaskPri[num-1];
+        }
+        ActivePri[seqNum]     = pri;
+        TaskNumPerPri[seqNum] = 1;
+        RdyTaskPri[seqNum]    = INVALID_ID;
+        PriNum++;
+        PrioRemap(seqNum);
+    }
+    else
+    {
+         TaskNumPerPri[seqNum]++;
+    }
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete priority in queue 
+ * @param[in]  pri       Task priority
+ * @param[in]  None     
+ * @param[out] None
+ * @retval     None          
+ *                    
+ * @par Description
+ * @details    This function is called in Binary-Scheduling Algorithm 
+ *             to decrease the task num for this priority, if the num goto 0,
+ *             remove the priority for queue.
+ *******************************************************************************
+ */
+void DeleteTaskPri(U8 pri)
+{
+    OS_TID  seqNum,num;
+
+    GetPriSeqNum(pri,&seqNum);
+    TaskNumPerPri[seqNum]--;
+    if(TaskNumPerPri[seqNum]==0)
+    {
+        for(num=seqNum; num<(PriNum-1); num++)
+        {
+            ActivePri[num]     = ActivePri[num+1];
+            TaskNumPerPri[num] = TaskNumPerPri[num+1];
+            RdyTaskPri[num]    = RdyTaskPri[num+1];
+        }
+        PriNum--;
+        PrioRemap(seqNum);
+    }
+}
+
+#endif
+
+
+/**
+ *******************************************************************************
+ * @brief      Insert a task to the ready list       
+ * @param[in]  tcbInsert    A pointer to task will be inserted.
+ * @param[out] None  
+ * @retval     None     
+ *
+ * @par Description
+ * @details   This function is called to insert a task to the READY list. 
+ *******************************************************************************
+ */
+void InsertToTCBRdyList(P_OSTCB tcbInsert)
+{
+    P_OSTCB ptcbNext,ptcb;
+    U8  prio;
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    U8  seqNum;
+    U8  RdyTaskSeqNum;
+#endif
+    
+    prio = tcbInsert->prio;             /* Get PRI of inserted task           */
+    tcbInsert->state     = TASK_READY;  /* Set task as TASK_READY             */
+
+#if CFG_ROBIN_EN >0
+    ptcb = TCBRunning;
+    /* Set schedule time for the same PRI task as TCBRunning.                 */
+    if(prio == ptcb->prio)  /* Is PRI of inserted task equal to running task? */
+    {
+        if(ptcb != tcbInsert) /* Yes,is inserted task equal to running task?  */
+        {
+            if(ptcb != Co_NULL)            /* No,TCBRunning == Co_NULL?             */
+            {                           /* N0,OSCheckTime < OSTickCnt?        */
+                if(OSCheckTime < OSTickCnt)     
+                {                       /* Yes,set OSCheckTime for task robin */
+                    OSCheckTime = OSTickCnt + ptcb->timeSlice;    
+                }            
+            }            
+        }
+    }
+#endif
+
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    GetPriSeqNum(prio,&seqNum);
+    if(GetPrioSeqNumStatus(seqNum) == Co_TRUE)
+    {
+        ptcb = &TCBTbl[RdyTaskPri[seqNum]];
+        RdyTaskPri[seqNum] = tcbInsert->taskID;
+    }
+    else
+    {
+        RdyTaskPri[seqNum] = tcbInsert->taskID;
+        RdyTaskSeqNum = GetRdyPriSeqNum(seqNum);
+        SetPrioSeqNumStatus(seqNum, 1);
+        if(RdyTaskSeqNum == INVALID_ID)
+        {
+            ptcb = TCBRdy;
+            TaskSchedReq = Co_TRUE;
+            if(ptcb == Co_NULL)
+            {
+                TCBRdy   = tcbInsert;    
+            }
+            else
+            {
+                tcbInsert->TCBnext = ptcb;  /* Yes,set tcbInsert as head item of list */
+                ptcb->TCBprev = tcbInsert;
+                TCBRdy         = tcbInsert;
+            }
+            return;
+        }
+        else
+        {
+            ptcb = &TCBTbl[RdyTaskPri[RdyTaskSeqNum]];    
+        }
+    }
+
+    ptcbNext = ptcb->TCBnext;
+    tcbInsert->TCBnext = ptcbNext;    /* Set link for list                  */
+    ptcb->TCBnext      = tcbInsert;
+    tcbInsert->TCBprev = ptcb;
+    if(ptcbNext != Co_NULL)
+    {
+        ptcbNext->TCBprev  = tcbInsert;
+    }
+
+
+#else
+    ptcb = TCBRdy;
+    if (ptcb == Co_NULL)                   /* Is ready list Co_NULL?                */
+    {
+        TaskSchedReq = Co_TRUE;
+        TCBRdy = tcbInsert;         /* Yse,set tcbInsert as head item of list */
+    }
+    else if (prio < ptcb->prio)/* Is PRI of inserted task higher than TCBRdy? */
+    {
+        TaskSchedReq = Co_TRUE;
+        tcbInsert->TCBnext = ptcb;  /* Yes,set tcbInsert as head item of list */
+        ptcb->TCBprev  = tcbInsert;
+        TCBRdy         = tcbInsert;
+    }
+    else                                /* No,find correct place              */
+    {                                    
+        ptcbNext = ptcb->TCBnext;       /* Get next item                      */
+        while(ptcbNext != Co_NULL)         /* Is last item in ready list?        */
+        {                               /* No,find correct place              */
+            if(prio < ptcbNext->prio)   /* Is correct place?                  */
+                break;                  /* Yes,break circulation              */
+            ptcb     = ptcbNext;        /* Save current item                  */
+            ptcbNext = ptcbNext->TCBnext; /* Get next item                    */
+        }
+        tcbInsert->TCBnext = ptcbNext;  /* Set link for list                  */
+        ptcb->TCBnext      = tcbInsert;
+        tcbInsert->TCBprev = ptcb;
+        if(ptcbNext != Co_NULL)
+        {
+            ptcbNext->TCBprev  = tcbInsert;
+        }        
+    }
+#endif
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Remove a task from the READY list       
+ * @param[in]  ptcb     A pointer to task which be removed.     
+ * @param[out] None                  
+ * @retval     None         
+ *
+ * @par Description
+ * @details    This function is called to remove a task from the READY list.
+ *******************************************************************************
+ */
+void RemoveFromTCBRdyList(P_OSTCB ptcb)
+{
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    U8 prio;
+    U8 seqNum;
+    BOOL isChange;
+    isChange = Co_FALSE;
+    prio = ptcb->prio;
+    GetPriSeqNum(prio,&seqNum);
+#endif
+
+    /* Is there only one item in READY list?                                  */
+    if((ptcb->TCBnext == Co_NULL) && (ptcb->TCBprev == Co_NULL) )
+    {
+        TCBRdy = 0;                  /* Yes,set READY list as Co_NULL         */
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        isChange = Co_TRUE;
+#endif
+    }
+    else if(ptcb->TCBprev == 0)      /* Is the first item in READY list?   */
+    {   
+        /* Yes,remove task from the list,and reset the head of READY list     */
+        TCBRdy = ptcb->TCBnext;            
+        ptcb->TCBnext   = 0;
+        TCBRdy->TCBprev = 0;
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        if(TCBRdy->prio != prio)
+            isChange = Co_TRUE;
+        
+#endif
+    }
+    else if( ptcb->TCBnext == 0)     /* Is the last item in READY list?    */
+    {                                   /* Yes,remove task from list          */
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        if(ptcb->TCBprev->prio != prio)
+            isChange = Co_TRUE;
+        else 
+            RdyTaskPri[seqNum] = ptcb->TCBprev->taskID;
+#endif
+        ptcb->TCBprev->TCBnext = 0;
+        ptcb->TCBprev          = 0;
+    }
+    else                                /* No, remove task from list          */
+    {    
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        if((ptcb->TCBprev->prio != prio) && (ptcb->TCBnext->prio != prio))
+            isChange = Co_TRUE;
+        else if((ptcb->TCBprev->prio == prio) && (ptcb->TCBnext->prio != prio))
+            RdyTaskPri[seqNum] = ptcb->TCBprev->taskID;
+#endif                                
+        ptcb->TCBprev->TCBnext = ptcb->TCBnext;
+        ptcb->TCBnext->TCBprev = ptcb->TCBprev;
+        ptcb->TCBnext = 0;
+        ptcb->TCBprev = 0;
+    }
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        if(isChange == Co_TRUE)
+        {
+            RdyTaskPri[seqNum] = INVALID_ID;
+            SetPrioSeqNumStatus(seqNum, 0);
+        }
+#endif
+}
+
+
+#if CFG_MUTEX_EN > 0
+#define CFG_PRIORITY_SET_EN       (1)
+#endif
+#if CFG_PRIORITY_SET_EN >0
+/**
+ *******************************************************************************
+ * @brief      Change task priority       
+ * @param[in]  taskID     Specify task id.
+ * @param[in]  priority   New priority.     
+ * @param[out] None           
+ * @retval     E_OK              Change priority successful.
+ * @retval     E_INVALID_ID      Invalid id,change priority fail.
+ * @retval     E_PROTECTED_TASK  Can't change idle task priority.         
+ *
+ * @par Description
+ * @details    This function is called to change priority for a specify task.     
+ *******************************************************************************
+ */
+StatusType CoSetPriority(OS_TID taskID,U8 priority)
+{            
+    P_OSTCB ptcb;
+#if CFG_MUTEX_EN >0
+    U8 prio;
+    P_MUTEX    pMutex;
+#endif
+#if CFG_EVENT_EN >0
+    P_ECB pecb;
+#endif
+
+    if(taskID == 0)                     /* Is idle task?                      */
+    {                                             
+        return E_PROTECTED_TASK;        /* Yes,error return                   */
+    }   
+    
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    ptcb = &TCBTbl[taskID];             /* Get TCB of task ID                 */
+#if CFG_PAR_CHECKOUT_EN >0    
+    if(ptcb->state == TASK_DORMANT)
+    {
+        return E_INVALID_ID;
+    }
+    if(priority > CFG_LOWEST_PRIO)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+    if(ptcb->prio != priority)          /* Is PRI equal to original PRI?      */
+    {                                   /* No                                 */
+#if CFG_MUTEX_EN >0
+        if(ptcb->mutexID != INVALID_ID)
+        {
+            pMutex = &MutexTbl[ptcb->mutexID];
+            if(pMutex->taskID == ptcb->taskID)  /* Task hold mutex?               */
+            {
+                 pMutex->originalPrio= priority;/* Yes,change original PRI in mutex*/
+                 if(ptcb->prio < priority)     /* Is task priority higher than set?*/
+                 {
+                     return E_OK;                /* Yes,do nothing,return OK       */
+                 }
+            }        
+         }
+
+#endif    
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+        DeleteTaskPri(ptcb->prio);
+        ActiveTaskPri(priority);    
+#endif    
+
+        ptcb->prio = priority;              /* Change task PRI                */
+        if(ptcb->state == TASK_READY)       /* Is task in READY list?         */
+        {
+            OsSchedLock();                  /* Yes,reorder task in READY list */
+            RemoveFromTCBRdyList(ptcb);
+            InsertToTCBRdyList(ptcb);    
+            OsSchedUnlock();
+        }
+        else if(ptcb->state == TASK_RUNNING)/* Is task running?               */
+        {
+            if(ptcb->prio > TCBRdy->prio)   /* Yes,Is PRI higher than TCBRdy? */
+            {
+                OsSchedLock();              /* Yes,reorder task in READY list */
+                TaskSchedReq = Co_TRUE;
+                OsSchedUnlock();
+            }
+        }
+        else
+        {                                   /* No,task in WAITING list        */
+#if CFG_MUTEX_EN >0
+            if(ptcb->mutexID != INVALID_ID) /* Is task in mutex WAITING list? */
+            {
+                /* Yes,reset the highest PRI in the list */
+                OsSchedLock(); 
+                pMutex = &MutexTbl[ptcb->mutexID];
+                ptcb = pMutex->waittingList;  
+                prio = pMutex->originalPrio; 
+                pMutex->hipriTaskID = pMutex->taskID;
+                while(ptcb != Co_NULL)
+                {
+                    if(ptcb->prio < prio)
+                    {
+                        prio = ptcb->prio;
+                        pMutex->hipriTaskID = ptcb->taskID;
+                    }
+                    ptcb = ptcb->TCBnext;            
+                }
+                OsSchedUnlock();
+                if(pMutex->originalPrio != prio)
+                {
+                    CoSetPriority(pMutex->taskID,prio);    
+                }    
+            }
+#endif
+
+#if CFG_EVENT_EN >0
+            ptcb = &TCBTbl[taskID];
+            if(ptcb->eventID != INVALID_ID) /* Is task in event WAITING list? */
+            {                                    
+                pecb = &EventTbl[ptcb->eventID];
+                
+                /* Yes,is event sort type as preemptive PRI?                  */
+                if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
+                {      
+                    /* Yes,reorder task in the list                           */
+                    RemoveEventWaittingList(ptcb);
+                    EventTaskToWait(pecb,ptcb);
+                }    
+            }
+#endif
+        }
+    }
+    return E_OK;
+}
+#endif
+
+/**
+ *******************************************************************************
+ * @brief      Schedule function      
+ * @param[in]  None      
+ * @param[out] None       
+ * @retval     None     
+ *
+ * @par Description
+ * @details    This function is called by every where need to switch context,
+ *             It is schedule function of OS kernel.
+ *******************************************************************************
+ */
+void Schedule(void)
+{
+    U8  RunPrio,RdyPrio;
+    P_OSTCB pRdyTcb,pCurTcb;
+   
+    
+    pCurTcb = TCBRunning;    
+    pRdyTcb = TCBRdy;
+
+    if((pRdyTcb==Co_NULL) || (pCurTcb != TCBNext) || (OSSchedLock >1) || (OSIntNesting >0))
+    {
+        return;
+    }
+    
+    TaskSchedReq = Co_FALSE;
+    RunPrio = pCurTcb->prio;
+    RdyPrio = pRdyTcb->prio;
+
+    /* Is Running task status was changed? */
+    if(pCurTcb->state != TASK_RUNNING)    
+    {
+        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
+        pRdyTcb->state = TASK_RUNNING;
+        RemoveFromTCBRdyList(pRdyTcb);
+    }
+
+    else if(RdyPrio < RunPrio )     /* Is higher PRI task coming in?          */
+    {
+        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
+        InsertToTCBRdyList(pCurTcb);
+        RemoveFromTCBRdyList(pRdyTcb);
+        pRdyTcb->state = TASK_RUNNING;
+    }
+    
+#if CFG_ROBIN_EN >0                 /* Is time for robinning                  */                            
+    else if((RunPrio == RdyPrio) && (OSCheckTime == OSTickCnt))
+    {
+        TCBNext        = pRdyTcb;   /* Yes,set TCBNext and reorder READY list */
+        InsertToTCBRdyList(pCurTcb);
+        RemoveFromTCBRdyList(pRdyTcb);
+        pRdyTcb->state = TASK_RUNNING;
+    }
+#endif
+    else
+    {                                    
+        return;    
+    }
+    
+#if CFG_ROBIN_EN >0
+    if(TCBNext->prio == TCBRdy->prio)  /* Reset OSCheckTime for task robinnig */
+        OSCheckTime = OSTickCnt + TCBNext->timeSlice;
+#endif
+    
+  
+#if CFG_STK_CHECKOUT_EN > 0                       /* Is stack overflow?       */
+    if((pCurTcb->stkPtr < pCurTcb->stack)||(*(U32*)(pCurTcb->stack) != MAGIC_WORD))       
+    {                                    
+        CoStkOverflowHook(pCurTcb->taskID);       /* Yes,call handler         */        
+    }   
+#endif
+     
+    SwitchContext();                              /* Call task context switch */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Assign a TCB to task being created                         
+ * @param[in]  None     
+ * @param[out] None     
+ *      
+ * @retval     XXXX                             
+ *
+ * @par Description
+ * @details    This function is called to assign a task control block for task 
+ *              being created.
+ *******************************************************************************
+ */
+static P_OSTCB AssignTCB(void)
+{
+    P_OSTCB    ptcb;
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    if(FreeTCB == 0)                 /* Is there no free TCB               */
+    {
+        OsSchedUnlock();                /* Yes,unlock schedule                */
+        return 0;                    /* Error return                       */
+    }    
+    ptcb    = FreeTCB;          /* Yes,assgin free TCB for this task  */    
+    /* Set next item as the head of free TCB list                     */
+    FreeTCB = FreeTCB->TCBnext; 
+    OsSchedUnlock();
+    return ptcb;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a task       
+ * @param[in]  task       Task code entry.
+ * @param[in]  argv       The parameter passed to task.
+ * @param[in]  parameter  Task priority + stack size + time slice + isWaitting.
+ * @param[in]  stk        Pointer to stack top of task.
+ * @param[out] None   
+ * @retval     E_CREATE_FAIL    Fail to create a task .
+ * @retval     others           Valid task id.                 
+ *
+ * @par Description
+ * @details    This function is called by application to create a task,return a id 
+ *             to mark this task.
+ *******************************************************************************
+ */
+OS_TID CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk)
+{
+    OS_STK* stkTopPtr;
+    P_OSTCB ptcb;
+    U8      prio;
+#if CFG_ROBIN_EN >0    
+    U16     timeSlice;
+#endif
+   
+#if CFG_STK_CHECKOUT_EN >0              /* Check validity of parameter        */
+    U16 sktSz;
+    sktSz = (parameter&0xfff00)>>8;    
+#endif
+    prio = parameter&0xff;
+
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(task == 0)
+    {
+        return E_CREATE_FAIL;
+    }
+    if(stk == 0)
+    {
+        return E_CREATE_FAIL;
+    }
+    if(prio > CFG_LOWEST_PRIO)
+    {
+        return E_CREATE_FAIL;        
+    }
+#if CFG_STK_CHECKOUT_EN >0
+    if(sktSz < 20)
+    {
+        return E_CREATE_FAIL;        
+    }
+#endif      // CFG_STK_CHECKOUT_EN
+#endif      // CFG_PAR_CHECKOUT_EN
+
+#if CFG_TASK_SCHEDULE_EN == 0
+    if(TCBRunning != 0)
+         return E_CREATE_FAIL;    
+#endif   
+
+    stkTopPtr = InitTaskContext(task,argv,stk);   /* Initialize task context. */
+    
+    ptcb = AssignTCB();                 /* Get free TCB to use                */
+    
+    if(ptcb == 0)                    /* Is free TCB equal to Co_NULL?         */
+    {
+        return E_CREATE_FAIL;           /* Yes,error return                   */
+    }
+    
+    ptcb->stkPtr = stkTopPtr;           /* Initialize TCB as user set         */
+    ptcb->prio   = prio;
+#if CFG_STK_CHECKOUT_EN >0
+    ptcb->stack = stk+1 - sktSz; /* Set bottom stack for stack overflow check */
+    *(U32*)(ptcb->stack) = MAGIC_WORD;
+#endif    
+
+#if CFG_TASK_WAITTING_EN >0
+    ptcb->delayTick    = INVALID_VALUE;    
+#endif         
+
+#if CFG_TASK_SCHEDULE_EN == 0
+    ptcb->taskFuc = task;
+    ptcb->taskStk = stk;
+#endif     
+    ptcb->TCBnext = 0;               /* Initialize TCB link in READY list  */
+    ptcb->TCBprev = 0;
+
+#if CFG_ROBIN_EN >0                        /* Set task time slice for task robin */
+    timeSlice = (parameter&0x7fff0000)>>20; 
+    if(timeSlice == 0)
+    {
+        timeSlice = CFG_TIME_SLICE;
+    }
+    ptcb->timeSlice = timeSlice;
+#endif
+
+#if CFG_FLAG_EN > 0
+    ptcb->pnode = 0;                 /* Initialize task as no flag waiting */
+#endif
+
+#if CFG_EVENT_EN > 0
+    ptcb->eventID  = INVALID_ID;          /* Initialize task as no event waiting*/
+    ptcb->pmail    = 0;
+    ptcb->waitNext = 0;
+    ptcb->waitPrev = 0;
+#endif
+
+#if CFG_MUTEX_EN > 0
+    /* Initialize task as no mutex holding or waiting                         */
+    ptcb->mutexID = INVALID_ID; 
+#endif 
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    ActiveTaskPri(prio);    
+#endif    
+
+    if((parameter>>31) == 0)            /* Is task in waitting state?         */
+    {                                    /* No,set it into ready list          */
+        OsSchedLock();                  /* Lock schedule                      */
+        InsertToTCBRdyList(ptcb);       /* Insert into the READY list         */
+        OsSchedUnlock();                /* Unlock schedule                    */
+    }
+    else
+    {                                    /* Yes,Set task status as TASK_WAITING*/
+        ptcb->state   = TASK_WAITING;    
+    }
+    return ptcb->taskID;                /* Return task ID                     */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete Task     
+ * @param[in]  taskID      Task ID 
+ * @param[out] None  
+ * @retval     E_INVALID_ID      Invalid task ID.     
+ * @retval     E_PROTECTED_TASK  Protected task in OS.     
+ * @retval     E_OK              Delete successful.    
+ *
+ * @par Description
+ * @details    This function is called to delete assign task.     
+ *******************************************************************************
+ */
+StatusType CoDelTask(OS_TID taskID)
+{
+    P_OSTCB ptcb;
+
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    ptcb = &TCBTbl[taskID];
+#if CFG_PAR_CHECKOUT_EN >0 
+    if(ptcb->state == TASK_DORMANT)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    if(taskID == 0)                     /* Is idle task?                      */
+    {                                             
+        return E_PROTECTED_TASK;        /* Yes,error return                   */
+    }    
+    
+    if(ptcb->state == TASK_RUNNING)     /* Is task running?                   */
+    {
+        if(OSSchedLock != 0)            /* Yes,is OS lock?                    */
+        {
+            return E_OS_IN_LOCK;        /* Yes,error return                   */
+        }    
+    }
+        
+#if CFG_MUTEX_EN >0                     /* Do task hold mutex?                */
+    if(ptcb->mutexID != INVALID_ID)
+    {
+        if(MutexTbl[ptcb->mutexID].taskID == ptcb->taskID)
+        {                               /* Yes,leave the mutex                */
+            CoLeaveMutexSection(ptcb->mutexID);
+        }
+    }
+    
+#endif    
+
+    OsSchedLock();                      /* Lock schedule                      */
+    
+    if(ptcb->state == TASK_READY)       /* Is task in READY list?             */
+    {
+        RemoveFromTCBRdyList(ptcb);     /* Yes,remove task from the READY list*/
+    }
+
+#if CFG_TASK_WAITTING_EN > 0 
+    else if(ptcb->state == TASK_WAITING)/* Is task in the WAITING list?       */
+    {
+        /* Yes,Is task in delay list? */
+        if(ptcb->delayTick != INVALID_VALUE)                     
+        {
+            RemoveDelayList(ptcb);      /* Yes,remove task from READY list    */
+        }
+
+#if CFG_EVENT_EN > 0
+        if(ptcb->eventID != INVALID_ID) /* Is task in event waiting list?     */
+        {        
+            /* Yes,remove task from event waiting list                        */
+            RemoveEventWaittingList(ptcb);    
+        }
+#endif
+
+#if CFG_FLAG_EN > 0
+        if(ptcb->pnode != 0)         /* Is task in flag waiting list?      */
+        {
+            /* Yes,remove task from flag waiting list                         */
+            RemoveLinkNode((P_FLAG_NODE)ptcb->pnode);    
+        }
+#endif
+
+#if CFG_MUTEX_EN >0
+        if(ptcb->mutexID != INVALID_ID) /* Is task in mutex waiting list?     */
+        {
+            RemoveMutexList(ptcb);  /* Yes,remove task from mutex waiting list*/
+        }
+#endif
+      }
+#endif
+    ptcb->state   = TASK_DORMANT;       /* Release TCB                        */
+    TaskSchedReq  = Co_TRUE;
+
+#if CFG_ORDER_LIST_SCHEDULE_EN ==0
+    DeleteTaskPri(ptcb->prio);    
+#endif    
+
+#if CFG_TASK_SCHEDULE_EN >0
+    ptcb->TCBnext = FreeTCB;
+    FreeTCB       = ptcb;
+#endif
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    return E_OK;                        /* return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Exit Task       
+ * @param[in]  None 
+ * @param[out] None  
+ * @retval     None             
+ *
+ * @par Description
+ * @details    This function is called to exit current task.     
+ *******************************************************************************
+ */
+void CoExitTask(void)
+{
+    CoDelTask(TCBRunning->taskID);      /* Call task delete function          */
+}
+
+
+#if CFG_TASK_SCHEDULE_EN ==0
+/**
+ *******************************************************************************
+ * @brief      Activate Task       
+ * @param[in]  taskID      Task ID 
+ * @param[in]  argv        Task argv 
+ * @param[out] None  
+ * @retval     E_INVALID_ID      Invalid task ID.      
+ * @retval     E_OK              Activate task successful.             
+ *
+ * @par Description
+ * @details    This function is called to activate current task.     
+ *******************************************************************************
+ */
+StatusType CoActivateTask(OS_TID taskID,void *argv)
+{
+    P_OSTCB ptcb;
+    OS_STK* stkTopPtr;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    ptcb = &TCBTbl[taskID];
+#if CFG_PAR_CHECKOUT_EN >0
+    if(ptcb->stkPtr == Co_NULL)
+        return E_INVALID_ID;
+#endif
+    if(ptcb->state != TASK_DORMANT)    
+        return E_OK;
+
+
+                                        /* Initialize task context. */
+    stkTopPtr = InitTaskContext(ptcb->taskFuc,argv,ptcb->taskStk);   
+        
+    ptcb->stkPtr = stkTopPtr;           /* Initialize TCB as user set         */
+    OsSchedLock();                      /* Lock schedule                      */
+    InsertToTCBRdyList(ptcb);           /* Insert into the READY list         */
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    return E_OK;
+}
+#endif
+
+
+/**
+ *******************************************************************************
+ * @brief      Get current task id      
+ * @param[in]  None
+ * @param[out] None
+ * @retval     ID of the current task.             
+ *
+ * @par Description
+ * @details    This function is called to get current task id.     
+ *******************************************************************************
+ */
+OS_TID CoGetCurTaskID(void)
+{
+    return (TCBRunning->taskID);        /* Return running task ID             */
+}
+
+#if CFG_TASK_SUSPEND_EN >0
+/**
+ *******************************************************************************
+ * @brief      Suspend Task      
+ * @param[in]  taskID    ID of task that want to suspend.
+ * @param[out] None  
+ * @retval     E_OK                  Task suspend successful. 
+ * @retval     E_INVALID_ID          Invalid event ID. 
+ * @retval     E_PROTECTED_TASK      Can't suspend idle task. 
+ * @retval     E_ALREADY_IN_WAITING  Task now in waiting state.
+      
+ *
+ * @par Description
+ * @details    This function is called to exit current task.     
+ *******************************************************************************
+ */
+StatusType CoSuspendTask(OS_TID taskID)
+{
+    P_OSTCB ptcb;
+
+    if(taskID == 0)                     /* Is idle task?                      */
+    {                                             
+        return E_PROTECTED_TASK;        /* Yes,error return                   */
+    }   
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    ptcb = &TCBTbl[taskID];
+#if CFG_PAR_CHECKOUT_EN >0  
+    if(ptcb->state == TASK_DORMANT)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    if(OSSchedLock != 0)
+    {
+        return E_OS_IN_LOCK;
+    }
+    if(ptcb->state == TASK_WAITING)     /* Is task in WAITING list?           */
+    {
+        return E_ALREADY_IN_WAITING;    /* Yes,error return                   */
+    }
+    
+    OsSchedLock();    
+    if(ptcb != TCBRunning)              /* Is runing task?                    */
+    {
+        RemoveFromTCBRdyList(ptcb);     /* No,Remove task from READY list     */
+    }
+    else
+    {
+        TaskSchedReq = Co_TRUE;
+    }
+
+    ptcb->state = TASK_WAITING;            /* Set task status as TASK_WAITING    */
+    OsSchedUnlock();                    /* Call task schedule                 */
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Awake Task     
+ * @param[in]  taskID      ID of task that will been awaked.
+ * @param[out] None  
+ * @retval     E_OK                 Task awake successful. 
+ * @retval     E_INVALID_ID         Invalid task ID.
+ * @retval     E_TASK_NOT_WAITING   Task now not in waiting state.
+ * @retval     E_TASK_WAIT_OTHER    Task now waiting other awake event.
+ * @retval     E_PROTECTED_TASK     Idle task mustn't be awaked.      
+ *
+ * @par Description
+ * @details    This function is called to awake current task.     
+ *******************************************************************************
+ */
+StatusType CoAwakeTask(OS_TID taskID)
+{
+    P_OSTCB ptcb;
+    
+     if(taskID == 0)                     /* Is idle task?                      */
+    {                                             
+        return E_PROTECTED_TASK;        /* Yes,error return                   */
+    } 
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    ptcb = &TCBTbl[taskID];
+#if CFG_PAR_CHECKOUT_EN >0  
+    if(ptcb->state == TASK_DORMANT)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    
+    if(ptcb->state != TASK_WAITING)     /* Is task in WAITING list            */
+    {
+        return E_TASK_NOT_WAITING;      /* No,error return                    */
+    }    
+
+#if CFG_TASK_WAITTING_EN > 0
+    if(ptcb->delayTick != INVALID_VALUE)/* Is task in READY list              */
+    {
+        return E_TASK_WAIT_OTHER;       /* Yes,error return                   */
+    }
+
+#if CFG_FLAG_EN > 0
+    if(ptcb->pnode != Co_NULL)             /* Is task in flag waiting list       */
+    {
+        return E_TASK_WAIT_OTHER;       /* Yes,error return                   */
+    }
+#endif
+
+#if CFG_EVENT_EN>0
+    if(ptcb->eventID != INVALID_ID)     /* Is task in event waiting list      */
+    {
+        return E_TASK_WAIT_OTHER;       /* Yes,error return                   */
+    }
+#endif    
+
+#if CFG_MUTEX_EN > 0
+    if(ptcb->mutexID != INVALID_ID)     /* Is task in mutex waiting list      */
+    {
+        return E_TASK_WAIT_OTHER;       /* Yes,error return                   */
+    }
+#endif
+
+#endif      //CFG_TASK_WAITTING_EN
+
+    /* All no,so WAITING state was set by CoSuspendTask()                     */
+    OsSchedLock();                      /* Lock schedule                      */
+    InsertToTCBRdyList(ptcb);           /* Insert the task into the READY list*/
+    OsSchedUnlock();                    /* Unlock schedule                    */
+    return E_OK;                        /* return OK                          */
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/time.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,376 @@
+/**
+ *******************************************************************************
+ * @file       time.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      time management implementation code of CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */  
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+#if CFG_TASK_WAITTING_EN > 0
+
+/*---------------------------- Variable Define -------------------------------*/
+P_OSTCB DlyList   = 0;               /*!< Header pointer to the DELAY list.*/
+
+
+/**
+ *******************************************************************************
+ * @brief      Insert into DELAY list             
+ *   
+ * @param[in]  ptcb    Task that want to insert into DELAY list. 
+ * @param[in]  ticks   Delay system ticks.     
+ * @param[out] None   
+ * @retval     None.          
+ *
+ * @par Description
+ * @details    This function is called to insert task into DELAY list.
+ *******************************************************************************
+ */
+void InsertDelayList(P_OSTCB ptcb,U32 ticks)
+{
+    S32 deltaTicks;
+    P_OSTCB dlyNext;
+    
+    if(ticks == 0)                      /* Is delay tick == 0?                */
+        return;                         /* Yes,do nothing,return              */
+    if(DlyList == 0)                 /* Is no item in DELAY list?          */
+    {
+        ptcb->delayTick = ticks;        /* Yes,set this as first item         */
+        DlyList         = ptcb;
+    }
+    else
+    {    
+        /* No,find correct place ,and insert the task */
+        dlyNext    = DlyList; 
+        deltaTicks = ticks;             /* Get task delay ticks               */
+        
+        /* Find correct place */
+        while(dlyNext != 0)
+        {        
+            /* Get delta ticks with previous item */ 
+            deltaTicks -= dlyNext->delayTick;  
+            if(deltaTicks < 0)          /* Is delta ticks<0?                  */
+            {      
+                /* Yes,get correct place */
+                if(dlyNext->TCBprev != 0)   /* Is head item of DELAY list? */
+                {                               
+                    dlyNext->TCBprev->TCBnext = ptcb;   /* No,insert into     */ 
+                    ptcb->TCBprev             = dlyNext->TCBprev;
+                    ptcb->TCBnext             = dlyNext;
+                    dlyNext->TCBprev          = ptcb;
+                }
+                else                    /* Yes,set task as first item         */
+                {                               
+                    ptcb->TCBnext    = DlyList;
+                    DlyList->TCBprev = ptcb;
+                    DlyList          = ptcb;
+                }
+                ptcb->delayTick           = ptcb->TCBnext->delayTick+deltaTicks;
+                ptcb->TCBnext->delayTick -= ptcb->delayTick; 
+                break;
+            }
+            /* Is last item in DELAY list? */
+            else if((deltaTicks >= 0) && (dlyNext->TCBnext == 0) )
+            {                                   
+                ptcb->TCBprev    = dlyNext; /* Yes,insert into                */
+                dlyNext->TCBnext = ptcb;    
+                ptcb->delayTick  = deltaTicks;
+                break;
+            }
+            dlyNext = dlyNext->TCBnext; /* Get the next item in DELAY list    */
+        }
+    }
+
+    ptcb->state  = TASK_WAITING;        /* Set task status as TASK_WAITING    */
+    TaskSchedReq = Co_TRUE;
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Remove from the DELAY list              
+ * @param[in]  ptcb   Task that want to remove from the DELAY list. 
+ * @param[out] None   
+ * @retval     None          
+ *
+ * @par Description
+ * @details    This function is called to remove task from the DELAY list.
+ *******************************************************************************
+ */
+void RemoveDelayList(P_OSTCB ptcb)
+{
+    
+    /* Is there only one item in the DELAY list?   */
+    if((ptcb->TCBprev == 0) && ( ptcb->TCBnext == 0))
+    {
+        DlyList = 0;                    /* Yes,set DELAY list as Co_NULL         */
+    }
+    else if(ptcb->TCBprev == 0)      /* Is the first item in DELAY list?   */
+    {   
+        /* Yes,remove task from the DELAY list,and reset the list             */
+        DlyList                      = ptcb->TCBnext;
+        ptcb->TCBnext->delayTick += ptcb->delayTick;
+        ptcb->TCBnext->TCBprev    = 0;
+        ptcb->TCBnext             = 0;
+        
+    }
+    else if(ptcb->TCBnext == 0)      /* Is the last item in DELAY list?    */
+    {                                    
+        ptcb->TCBprev->TCBnext = 0;  /* Yes,remove task form DELAY list    */
+        ptcb->TCBprev          = 0;
+    }
+    else                                /* No, remove task from DELAY list    */
+    {                                    
+        ptcb->TCBprev->TCBnext    = ptcb->TCBnext;    
+        ptcb->TCBnext->TCBprev    = ptcb->TCBprev;    
+        ptcb->TCBnext->delayTick += ptcb->delayTick;
+        ptcb->TCBnext               = 0;
+        ptcb->TCBprev             = 0;
+    }
+    ptcb->delayTick = INVALID_VALUE;  /* Set task delay tick value as invalid */        
+}
+
+/**
+ *******************************************************************************
+ * @brief      Get current ticks             
+ * @param[in]  None     
+ * @param[out] None   
+ * @retval     Return current system tick counter.          
+ *
+ * @par Description
+ * @details    This function is called to obtain current system tick counter.
+ *******************************************************************************
+ */
+U64 CoGetOSTime(void)
+{
+    return OSTickCnt;                   /* Get system time(tick)              */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delay current task for specify ticks number      
+ * @param[in]  ticks    Specify system tick number which will delay.             
+ * @param[out] None  
+ * @retval     E_CALL   Error call in ISR.
+ * @retval     E_OK     The current task was insert to DELAY list successful,it
+ *                      will delay specify time.         
+ * @par Description
+ * @details    This function delay specify ticks for current task.
+ *
+ * @note       This function be called in ISR,do nothing and return immediately.
+ *******************************************************************************    
+ */
+StatusType CoTickDelay(U32 ticks)
+{
+    if(OSIntNesting >0)                    /* Is call in ISR?                    */
+    {
+        return E_CALL;                  /* Yes,error return                   */
+    }
+    
+    if(ticks == INVALID_VALUE)          /* Is tick==INVALID_VALUE?            */
+    {
+        return E_INVALID_PARAMETER;     /* Yes,error return                   */
+    }    
+    if(ticks == 0)                      /* Is tick==0?                        */
+    {
+        return E_OK;                    /* Yes,do nothing ,return OK          */
+    }
+    if(OSSchedLock != 0)                /* Is OS lock?                        */
+    {
+        return E_OS_IN_LOCK;            /* Yes,error return                   */
+    }    
+    OsSchedLock();                      /* Lock schedule                      */
+    InsertDelayList(TCBRunning,ticks);    /* Insert task in DELAY list          */
+    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Reset task delay ticks     
+ * @param[in]  ptcb    Task that want to insert into DELAY list.
+ * @param[in]  ticks   Specify system tick number which will delay .             
+ * @param[out] None  
+ * @retval     E_CALL               Error call in ISR.
+ * @retval     E_INVALID_ID         Invalid task id.
+ * @retval     E_NOT_IN_DELAY_LIST  Task not in delay list.
+ * @retval     E_OK                 The current task was inserted to DELAY list 
+ *                                  successful,it will delay for specify time.         
+ * @par Description
+ * @details    This function delay specify ticks for current task.
+ *******************************************************************************     
+ */
+StatusType CoResetTaskDelayTick(OS_TID taskID,U32 ticks)
+{
+    P_OSTCB ptcb;
+    
+
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+    ptcb = &TCBTbl[taskID];
+#if CFG_PAR_CHECKOUT_EN >0 
+    if(ptcb->stkPtr == Co_NULL)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+
+    if(ptcb->delayTick == INVALID_VALUE)  /* Is tick==INVALID_VALUE?          */
+    {
+        return E_NOT_IN_DELAY_LIST;       /* Yes,error return                 */
+    }
+    OsSchedLock();                        /* Lock schedule                    */
+    RemoveDelayList(ptcb);                /* Remove task from the DELAY list  */
+    
+    if(ticks == 0)                        /* Is delay tick==0?                */
+    {
+        InsertToTCBRdyList(ptcb);         /* Insert task into the DELAY list  */
+    }
+    else
+    {                                    
+        InsertDelayList(ptcb,ticks);      /* No,insert task into DELAY list   */
+    }
+    OsSchedUnlock();                /* Unlock schedule,and call task schedule */
+    return E_OK;                          /* Return OK                        */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delay current task for detail time       
+ * @param[in]  hour      Specify the number of hours.
+ * @param[in]  minute    Specify the number of minutes.
+ * @param[in]  sec       Specify the number of seconds.
+ * @param[in]  millsec   Specify the number of millseconds.     
+ * @param[out] None  
+ * @retval     E_CALL               Error call in ISR.
+ * @retval     E_INVALID_PARAMETER  Parameter passed was invalid,delay fail.
+ * @retval     E_OK                 The current task was inserted to DELAY list
+ *                                  successful,it will delay for specify time.                             
+ * @par Description
+ * @details    This function delay specify time for current task.     
+ *
+ * @note       If this function called in ISR,do nothing and return immediately.
+ *******************************************************************************
+ */
+#if CFG_TIME_DELAY_EN >0
+StatusType  CoTimeDelay(U8 hour,U8 minute,U8 sec,U16 millsec)
+{
+    U32    ticks;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(OSIntNesting > 0)
+    {
+        return E_CALL;
+    }
+    if((minute > 59)||(sec > 59)||(millsec > 999))
+        return E_INVALID_PARAMETER;
+#endif
+    if(OSSchedLock != 0)                /* Is OS lock?                        */
+    {
+        return E_OS_IN_LOCK;            /* Yes,error return                   */
+    }    
+    
+    /* Get tick counter from time */
+    ticks = ((hour*3600) + (minute*60) + (sec)) * (CFG_SYSTICK_FREQ)\
+            + (millsec*CFG_SYSTICK_FREQ + 500)/1000;
+    
+    CoTickDelay(ticks);                 /* Call tick delay                    */
+    return E_OK;                        /* Return OK                          */
+}
+#endif
+
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Dispose time delay     
+ * @param[in]  None     
+ * @param[out] None 
+ * @retval     None 
+ *
+ * @par Description
+ * @details    This function is called to dispose time delay of all task.  
+ *******************************************************************************
+ */
+void TimeDispose(void)
+{  
+    P_OSTCB    dlyList;
+    
+    dlyList = DlyList;                  /* Get first item of DELAY list       */
+    while((dlyList != 0) && (dlyList->delayTick == 0) )
+    {    
+    
+#if CFG_EVENT_EN > 0
+        if(dlyList->eventID != INVALID_ID) /* Is task in event waiting list?  */
+        {                                   
+            RemoveEventWaittingList(dlyList); /* Yes,remove task from list    */    
+        }
+#endif
+
+#if CFG_FLAG_EN  > 0
+        if(dlyList->pnode != 0)          /* Is task in flag waiting list?  */
+        {
+            RemoveLinkNode((P_FLAG_NODE)dlyList->pnode); /* Yes,remove task from list      */    
+        }
+#endif
+        dlyList->delayTick = INVALID_VALUE; /* Set delay tick value as invalid*/
+        DlyList = dlyList->TCBnext; /* Get next item as the head of DELAY list*/
+        dlyList->TCBnext   = 0;
+
+        InsertToTCBRdyList(dlyList);        /* Insert task into READY list    */
+        
+        dlyList = DlyList;                /* Get the first item of DELAY list */
+        if(dlyList != 0)                 /* Is DELAY list as Co_NULL?         */
+        {
+            dlyList->TCBprev = 0;        /* No,initialize the first item   */
+        }
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Dispose time delay in ISR      
+ * @param[in]  None     
+ * @param[out] None 
+ * @retval     None 
+ *
+ * @par Description
+ * @details    This function is called in systick interrupt to dispose time delay   
+ *             of all task.
+ *******************************************************************************
+ */
+void isr_TimeDispose(void)
+{
+    if(OSSchedLock > 1)                 /* Is schedule lock?                  */
+    {
+        IsrReq = Co_TRUE;
+        TimeReq = Co_TRUE;                 /* Yes,set time request Co_TRUE          */
+    }
+    else
+    {
+        TimeDispose();                  /* No,call handler                    */
+    }
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/timer.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,447 @@
+/**
+ *******************************************************************************
+ * @file       timer.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      timer management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+/*---------------------------- Variable Define -------------------------------*/
+#if CFG_TMR_EN > 0
+
+TmrCtrl    TmrTbl[CFG_MAX_TMR]= {{0}};/*!< Table which save timer control block.*/
+P_TmrCtrl  TmrList     = Co_NULL;      /*!< The header of the TmrCtrl list.      */
+U32        TmrIDVessel = 0;         /*!< Timer ID container.                  */
+
+
+/**
+ *******************************************************************************
+ * @brief      Insert a timer into the timer list	   
+ * @param[in]  tmrID    Specify timer ID which insertted.		 
+ * @param[out] None  
+ * @retval     E_INVALID_ID  Timer ID passed was invalid,insert fail.
+ * @retval     E_OK          Insert successful.			 
+ *
+ * @par Description
+ * @details    This function is called to insert a timer into the timer list.  
+ *******************************************************************************
+ */
+static void InsertTmrList(OS_TCID tmrID)
+{
+    P_TmrCtrl pTmr;
+    S32 deltaTicks;
+    U32 tmrCnt;
+    tmrCnt = TmrTbl[tmrID].tmrCnt;      /* Get timer time                     */
+    
+    if(tmrCnt == 0)                     /* Is timer time==0?                  */
+    {
+        return;                         /* Do nothing,return                  */
+    }
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    if(TmrList == Co_NULL)                 /* Is no item in timer list?          */
+    {
+        TmrList = &TmrTbl[tmrID];       /* Yes,set this as first item         */
+    }
+    else                  /* No,find correct place ,and insert inserted timer */
+    {								    
+      	pTmr       = TmrList; 
+      	deltaTicks = tmrCnt;            /* Get timer tick                     */
+      	
+      	/* find correct place */
+      	while(pTmr != Co_NULL)
+      	{				    
+            deltaTicks -= pTmr->tmrCnt; /* Get ticks with previous item       */
+            if(deltaTicks < 0)          /* Is delta ticks<0?                  */  
+            {	
+                /* Yes,get correct place */
+                if(pTmr->tmrPrev!= Co_NULL)/* Is head item of timer list?        */
+                {	
+                    /* No,insert into */
+                    pTmr->tmrPrev->tmrNext = &TmrTbl[tmrID]; 
+                    TmrTbl[tmrID].tmrPrev  = pTmr->tmrPrev;
+                    TmrTbl[tmrID].tmrNext  = pTmr;
+                    pTmr->tmrPrev          = &TmrTbl[tmrID];
+                }
+                else                    /* Yes,set task as first item         */ 	
+                {
+                    TmrTbl[tmrID].tmrNext = TmrList;
+                    TmrList->tmrPrev      = &TmrTbl[tmrID];
+                    TmrList               = &TmrTbl[tmrID];
+                }
+                TmrTbl[tmrID].tmrCnt            = TmrTbl[tmrID].tmrNext->tmrCnt+deltaTicks;
+                TmrTbl[tmrID].tmrNext->tmrCnt  -= TmrTbl[tmrID].tmrCnt; 
+                break;	
+            }
+            /* Is last item in list? */									
+            else if((deltaTicks >= 0) && (pTmr->tmrNext == Co_NULL))
+            {	
+                /* Yes,insert into */
+                TmrTbl[tmrID].tmrPrev = pTmr;
+                pTmr->tmrNext         = &TmrTbl[tmrID];	
+                TmrTbl[tmrID].tmrCnt  = deltaTicks;
+                break;	
+            }
+            pTmr = pTmr->tmrNext;       /* Get the next item in timer list    */	
+      	}
+    }
+    OsSchedUnlock();                    /* Unlock schedule                    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Remove a timer from the timer list	  
+ * @param[in]  tmrID    Specify ID for a timer which removed form timer list.	 
+ * @param[out] None 
+ * @retval     None
+ *
+ * @par Description
+ * @details    This function is called to remove a timer from the timer list. 
+ *******************************************************************************
+ */
+static void RemoveTmrList(OS_TCID tmrID)
+{
+    P_TmrCtrl pTmr;
+    
+    pTmr = &TmrTbl[tmrID];
+    
+    OsSchedLock();                      /* Lock schedule                      */
+    
+    /* Is there only one item in timer list?                                  */
+    if((pTmr->tmrPrev == Co_NULL) && (pTmr->tmrNext == Co_NULL))
+    {		
+        TmrList = Co_NULL;                 /* Yes,set timer list as Co_NULL         */
+    }
+    else if(pTmr->tmrPrev == Co_NULL)      /* Is the first item in timer list?   */
+    {   /* Yes,remove timer from list,and reset timer list                    */
+        TmrList  = pTmr->tmrNext;
+        TmrList->tmrPrev = Co_NULL;
+        pTmr->tmrNext->tmrCnt += pTmr->tmrCnt;
+        pTmr->tmrNext    = Co_NULL;
+    }
+    else if(pTmr->tmrNext == Co_NULL)      /* Is the last item in timer list?    */
+    {
+        /* Yes,remove timer form list */
+        pTmr->tmrPrev->tmrNext = Co_NULL;
+        pTmr->tmrPrev = Co_NULL;
+    }
+    else                                /* No, remove timer from list         */
+    {
+        pTmr->tmrPrev->tmrNext  =  pTmr->tmrNext;
+        pTmr->tmrNext->tmrPrev  =  pTmr->tmrPrev;
+        pTmr->tmrNext->tmrCnt  += pTmr->tmrCnt;
+        pTmr->tmrNext = Co_NULL;
+        pTmr->tmrPrev = Co_NULL;
+    }
+    OsSchedUnlock();                    /* Unlock schedule                    */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Create a timer	   
+ * @param[in]  tmrType     Specify timer's type.		 
+ * @param[in]  tmrCnt      Specify timer initial counter value.  
+ * @param[in]  tmrReload   Specify timer reload value.
+ * @param[in]  func        Specify timer callback function entry.
+ * @param[out] None
+ * @retval     E_CREATE_FAIL   Create timer fail.
+ * @retval     others          Create timer successful.			 
+ *
+ * @par Description
+ * @details    This function is called to create a timer.
+ *******************************************************************************
+ */
+OS_TCID CoCreateTmr(U8 tmrType, U32 tmrCnt, U32 tmrReload, vFUNCPtr func)
+{
+    U8 i;
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if((tmrType != TMR_TYPE_ONE_SHOT) && (tmrType != TMR_TYPE_PERIODIC))
+    {
+        return E_CREATE_FAIL;	
+    }
+    if(func == Co_NULL)
+    {
+        return E_CREATE_FAIL;
+    }
+#endif
+    OsSchedLock();                        /* Lock schedule                    */
+    for(i = 0; i < CFG_MAX_TMR; i++)
+    {
+        if((TmrIDVessel & (1 << i)) == 0) /* Is free timer ID?                */
+        {
+            TmrIDVessel |= (1<<i);        /* Yes,assign ID to this timer      */
+            OsSchedUnlock();              /* Unlock schedule                  */
+            TmrTbl[i].tmrID     = i;      /* Initialize timer as user set     */
+            TmrTbl[i].tmrType   = tmrType;	
+            TmrTbl[i].tmrState  = TMR_STATE_STOPPED;
+            TmrTbl[i].tmrCnt    = tmrCnt;
+            TmrTbl[i].tmrReload	= tmrReload;
+            TmrTbl[i].tmrCallBack = func;
+            TmrTbl[i].tmrPrev   = Co_NULL;
+            TmrTbl[i].tmrNext   = Co_NULL;
+            return i;                     /* Return timer ID                  */
+        }
+    }
+    OsSchedUnlock();                      /* Unlock schedule                  */
+    return E_CREATE_FAIL;                 /* Error return                     */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Start counter	 
+ * @param[in]  tmrID    Specify a timer which startted.		 
+ * @param[out] None 
+ * @retval     E_INVALID_ID  The timer id passed was invalid,can't start timer	
+ * @retval     E_OK          Insert a timer to timer list and start it successful. 
+ *
+ * @par Description
+ * @details    This function is called to make a timer start countering. 
+ *******************************************************************************
+ */
+StatusType CoStartTmr(OS_TCID tmrID)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING)   /* Is timer running?    */
+    {
+        return E_OK;                              /* Yes,do nothing,return OK */
+    }
+    
+    /* No,set timer status as TMR_STATE_RUNNING */
+    TmrTbl[tmrID].tmrState = TMR_STATE_RUNNING; 
+    InsertTmrList(tmrID);               /* Insert this timer into timer list  */
+    return E_OK;                        /* Return OK                          */
+}
+
+
+
+/**
+ *******************************************************************************
+ * @brief      Stop countering for a spcify timer	  
+ * @param[in]  tmrID    Specify a timer which stopped.	 
+ * @param[out] None  	 
+ * @retval     E_INVALID_ID  The timer id passed was invalid, stop failure.
+ * @retval     E_OK          Stop a timer countering successful.
+ *
+ * @par Description
+ * @details    This function is called to stop a timer from counting. 
+ *******************************************************************************
+ */
+StatusType CoStopTmr(OS_TCID tmrID)
+{	
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if((TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    
+    
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_STOPPED)/* Does timer stop running?*/
+    {
+        return E_OK;                    /* Yes,do nothing,return OK           */
+    }
+    RemoveTmrList(tmrID);             /* No,remove this timer from timer list */
+    
+    /* Set timer status as TMR_STATE_STOPPED  */
+    TmrTbl[tmrID].tmrState = TMR_STATE_STOPPED;	
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Delete a timer	 
+ * @param[in]  tmrID     Specify a timer which deleted.		 
+ * @param[out] None   
+ * @retval     E_INVALID_ID  The timer id passed was invalid,deleted failure.	
+ * @retval     E_OK          Delete a timer successful.
+ *
+ * @par Description
+ * @details    This function is called to delete a timer which created before.	
+ *******************************************************************************
+ */
+StatusType CoDelTmr(OS_TCID tmrID)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+	
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING) /* Is timer running?      */
+    {
+        RemoveTmrList(tmrID);         /* Yes,remove this timer from timer list*/
+    }
+    TmrIDVessel &=~(1<<tmrID);        /* Release resource that this timer hold*/
+    return E_OK;                      /* Return OK                            */
+}
+
+ 
+/**
+ *******************************************************************************
+ * @brief      Get current counter of specify timer	 
+ * @param[in]  tmrID          Specify timer by ID.		 
+ * @param[out] E_INVALID_ID   Invalid ID was passed and get counter failure.	  
+ * @param[out] E_OK           Get current counter successful.	 
+ * @retval     Current counter of a timer which specify by id.			 
+ *
+ * @par Description
+ * @details    This function is called to obtain current counter of specify timer.
+ *******************************************************************************
+ */
+U32 CoGetCurTmrCnt(OS_TCID tmrID,StatusType* perr)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        *perr = E_INVALID_ID;
+        return 0;
+    }
+    if((TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        *perr = E_INVALID_ID;
+        return 0;
+    }
+#endif
+    *perr = E_OK;
+    return TmrTbl[tmrID].tmrCnt;        /* Return timer counter               */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Setting for a specify timer	  		   	
+ * @param[in]  tmrID       Specify timer by ID.
+ * @param[in]  tmrCnt      Specify timer counter which need to be set.
+ * @param[in]  tmrReload   Specify timer reload value which need to be set.		 
+ * @param[out] None  
+ * @retval     E_INVALID_ID  The ID passed was invalid,set fail.
+ * @retval     E_OK          Set timer counter successful.				 
+ *
+ * @par Description
+ * @details    This function is called to set timer counter and reload value.
+ *******************************************************************************
+ */
+StatusType CoSetTmrCnt(OS_TCID tmrID,U32 tmrCnt,U32 tmrReload)
+{
+#if CFG_PAR_CHECKOUT_EN >0              /* Check validity of parameter        */
+    if(tmrID >= CFG_MAX_TMR)
+    {
+        return E_INVALID_ID;
+    }
+    if( (TmrIDVessel & (1<<tmrID)) == 0)
+    {
+        return E_INVALID_ID;
+    }
+#endif
+    TmrTbl[tmrID].tmrCnt    = tmrCnt; /* Reset timer counter and reload value */
+    TmrTbl[tmrID].tmrReload = tmrReload;
+    								
+    if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING)   /* Is timer running?    */
+    {
+        RemoveTmrList(tmrID);           /* Yes,reorder timer in timer list    */
+        InsertTmrList(tmrID);	
+    }
+    return E_OK;                        /* Return OK                          */
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Timer counter dispose	   
+ * @param[in]  None 	 
+ * @param[out] None	 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to dispose timer counter.
+ *******************************************************************************
+ */
+void TmrDispose(void)
+{
+    P_TmrCtrl	pTmr;
+    
+    pTmr = TmrList;                     /* Get first item of timer list       */
+    while((pTmr != Co_NULL) && (pTmr->tmrCnt == 0) )
+    {	
+        if(pTmr->tmrType == TMR_TYPE_ONE_SHOT)    /* Is a One-shot timer?     */
+        {
+            /* Yes,remove this timer from timer list                          */
+            RemoveTmrList(pTmr->tmrID);
+            
+            /* Set timer status as TMR_STATE_STOPPED                          */
+            pTmr->tmrState = TMR_STATE_STOPPED;
+            (pTmr->tmrCallBack)();          /* Call timer callback function   */
+        }
+        else if(pTmr->tmrType == TMR_TYPE_PERIODIC)   /* Is a periodic timer? */
+        {
+            /* Yes,remove this timer from timer list                          */
+            RemoveTmrList(pTmr->tmrID); 
+            pTmr->tmrCnt = pTmr->tmrReload;   /* Reset timer tick             */
+            InsertTmrList(pTmr->tmrID);       /* Insert timer into timer list */
+            (pTmr->tmrCallBack)();            /* Call timer callback function */
+        }
+        pTmr = TmrList;	                      /* Get first item of timer list */
+    }
+}
+
+
+/**
+ *******************************************************************************
+ * @brief      Timer counter dispose in ISR	   
+ * @param[in]  None 	 
+ * @param[out] None	 
+ * @retval     None	 
+ *
+ * @par Description
+ * @details    This function is called to dispose timer counter.
+ *******************************************************************************
+ */
+void isr_TmrDispose(void)
+{
+    if(OSSchedLock > 1)                 /* Is schedule lock?                  */
+    {
+        IsrReq = Co_TRUE;
+        TimerReq  = Co_TRUE;               /* Yes,set timer request true         */
+    }
+    else
+    {
+        TmrDispose();                   /* No,call handler                    */
+    }
+}	 
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/utility.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,86 @@
+/**
+ *******************************************************************************
+ * @file       utility.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Utility management implementation code of CooCox CoOS kernel.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+#if CFG_UTILITY_EN > 0
+
+
+/**
+ *******************************************************************************
+ * @brief      Convert tick number to time 	  
+ * @param[in]  ticks    Specifies the systerm tick numbers that will be converted.	 
+ * @param[out] hour     Hours which converted. 
+ * @param[out] minute   minutes which converted.
+ * @param[out] sec      seconds which converted.
+ * @param[out] millsec  millseconds which converted.
+ * @retval     None		 
+ *
+ * @par Description
+ * @details    This function is called to convert specify ticks to time format.	  	 	
+ *******************************************************************************				
+ */
+#if CFG_TICK_TO_TIME_EN > 0
+void CoTickToTime(U32 ticks,U8* hour,U8* minute,U8* sec,U16* millsec)
+{
+    U32 totalTime;
+    
+    /* Convert ticks to time*/
+    totalTime = ticks * (1000/CFG_SYSTICK_FREQ);
+    *millsec  = totalTime%1000;
+    totalTime = totalTime/1000;
+    *sec      = totalTime%60;
+    totalTime = totalTime/60;
+    *minute   = totalTime%60;
+    totalTime = totalTime/60;
+    *hour     = totalTime;		
+}
+#endif    /* CFG_TICK_TO_TIME_EN    */
+
+
+/**
+ *******************************************************************************
+ * @brief      Convert time to tick	  
+ * @param[in]  hour     Specifies the number of hours.
+ * @param[in]  minute   Specifies the number of minutes.
+ * @param[in]  sec      Specifies the number of seconds.
+ * @param[in]  millsec  Specifies the number of millseconds.	 
+ * @param[out] ticks    Tick numbers that converted.  
+ * @retval     E_INVALID_PARAMETER   Invalid parameter be passed and convert fail.
+ * @retval     E_OK                  Convert successful.
+ *
+ * @par Description
+ * @details    This function is called to convert specify time to tick number. 		 
+ *******************************************************************************
+ */
+#if CFG_TIME_TO_TICK_EN > 0
+StatusType  CoTimeToTick(U8 hour,U8 minute,U8 sec,U16 millsec,U32* ticks)
+{
+#if CFG_PAR_CHECKOUT_EN >0
+    /* Validate arguments to be within range */
+    if((minute > 59)||(sec > 59)||(millsec > 999))
+        return E_INVALID_PARAMETER;
+#endif
+
+    /* Convert time to ticks */
+    *ticks = ((hour*3600) + (minute*60) + (sec)) * (CFG_SYSTICK_FREQ)\
+              + (millsec*CFG_SYSTICK_FREQ + 500)/1000;
+    return E_OK;
+}
+#endif    /* CFG_TIME_TO_TICK_EN  */
+
+#endif    /* CFG_UTILITY_EN       */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/kernel/utility.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,39 @@
+/**
+ *******************************************************************************
+ * @file       utility.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Utility function header file 
+ * @details    This file including some defines and declares related to utility 
+ *             function.	
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef  _UTILITY_H
+#define  _UTILITY_H
+
+
+/**
+ * @struct  Time struct  utility.h  	
+ * @brief   Time struct	 
+ * @details This struct use to manage time 	 
+ */
+typedef struct SysTime
+{
+    U8   sec;                           /*!< Second                           */
+    U8   min;                           /*!< Minute                           */
+    U8   hour;                          /*!< Hour                             */
+    U8   date;                          /*!< Date                             */
+    U8   month;                         /*!< Month                            */
+    U16  year;                          /*!< Year                             */
+}TIME;
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/portable/Keil/port.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,248 @@
+/**
+ *******************************************************************************
+ * @file       port.c
+ * @version    V1.14    
+ * @date       2011.04.20
+ * @brief      Compiler adapter for CooCox CoOS kernel.    
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2010 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+
+
+/**
+ ******************************************************************************
+ * @brief      Plus a byte integers and Saved into memory cell
+ * @param[in]  data    byte integers.     
+ * @param[out] None  
+ * @retval     Returns Original value.         
+ *
+ * @par Description
+ * @details    This function is called to Plus a byte integers 
+ *             and Saved into memory cell.
+ ******************************************************************************
+ */
+__asm U8  Inc8 (volatile U8 *data)
+{
+    PUSH    {R1}
+    CPSID   I
+    LDRB    R1,[R0]
+    ADDS    R1,#1
+    STRB    R1,[R0]
+    CPSIE   I
+    SUBS    R1,#1
+    MOVS    R0,R1
+    POP     {R1}
+    BX      LR    
+    ALIGN
+}
+
+
+/**
+ ******************************************************************************
+ * @brief      Decrease a byte integers and Saved into memory cell
+ * @param[in]  data    byte integers.     
+ * @param[out] None  
+ * @retval     Returns Original value.         
+ *
+ * @par Description
+ * @details    This function is called to Decrease a byte integers 
+ *             and Saved into memory cell.
+ ******************************************************************************
+ */
+__asm U8 Dec8 (volatile U8 *data)
+{
+    PUSH    {R1}
+    CPSID   I
+    LDRB    R1,[R0]
+    SUBS    R1,#1
+    STRB    R1,[R0]
+    CPSIE   I
+    MOVS    R0,R1
+    POP     {R1}
+    BX      LR
+    ALIGN
+}
+
+/**
+ ******************************************************************************
+ * @brief      ENABLE Interrupt
+ * @param[in]  None     
+ * @param[out] None  
+ * @retval     None         
+ *
+ * @par Description
+ * @details    This function is called to ENABLE Interrupt.
+ ******************************************************************************
+ */
+__asm void IRQ_ENABLE_RESTORE(void)
+{   CPSIE   I
+    BX      LR
+}
+
+/**
+ ******************************************************************************
+ * @brief      Close Interrupt
+ * @param[in]  None     
+ * @param[out] None  
+ * @retval     None         
+ *
+ * @par Description
+ * @details    This function is called to close Interrupt.
+ ******************************************************************************
+ */
+__asm void IRQ_DISABLE_SAVE(void)
+{   CPSID   I
+    BX      LR
+}
+
+/**
+ ******************************************************************************
+ * @brief      Set environment    for Coocox OS running
+ * @param[in]  pstk    stack pointer     
+ * @param[out] None  
+ * @retval     None.         
+ *
+ * @par Description
+ * @details    This function is called to Set environment
+ *              for Coocox OS running.
+ ******************************************************************************
+ */
+__asm  void SetEnvironment(OS_STK *pstk)
+{
+    SUBS    R0,#28
+    MSR     PSP, R0             ; Mov new stack point to PSP
+    BX      LR    
+    ALIGN
+}
+
+
+/**
+ ******************************************************************************
+ * @brief      Do ready work to Switch Context for task change
+ * @param[in]  None     
+ * @param[out] None  
+ * @retval     None.         
+ *
+ * @par Description
+ * @details    This function is called to Do ready work to 
+ *              Switch Context for task change
+ ******************************************************************************
+ */
+__asm void SwitchContext(void)
+{
+    LDR     R0, =0xE000ED04  ; Trigger the PendSV exception (causes context switch)
+    LDR     R1, =0x10000000
+    STR     R1, [R0]
+    BX      LR
+    ALIGN    
+}
+
+
+/**
+ ******************************************************************************
+ * @brief      Switch Context for task change
+ * @param[in]  None     
+ * @param[out] None  
+ * @retval     None.         
+ *
+ * @par Description
+ * @details    This function is called to Switch Context for task change.
+ ******************************************************************************
+ */
+#if CFG_CHIP_TYPE == 2
+extern "C" __asm  void PendSV_Handler()
+{
+    IMPORT  TCBRunning
+    IMPORT  TCBNext
+    IMPORT  OSSchedLock
+    LDR     R3,=TCBRunning
+    LDR     R1,[R3]             ; R1 == running tcb
+    LDR     R2,=TCBNext
+    LDR     R2,[R2]             ; R2 == next tcb
+
+    CMP     R1,R2
+    BEQ     exitPendSV                
+    MRS     R0, PSP             ; Get PSP point (can not use PUSH,in ISR,SP is MSP )
+  
+    SUBS    R0,R0,#32
+    STR     R0,[R1]             ; Save orig PSP
+                                ; Store r4-r11,r0 -= regCnt * 4,r0 is new stack 
+                                ; top point (addr h->l r11,r10,...,r5,r4)
+    STMIA   R0!,{R4-R7}         ; Save old context (R4-R7)
+    MOV     R4,R8
+    MOV     R5,R9
+    MOV     R6,R10
+    MOV     R7,R11
+    STMIA   R0!,{R4-R7}         ; Save old context (R8-R11)
+
+
+popStk  
+    STR     R2, [R3]            ; TCBRunning  = TCBNext;
+    LDR     R0, [R2]            ; Get SP of task that be switch into.
+        
+    ADDS    R0,    R0,#16
+    LDMIA   R0!,{R4-R7}         ; Restore new Context (R8-R11)
+    MOV     R8,R4
+    MOV     R9,R5
+    MOV     R10,R6
+    MOV     R11,R7
+    SUBS    R0,R0,#32
+    LDMIA   R0!,{R4-R7}         ; Restore new Context (R4-R7)
+    ADDS    R0,    R0,#16
+    MSR     PSP, R0             ; Mov new stack point to PSP
+
+exitPendSV    
+   LDR     R3,=OSSchedLock
+   MOVS    R0, #0x0
+   STRB    R0, [R3]
+   MOVS    R0,#4
+   RSBS    R0,#0               ; =0xFFFFFFFC,Ensure exception return uses process stack
+   BX      R0                  ; Exit interrupt
+   ALIGN
+}
+#endif
+
+
+#if CFG_CHIP_TYPE == 1
+extern "C" __asm  void PendSV_Handler()
+{
+    IMPORT  TCBRunning
+    IMPORT  TCBNext
+    IMPORT  OSSchedLock
+    LDR     R3,=TCBRunning
+    LDR     R1,[R3]             ; R1 == running tcb
+    LDR     R2,=TCBNext
+    LDR     R2,[R2]             ; R2 == next tcb
+
+    CMP     R1,R2
+    BEQ     exitPendSV                
+    MRS     R0, PSP             ; Get PSP point (can not use PUSH,in ISR,SP is MSP )
+    STMDB   R0!,{R4-R11}        ; Store r4-r11,r0 -= regCnt * 4,r0 is new stack 
+                                ; top point (addr h->l r11,r10,...,r5,r4)
+    STR     R0,[R1]             ; Save orig PSP
+popStk  
+    STR     R2, [R3]            ; TCBRunning  = TCBNext;
+    LDR     R0, [R2]            ; Get SP of task that be switch into.
+    LDMIA   R0!,{R4-R11}        ; POP (R4-R11),R0 += regCnt * 4
+    MSR     PSP, R0             ; Mov new stack point to PSP
+
+exitPendSV    
+    LDR     R3,=OSSchedLock
+    MOVS    R0, #0x0
+    STRB    R0, [R3]
+    ORR     LR, LR, #0x04       ; Ensure exception return uses process stack
+    BX      LR                  ; Exit interrupt
+    
+    ALIGN
+}
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/portable/OsArch.h	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,50 @@
+/**
+ *******************************************************************************
+ * @file       OsArch.h
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief      Implement function declare related to Cortex-M3(ARM-v7)
+ * @details    This header file including functions or defines related to 
+ *             Cortex-M3(ARM-v7).	 		
+ *******************************************************************************
+ * @copy
+ *
+ * INTERNAL FILE,DON'T PUBLIC.
+ * 
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */ 
+
+
+#ifndef  _CPU_H
+#define  _CPU_H
+
+
+#define NVIC_ST_CTRL    (*((volatile U32 *)0xE000E010))
+#define NVIC_ST_RELOAD  (*((volatile U32 *)0xE000E014))
+#define RELOAD_VAL      ((U32)(( (U32)CFG_CPU_FREQ) / (U32)CFG_SYSTICK_FREQ) -1)
+
+/*!< Initial System tick.	*/
+#define InitSysTick()   NVIC_ST_RELOAD =  RELOAD_VAL; \
+                        NVIC_ST_CTRL   =  0x0007    
+
+#define NVIC_SYS_PRI2   (*((volatile U32 *)0xE000ED1C))
+#define NVIC_SYS_PRI3   (*((volatile U32 *)0xE000ED20))
+
+/*!< Initialize PendSV,SVC and SysTick interrupt priority to lowest.          */
+#define InitInt()       NVIC_SYS_PRI2 |=  0xFF000000;\
+                        NVIC_SYS_PRI3 |=  0xFFFF0000
+
+
+/*---------------------------- Variable declare ------------------------------*/
+extern U64      OSTickCnt;          /*!< Counter for current system ticks.    */									
+
+/*!< Initial context of task being created	*/
+extern OS_STK  *InitTaskContext(FUNCPtr task,void *param,OS_STK *pstk);
+extern void    SwitchContext(void);         /*!< Switch context                   */
+extern void    SetEnvironment(OS_STK *pstk);/*!< Set environment for run          */
+extern U8      Inc8 (volatile U8 *data);
+extern U8      Dec8 (volatile U8 *data);
+extern void    IRQ_ENABLE_RESTORE(void);
+extern void    IRQ_DISABLE_SAVE(void);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CoOS/portable/arch.c	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,96 @@
+/**
+ *******************************************************************************
+ * @file      arch.c
+ * @version    V1.1.4    
+ * @date       2011.04.20
+ * @brief     This file provides InitTaskContext() and SysTick_Handler().
+ *******************************************************************************
+ * @copy
+ *    WRITE COPY INFORMATION USE CAPITAL LETTER
+ *
+ * <h2><center>&copy; COPYRIGHT 2009 CooCox </center></h2>
+ *******************************************************************************
+ */  
+
+/*---------------------------- Include ---------------------------------------*/
+#include <coocox.h>
+U64     OSTickCnt = 0;                  /*!< Current system tick counter      */                                                                              
+
+/**
+ ******************************************************************************
+ * @brief      Initial task context      
+ * @param[in]  task    Entry point of task.
+ * @param[in]  param   The parameter pass to task.    
+ * @param[in]  pstk    The pointer to stack top.     
+ * @param[out] None  
+ * @retval     Returns location of new stack top.         
+ *
+ * @par Description
+ * @details    This function is called to initialize the stack frame of the 
+ *             task being created.
+ ******************************************************************************
+ */
+OS_STK *InitTaskContext(FUNCPtr task,void *param,OS_STK *pstk)
+{
+    OS_STK *context;
+    context  = pstk;
+    *(context--) = (U32)0x01000000L;      /* xPSR            */
+    *(context--) = (U32)task;             /* Entry point of task.                         */
+    *(context)   = (U32)0xFFFFFFFEL;
+    context      = context - 5;
+    *(context)   = (U32)param;            /* R0: argument */
+    context      = context - 8;
+      
+    return (context);                   /* Returns location of new stack top. */
+}
+
+
+ 
+/**
+ *******************************************************************************
+ * @brief      System tick interrupt handler.             
+ * @param[in]  None     
+ * @param[out] None       
+ * @retval     None
+ *         
+ * @par Description
+ * @details    This is system tick interrupt headler.         
+ * @note       CoOS may schedule when exiting this ISR. 
+ *******************************************************************************
+ */ 
+extern "C" void SysTick_Handler(void)
+{
+    OSSchedLock++;                  /* Lock scheduler.                        */
+    OSTickCnt++;                    /* Increment systerm time.                */
+#if CFG_TASK_WAITTING_EN >0    
+    if(DlyList != Co_NULL)             /* Have task in delay list?               */
+    {
+        if(DlyList->delayTick > 1)  /* Delay time > 1?                        */
+        {
+            DlyList->delayTick--;   /* Decrease delay time of the list head.  */         
+        }
+        else
+        {
+            DlyList->delayTick = 0;
+            isr_TimeDispose();       /* Call hander for delay time list        */
+        }
+    }
+#endif
+    
+#if CFG_TMR_EN > 0    
+    if(TmrList != Co_NULL)             /* Have timer in working?                 */
+    {
+        if(TmrList->tmrCnt > 1)     /* Timer time > 1?                        */
+        {
+            TmrList->tmrCnt--;      /* Decrease timer time of the list head.  */        
+        }
+        else
+        {
+            TmrList->tmrCnt = 0;
+            isr_TmrDispose();         /* Call hander for timer list             */
+        }
+    }    
+#endif
+    TaskSchedReq = Co_TRUE;
+    OsSchedUnlock();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,83 @@
+// CooCox RTOS v1.1.4 with simple example
+// Two LEDs will blink with 250ms and 500ms interval based on two seperate tasks
+// by electronix79, 29/July/2011
+//
+// Comments: Nice work by Eric Ebert which used CooCox RTOS v1.1.3 but all files of CoOS were in one main folder,
+// so I create new project with the same structure as in CooCox design and of cause I use the updated version 1.1.4 
+
+#include "mbed.h"
+
+#include <CoOS.h>
+
+DigitalOut led1(LED1), led4(LED4);
+
+#define TASK_STACK_SIZE         128         /*!< Define task size */
+
+#define PRIORITY_TASK1          1           /* Priority of task 1 */
+#define PRIORITY_TASK2          2           /* Priority of task 2 */
+#define PRIORITY_TASK3          3           /* Priority of task 3 */
+
+OS_STK    task1_stk[TASK_STACK_SIZE];       /*!< Define "task1" task stack */
+OS_STK    task2_stk[TASK_STACK_SIZE];       /*!< Define "task2" task stack */
+OS_STK    task3_stk[TASK_STACK_SIZE];       /*!< Define "task3" task stack */
+
+OS_TID    task1_id;                         /*!< Task ID of 'task1'. */
+OS_TID    task2_id;                         /*!< Task ID of 'task2'. */
+OS_TID    task3_id;                         /*!< Task ID of 'task3'. */
+
+OS_MutexID	mut_1;							/*!< Save id of mutex.	*/
+
+void task1(void *);
+void task2(void *);
+void task3(void *);
+
+void task1(void* pdata)
+{   
+    mut_1 = CoCreateMutex();				/* Create a mutex */
+
+    task2_id = CoCreateTask(task2, (void *)0, PRIORITY_TASK2, &task2_stk[TASK_STACK_SIZE-1], TASK_STACK_SIZE);
+    task3_id = CoCreateTask(task3, (void *)0, PRIORITY_TASK3, &task3_stk[TASK_STACK_SIZE-1], TASK_STACK_SIZE);
+    
+    CoExitTask();							/* Delete 'task1' task. */
+}
+
+void task2(void* pdata)
+{
+    for(;;)
+    {
+        CoEnterMutexSection(mut_1);			/* Enter critical region */
+        led1 = 1;                           /* Turn On Led */
+        CoLeaveMutexSection(mut_1);			/* Exit critical region */
+        CoTickDelay(250);                   /* Delay 250ms */
+        CoEnterMutexSection(mut_1);			/* Enter critical region */
+        led1 = 0;                           /* Turn Off Led */
+        CoLeaveMutexSection(mut_1);			/* Exit critical region */
+        CoTickDelay(250);                   /* Delay 250ms */
+    }
+}
+
+void task3(void* pdata)
+{
+    for(;;)
+    {
+        CoEnterMutexSection(mut_1);			/* Enter critical region */
+        led4 = 1;                           /* Turn On Led */
+        CoLeaveMutexSection(mut_1);			/* Exit critical region */
+        CoTickDelay(500);                   /* Delay 500ms */
+        CoEnterMutexSection(mut_1);			/* Enter critical region */
+        led4 = 0;                           /* Turn Off Led */
+        CoLeaveMutexSection(mut_1);			/* Exit critical region */
+        CoTickDelay(500);                   /* Delay 500ms */
+    }
+}
+
+int main()
+{
+    CoInitOS();                             /*!< Initial CooCox CoOS */
+
+    task1_id = CoCreateTask(task1, (void *)0, PRIORITY_TASK1, &task1_stk[TASK_STACK_SIZE-1], TASK_STACK_SIZE);
+
+    CoStartOS();                            /*!< Start multitask */
+
+    while (1);                              /*!< The code don't reach here */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Jul 29 03:01:03 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912