diff --git a/radio/src/CoOS/kernel/OsConfig.h b/radio/src/CoOS/OsConfig.h similarity index 76% rename from radio/src/CoOS/kernel/OsConfig.h rename to radio/src/CoOS/OsConfig.h index 32546a27b..c6afebe4e 100644 --- a/radio/src/CoOS/kernel/OsConfig.h +++ b/radio/src/CoOS/OsConfig.h @@ -1,16 +1,39 @@ /** ******************************************************************************* * @file OsConfig.h - * @version V1.1.4 - * @date 2011.04.20 + * @version V1.1.6 + * @date 2014.05.23 * @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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. * - *

© COPYRIGHT 2009 CooCox

+ *

© COPYRIGHT 2014 CooCox

******************************************************************************* */ @@ -37,7 +60,11 @@ Max number of tasks that can be running. /*!< Idle task stack size(word). */ +#if CFG_CHIP_TYPE == 3 +#define CFG_IDLE_STACK_SIZE (58) +#else #define CFG_IDLE_STACK_SIZE (25) +#endif /*!< System frequency (Hz). diff --git a/radio/src/CoOS/kernel/CoOS.h b/radio/src/CoOS/kernel/CoOS.h index 33fdc5321..be687b2e7 100644 --- a/radio/src/CoOS/kernel/CoOS.h +++ b/radio/src/CoOS/kernel/CoOS.h @@ -1,222 +1,245 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -#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 +/** + ******************************************************************************* + * @file CoOS.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief API header file of CooCox CoOS. + * @details This file including all API functions's declare of CooCox CoOS. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +#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 diff --git a/radio/src/CoOS/kernel/OsCore.h b/radio/src/CoOS/kernel/OsCore.h index 20761b3b5..98395db7d 100644 --- a/radio/src/CoOS/kernel/OsCore.h +++ b/radio/src/CoOS/kernel/OsCore.h @@ -1,27 +1,50 @@ -/** - ******************************************************************************* - * @file OsCore.h - * @version V1.1.4 - * @date 2011.04.20 - * @brief Header file related to kernel - ******************************************************************************* - * @copy - * - * INTERNAL FILE,DON'T PUBLIC. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#ifndef _CORE_H -#define _CORE_H - -#include - - -#define OsSchedLock() { OSSchedLock++; asm volatile ("" : : : "memory"); } /*!< Lock schedule */ -extern void OsSchedUnlock(void); - -#endif - +/** + ******************************************************************************* + * @file OsCore.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to kernel + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#ifndef _CORE_H +#define _CORE_H + +#include + + +#define OsSchedLock() OSSchedLock++; /*!< Lock schedule */ +extern void OsSchedUnlock(void); + +#endif + diff --git a/radio/src/CoOS/kernel/OsError.h b/radio/src/CoOS/kernel/OsError.h index 75793cbac..b09ec2703 100644 --- a/radio/src/CoOS/kernel/OsError.h +++ b/radio/src/CoOS/kernel/OsError.h @@ -1,84 +1,107 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 */ +/** + ******************************************************************************* + * @file OsError.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief rror dispose header file + * @details This file use to dispose error which from error configure for OS. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 */ diff --git a/radio/src/CoOS/kernel/OsEvent.h b/radio/src/CoOS/kernel/OsEvent.h index 7569a5e19..e0f8ab8ac 100644 --- a/radio/src/CoOS/kernel/OsEvent.h +++ b/radio/src/CoOS/kernel/OsEvent.h @@ -1,58 +1,81 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 +/** + ******************************************************************************* + * @file OsEvent.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Event management header file + * @details This file including some defines and declares related to event + * (semaphore,mailbox,queque) management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 diff --git a/radio/src/CoOS/kernel/OsFlag.h b/radio/src/CoOS/kernel/OsFlag.h index 408ff8e19..3f318af96 100644 --- a/radio/src/CoOS/kernel/OsFlag.h +++ b/radio/src/CoOS/kernel/OsFlag.h @@ -1,57 +1,80 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 - +/** + ******************************************************************************* + * @file OsFlag.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Evnet flag management header file + * @details This file including some defines and declares about flag management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 + diff --git a/radio/src/CoOS/kernel/OsKernelHeap.h b/radio/src/CoOS/kernel/OsKernelHeap.h index a02f87017..be6be4164 100644 --- a/radio/src/CoOS/kernel/OsKernelHeap.h +++ b/radio/src/CoOS/kernel/OsKernelHeap.h @@ -1,48 +1,71 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 */ - +/** + ******************************************************************************* + * @file OsKernelHeap.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to memory management + * @details This file including some defines and function declare related to + * kernel heap management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 */ + diff --git a/radio/src/CoOS/kernel/OsMM.h b/radio/src/CoOS/kernel/OsMM.h index 506266d8f..4332600b4 100644 --- a/radio/src/CoOS/kernel/OsMM.h +++ b/radio/src/CoOS/kernel/OsMM.h @@ -1,41 +1,64 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 */ - +/** + ******************************************************************************* + * @file OsMm.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to memory management + * @details This file including some defines and function declare related to + * memory management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 */ + diff --git a/radio/src/CoOS/kernel/OsMutex.h b/radio/src/CoOS/kernel/OsMutex.h index 584b11946..769154740 100644 --- a/radio/src/CoOS/kernel/OsMutex.h +++ b/radio/src/CoOS/kernel/OsMutex.h @@ -1,57 +1,80 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#ifndef _MUTEX_H -#define _MUTEX_H - -#include - -#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 */ +/** + ******************************************************************************* + * @file OsMutex.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Mutex management header file + * @details This file including some defines and declare related to mutex + * management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#ifndef _MUTEX_H +#define _MUTEX_H + +#include + +#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 */ diff --git a/radio/src/CoOS/kernel/OsQueue.h b/radio/src/CoOS/kernel/OsQueue.h index c39488d48..4a8c3ab3b 100644 --- a/radio/src/CoOS/kernel/OsQueue.h +++ b/radio/src/CoOS/kernel/OsQueue.h @@ -1,39 +1,62 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 +/** + ******************************************************************************* + * @file OsQueue.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Queue management header file + * @details This file including some defines and declares about queue management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 diff --git a/radio/src/CoOS/kernel/OsServiceReq.h b/radio/src/CoOS/kernel/OsServiceReq.h index 4d7d31d2e..af5d581ea 100644 --- a/radio/src/CoOS/kernel/OsServiceReq.h +++ b/radio/src/CoOS/kernel/OsServiceReq.h @@ -1,53 +1,76 @@ - -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 + +/** + ******************************************************************************* + * @file OsServiceReq.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to service request + * @details This file including some defines and function declare related to + * service request. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 diff --git a/radio/src/CoOS/kernel/OsTask.h b/radio/src/CoOS/kernel/OsTask.h index 0ff8febd9..e25bde982 100644 --- a/radio/src/CoOS/kernel/OsTask.h +++ b/radio/src/CoOS/kernel/OsTask.h @@ -1,112 +1,135 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -#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 +/** + ******************************************************************************* + * @file OsTask.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to task. + * @details This file including some defines and function declare related to task. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +#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 diff --git a/radio/src/CoOS/kernel/OsTime.h b/radio/src/CoOS/kernel/OsTime.h index 279d4856c..34bbc8efd 100644 --- a/radio/src/CoOS/kernel/OsTime.h +++ b/radio/src/CoOS/kernel/OsTime.h @@ -1,28 +1,51 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -#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 +/** + ******************************************************************************* + * @file OsTime.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Header file related to time management + * @details Thie file including some data declare related to time managment. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +#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 diff --git a/radio/src/CoOS/kernel/OsTimer.h b/radio/src/CoOS/kernel/OsTimer.h index 861f5ea73..8e9d4dac0 100644 --- a/radio/src/CoOS/kernel/OsTimer.h +++ b/radio/src/CoOS/kernel/OsTimer.h @@ -1,49 +1,72 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -#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 +/** + ******************************************************************************* + * @file OsTimer.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Timer manage header file + * @details This file including some declares and defines related to timer + * management. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +#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 diff --git a/radio/src/CoOS/kernel/coocox.h b/radio/src/CoOS/kernel/coocox.h index c325ec9d9..b9a3bf41a 100644 --- a/radio/src/CoOS/kernel/coocox.h +++ b/radio/src/CoOS/kernel/coocox.h @@ -1,60 +1,83 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#ifndef _COOCOX_H -#define _COOCOX_H - -#define OS_VERSION (U16)0x0113 /*!< OS version.(format: Vx.xx), - e.g. value 0x0113 is version V1.13*/ -/*---------------------------- 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 */ +/** + ******************************************************************************* + * @file coocox.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Gather for all header file of CooCox CoOS. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#ifndef _COOCOX_H +#define _COOCOX_H + +#define OS_VERSION (U16)0x0116 /*!< 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 */ diff --git a/radio/src/CoOS/kernel/core.c b/radio/src/CoOS/kernel/core.c index 7342983bb..68176fb31 100644 --- a/radio/src/CoOS/kernel/core.c +++ b/radio/src/CoOS/kernel/core.c @@ -1,238 +1,261 @@ - /** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -/*---------------------------- Include ---------------------------------------*/ -#include - -/*---------------------------- 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 */ -} - + /** + ******************************************************************************* + * @file core.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Core implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +/*---------------------------- Include ---------------------------------------*/ +#include + +/*---------------------------- 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 */ +} + diff --git a/radio/src/CoOS/kernel/event.c b/radio/src/CoOS/kernel/event.c index 52aea1929..eabee442f 100644 --- a/radio/src/CoOS/kernel/event.c +++ b/radio/src/CoOS/kernel/event.c @@ -1,410 +1,435 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - - -/*---------------------------- Variable Define -------------------------------*/ -#if CFG_EVENT_EN > 0 - -ECB EventTbl[CFG_MAX_EVENT]= {{0}};/*!< Table which save event control block.*/ -P_ECB FreeEventList = Co_NULL; /*!< 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 Co_NULL; /* Return error */ - } - pecb = FreeEventList;/* Assign the free event item to this event */ - FreeEventList = 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 = Co_NULL; - 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 = Co_NULL; /* 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 == Co_NULL) - 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 = Co_NULL; /* No,clear link for first item */ - } - - ptcb->waitNext = Co_NULL; /* 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 == Co_NULL) && (ptcb->waitPrev == Co_NULL)) - { - pecb->eventTCBList = Co_NULL; /* Yes,set event waiting list as Co_NULL */ - } - else if(ptcb->waitPrev == Co_NULL)/* Is the first item in event waiting list?*/ - { - /* Yes,remove task from list,and reset event waiting list */ - ptcb->waitNext->waitPrev = Co_NULL; - pecb->eventTCBList = ptcb->waitNext; - ptcb->waitNext = Co_NULL; - } - else if(ptcb->waitNext == Co_NULL)/* Is the last item in event waiting list? */ - { - ptcb->waitPrev->waitNext = Co_NULL; /* Yes,remove task form list */ - ptcb->waitPrev = Co_NULL; - } - else /* No, remove task from list */ - { - ptcb->waitPrev->waitNext = ptcb->waitNext; - ptcb->waitNext->waitPrev = ptcb->waitPrev; - ptcb->waitPrev = Co_NULL; - ptcb->waitNext = Co_NULL; - } - ptcb->eventID = INVALID_ID; /* Sign that not to use. */ -} - -#endif //CFG_EVENT_EN - +/** + ******************************************************************************* + * @file event.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief event management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + + +/*---------------------------- Variable Define -------------------------------*/ +#if CFG_EVENT_EN > 0 + +ECB EventTbl[CFG_MAX_EVENT]= {{0}};/*!< Table which save event control block.*/ +P_ECB FreeEventList = Co_NULL; /*!< 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 Co_NULL; /* Return error */ + } + pecb = FreeEventList;/* Assign the free event item to this event */ + FreeEventList = 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 = Co_NULL; + 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 = Co_NULL; /* 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 == Co_NULL) + 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 = Co_NULL; /* No,clear link for first item */ + } + + ptcb->waitNext = Co_NULL; /* 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 CFG_MAILBOX_EN >0 + 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--; + } +#endif +#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_SEM_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 == Co_NULL) && (ptcb->waitPrev == Co_NULL)) + { + pecb->eventTCBList = Co_NULL; /* Yes,set event waiting list as Co_NULL */ + } + else if(ptcb->waitPrev == Co_NULL)/* Is the first item in event waiting list?*/ + { + /* Yes,remove task from list,and reset event waiting list */ + ptcb->waitNext->waitPrev = Co_NULL; + pecb->eventTCBList = ptcb->waitNext; + ptcb->waitNext = Co_NULL; + } + else if(ptcb->waitNext == Co_NULL)/* Is the last item in event waiting list? */ + { + ptcb->waitPrev->waitNext = Co_NULL; /* Yes,remove task form list */ + ptcb->waitPrev = Co_NULL; + } + else /* No, remove task from list */ + { + ptcb->waitPrev->waitNext = ptcb->waitNext; + ptcb->waitNext->waitPrev = ptcb->waitPrev; + ptcb->waitPrev = Co_NULL; + ptcb->waitNext = Co_NULL; + } + ptcb->eventID = INVALID_ID; /* Sign that not to use. */ +} + +#endif //CFG_EVENT_EN + diff --git a/radio/src/CoOS/kernel/flag.c b/radio/src/CoOS/kernel/flag.c index 4fb4dc789..75fc58a7a 100644 --- a/radio/src/CoOS/kernel/flag.c +++ b/radio/src/CoOS/kernel/flag.c @@ -1,712 +1,735 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - - -/*---------------------------- Include ---------------------------------------*/ -#include - -#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 0) /* If be called from ISR */ - { - return E_CALL; - } -#if CFG_PAR_CHECKOUT_EN >0 - if((pfcb->flagActive&(1<headNode; - - while(pnode != Co_NULL) /* Ready all tasks waiting for flags */ - { - if((pnode->waitFlags&(1<waitType == OPT_WAIT_ALL) - { - /* If the flag is only required by NODE */ - if( pnode->waitFlags == (1<waitFlags &= ~(1<nextNode; - } - - /* Remove the flag from the flags list */ - pfcb->flagActive &= ~(1<flagRdy &= ~(1<resetOpt &= ~(1<0 - if(id >= FLAG_MAX_NUM) - { - return E_INVALID_ID; /* Invalid 'id',return error */ - } - if((pfcb->flagActive&(1<flagRdy&(1<flagRdy &= ~((FlagCrl.resetOpt)&(1<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<flagRdy&(1<flagRdy &= ~((pfcb->resetOpt&(1<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<resetOpt)); - OsSchedUnlock(); - } - else /* If time-out is configured */ - { - /* Block task until the required flag is set or time-out occurs */ - FlagBlock(&flagNode,(1<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<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<flagRdy &= ~(1<0 - if(id >= FLAG_MAX_NUM) /* Flag is valid or not */ - { - return E_INVALID_ID; /* Invalid flag id */ - } - if((pfcb->flagActive&(1<flagRdy&(1<flagRdy |= (1<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<waitFlags & pfcb->flagRdy) != 0) - { - /* Remove the flag node from the wait list */ - pnode = RemoveFromLink(pnode); - if((pfcb->resetOpt&(1<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 == Co_NULL) /* If this is the first NODE to insert? */ - { - pnode->nextNode = Co_NULL; - pnode->prevNode = Co_NULL; - 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 = Co_NULL; - } - 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 == Co_NULL) && (pnode->prevNode == Co_NULL)) - { - FlagCrl.headNode = Co_NULL; - FlagCrl.tailNode = Co_NULL; - } - else if(pnode->nextNode == Co_NULL) /* If the NODE is tail */ - { - FlagCrl.tailNode = pnode->prevNode; - pnode->prevNode->nextNode = Co_NULL; - } - else if(pnode->prevNode == Co_NULL) /* If the NODE is head */ - { - FlagCrl.headNode = pnode->nextNode; - pnode->nextNode->prevNode = Co_NULL; - } - else /* The NODE is in the middle */ - { - pnode->nextNode->prevNode = pnode->prevNode; - pnode->prevNode->nextNode = pnode->nextNode; - } - pnode->waitTask->pnode = Co_NULL; -} - -#endif +/** + ******************************************************************************* + * @file flag.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Flag management implementation code of coocox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include + +#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 0) /* If be called from ISR */ + { + return E_CALL; + } +#if CFG_PAR_CHECKOUT_EN >0 + if((pfcb->flagActive&(1<headNode; + + while(pnode != Co_NULL) /* Ready all tasks waiting for flags */ + { + if((pnode->waitFlags&(1<waitType == OPT_WAIT_ALL) + { + /* If the flag is only required by NODE */ + if( pnode->waitFlags == (1<waitFlags &= ~(1<nextNode; + } + + /* Remove the flag from the flags list */ + pfcb->flagActive &= ~(1<flagRdy &= ~(1<resetOpt &= ~(1<0 + if(id >= FLAG_MAX_NUM) + { + return E_INVALID_ID; /* Invalid 'id',return error */ + } + if((pfcb->flagActive&(1<flagRdy&(1<flagRdy &= ~((FlagCrl.resetOpt)&(1<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<flagRdy&(1<flagRdy &= ~((pfcb->resetOpt&(1<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<resetOpt)); + OsSchedUnlock(); + } + else /* If time-out is configured */ + { + /* Block task until the required flag is set or time-out occurs */ + FlagBlock(&flagNode,(1<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<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<flagRdy &= ~(1<0 + if(id >= FLAG_MAX_NUM) /* Flag is valid or not */ + { + return E_INVALID_ID; /* Invalid flag id */ + } + if((pfcb->flagActive&(1<flagRdy&(1<flagRdy |= (1<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<waitFlags & pfcb->flagRdy) != 0) + { + /* Remove the flag node from the wait list */ + pnode = RemoveFromLink(pnode); + if((pfcb->resetOpt&(1<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 == Co_NULL) /* If this is the first NODE to insert? */ + { + pnode->nextNode = Co_NULL; + pnode->prevNode = Co_NULL; + 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 = Co_NULL; + } + 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 == Co_NULL) && (pnode->prevNode == Co_NULL)) + { + FlagCrl.headNode = Co_NULL; + FlagCrl.tailNode = Co_NULL; + } + else if(pnode->nextNode == Co_NULL) /* If the NODE is tail */ + { + FlagCrl.tailNode = pnode->prevNode; + pnode->prevNode->nextNode = Co_NULL; + } + else if(pnode->prevNode == Co_NULL) /* If the NODE is head */ + { + FlagCrl.headNode = pnode->nextNode; + pnode->nextNode->prevNode = Co_NULL; + } + else /* The NODE is in the middle */ + { + pnode->nextNode->prevNode = pnode->prevNode; + pnode->prevNode->nextNode = pnode->nextNode; + } + pnode->waitTask->pnode = Co_NULL; +} + +#endif diff --git a/radio/src/CoOS/kernel/hook.c b/radio/src/CoOS/kernel/hook.c index c210a7e78..09853b962 100644 --- a/radio/src/CoOS/kernel/hook.c +++ b/radio/src/CoOS/kernel/hook.c @@ -1,65 +1,88 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Inlcude --------------------------------------*/ -#include - -/** - ******************************************************************************* - * @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(; ;) - { - - } -} - - - - - - +/** + ******************************************************************************* + * @file hook.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief hook management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Inlcude --------------------------------------*/ +#include + +/** + ******************************************************************************* + * @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(; ;) + { + + } +} + + + + + + diff --git a/radio/src/CoOS/kernel/kernelHeap.c b/radio/src/CoOS/kernel/kernelHeap.c index 0fb2f3d55..09509627f 100644 --- a/radio/src/CoOS/kernel/kernelHeap.c +++ b/radio/src/CoOS/kernel/kernelHeap.c @@ -1,409 +1,432 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - - -#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 +/** + ******************************************************************************* + * @file kernelHeap.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief kernel heap management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + + +#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 diff --git a/radio/src/CoOS/kernel/mbox.c b/radio/src/CoOS/kernel/mbox.c index 47cb47401..1e2e58737 100644 --- a/radio/src/CoOS/kernel/mbox.c +++ b/radio/src/CoOS/kernel/mbox.c @@ -1,325 +1,356 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -/*---------------------------- Include ---------------------------------------*/ -#include - - -#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 - - +/** + ******************************************************************************* + * @file mbox.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Mailbox management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +/*---------------------------- Include ---------------------------------------*/ +#include + + +#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 */ + OsSchedLock(); + pmail = curTCB->pmail; + pecb->eventCounter = 0; + curTCB->pmail = Co_NULL; + OsSchedUnlock(); + 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; + + OsSchedLock(); + pmail = curTCB->pmail; + pecb->eventCounter = 0; + curTCB->pmail = Co_NULL; + OsSchedUnlock(); + + 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 + + diff --git a/radio/src/CoOS/kernel/mm.c b/radio/src/CoOS/kernel/mm.c index 73a82d34b..8654ba05c 100644 --- a/radio/src/CoOS/kernel/mm.c +++ b/radio/src/CoOS/kernel/mm.c @@ -1,275 +1,298 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - - -#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<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<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<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<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<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 - +/** + ******************************************************************************* + * @file mm.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief memory management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + + +#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<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<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<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<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<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 + diff --git a/radio/src/CoOS/kernel/mutex.c b/radio/src/CoOS/kernel/mutex.c index 4bf541abc..4906fde96 100644 --- a/radio/src/CoOS/kernel/mutex.c +++ b/radio/src/CoOS/kernel/mutex.c @@ -1,349 +1,372 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - - -/*---------------------------- Include ---------------------------------------*/ -#include - - -/*---------------------------- 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 = Co_NULL; - 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 = Co_NULL; - pCurTcb->TCBprev = Co_NULL; - - ptcb = pMutex->waittingList; - if(ptcb == Co_NULL) /* 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 != Co_NULL) /* Insert the task to tail */ - { - ptcb = ptcb->TCBnext; - } - ptcb->TCBnext = pCurTcb; - pCurTcb->TCBprev = ptcb; - pCurTcb->TCBnext = Co_NULL; - } - } - 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 == Co_NULL) /* 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 != Co_NULL) /* 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 = Co_NULL; - ptcb->TCBprev = Co_NULL; - - 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 ==Co_NULL) && (ptcb->TCBprev == Co_NULL)) - { - pMutex->waittingList = Co_NULL; /* Waiting list is empty */ - } - else if(ptcb->TCBnext == Co_NULL) /* If the task is the last of waiting list*/ - { - /* Remove task from mutex waiting list */ - ptcb->TCBprev->TCBnext = Co_NULL; - ptcb->TCBprev = Co_NULL; - } - else if(ptcb->TCBprev == Co_NULL)/* If the task is the first of waiting list*/ - { - /* Remove task from waiting list */ - ptcb->TCBnext->TCBprev = Co_NULL; - ptcb->TCBnext = Co_NULL; - } - 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 = Co_NULL; - ptcb->TCBnext = Co_NULL; - } - - 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 != Co_NULL) /* 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 +/** + ******************************************************************************* + * @file mutex.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Mutex management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include + + +/*---------------------------- 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 = Co_NULL; + 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 = Co_NULL; + pCurTcb->TCBprev = Co_NULL; + + ptcb = pMutex->waittingList; + if(ptcb == Co_NULL) /* 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 != Co_NULL) /* Insert the task to tail */ + { + ptcb = ptcb->TCBnext; + } + ptcb->TCBnext = pCurTcb; + pCurTcb->TCBprev = ptcb; + pCurTcb->TCBnext = Co_NULL; + } + } + 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 == Co_NULL) /* 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 != Co_NULL) /* 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 = Co_NULL; + ptcb->TCBprev = Co_NULL; + + 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 ==Co_NULL) && (ptcb->TCBprev == Co_NULL)) + { + pMutex->waittingList = Co_NULL; /* Waiting list is empty */ + } + else if(ptcb->TCBnext == Co_NULL) /* If the task is the last of waiting list*/ + { + /* Remove task from mutex waiting list */ + ptcb->TCBprev->TCBnext = Co_NULL; + ptcb->TCBprev = Co_NULL; + } + else if(ptcb->TCBprev == Co_NULL)/* If the task is the first of waiting list*/ + { + /* Remove task from waiting list */ + ptcb->TCBnext->TCBprev = Co_NULL; + ptcb->TCBnext = Co_NULL; + } + 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 = Co_NULL; + ptcb->TCBnext = Co_NULL; + } + + 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 != Co_NULL) /* 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 diff --git a/radio/src/CoOS/kernel/queue.c b/radio/src/CoOS/kernel/queue.c index 2ff91a8e1..b8663be4d 100644 --- a/radio/src/CoOS/kernel/queue.c +++ b/radio/src/CoOS/kernel/queue.c @@ -1,393 +1,432 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -/*---------------------------- Include ---------------------------------------*/ -#include - - -#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<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 +/** + ******************************************************************************* + * @file queue.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Queue management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +/*---------------------------- Include ---------------------------------------*/ +#include + + +#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<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 */ + OsSchedLock(); + pmail = curTCB->pmail; + curTCB->pmail = Co_NULL; + pqcb->head++; /* Clear event sign */ + pqcb->qSize--; + if(pqcb->head == pqcb->qMaxSize) + { + pqcb->head = 0; + } + OsSchedUnlock(); + *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 */ + { + OsSchedLock(); + pmail = curTCB->pmail; + curTCB->pmail = Co_NULL; + pqcb->head++; /* Clear event sign */ + pqcb->qSize--; + if(pqcb->head == pqcb->qMaxSize) + { + pqcb->head = 0; + } + OsSchedUnlock(); + *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 \ No newline at end of file diff --git a/radio/src/CoOS/kernel/sem.c b/radio/src/CoOS/kernel/sem.c index 576be4cf1..d8893f84a 100644 --- a/radio/src/CoOS/kernel/sem.c +++ b/radio/src/CoOS/kernel/sem.c @@ -1,322 +1,347 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - -#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 +/** + ******************************************************************************* + * @file sem.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Semaphore management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + +#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 */ + { + pecb->eventCounter--; /* Decrement semaphore only if positive */ + OsSchedUnlock(); + 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 */ + { + curTCB = TCBRunning; + if(timeout == 0) /* If time-out is not configured */ + { + EventTaskToWait(pecb,curTCB); /* Block task until event occurs */ + pecb->eventCounter--; + curTCB->pmail = Co_NULL; + OsSchedUnlock(); + return E_OK; + } + else /* If time-out is configured */ + { + /* 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*/ + { + OsSchedLock(); + curTCB->pmail = Co_NULL; + pecb->eventCounter--; + OsSchedUnlock(); + 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 diff --git a/radio/src/CoOS/kernel/serviceReq.c b/radio/src/CoOS/kernel/serviceReq.c index 58fe7cfa6..2a4cc5c94 100644 --- a/radio/src/CoOS/kernel/serviceReq.c +++ b/radio/src/CoOS/kernel/serviceReq.c @@ -1,165 +1,188 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - - -/*---------------------------- Include ---------------------------------------*/ -#include - -#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 - +/** + ******************************************************************************* + * @file serviceReq.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief servive request management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include + +#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 + diff --git a/radio/src/CoOS/kernel/task.c b/radio/src/CoOS/kernel/task.c index a8bbfdd1a..a1b36555d 100644 --- a/radio/src/CoOS/kernel/task.c +++ b/radio/src/CoOS/kernel/task.c @@ -1,1260 +1,1283 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - -/*---------------------------- 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 = Co_NULL; /*!< pointer to free TCB */ -P_OSTCB TCBRdy = Co_NULL; /*!< Pointer to the READY list. */ -P_OSTCB TCBNext = Co_NULL; /*!< Poniter to task that next scheduled by OS */ -P_OSTCB TCBRunning = Co_NULL; /*!< 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 = Co_NULL; - 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<=num*8; cnt--) - { - if( (tmp&(1<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 = Co_NULL; /* Yes,set READY list as Co_NULL */ -#if CFG_ORDER_LIST_SCHEDULE_EN ==0 - isChange = Co_TRUE; -#endif - } - else if(ptcb->TCBprev == Co_NULL) /* 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 = Co_NULL; - TCBRdy->TCBprev = Co_NULL; -#if CFG_ORDER_LIST_SCHEDULE_EN ==0 - if(TCBRdy->prio != prio) - isChange = Co_TRUE; - -#endif - } - else if( ptcb->TCBnext == Co_NULL) /* 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 = Co_NULL; - ptcb->TCBprev = Co_NULL; - } - 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 = Co_NULL; - ptcb->TCBprev = Co_NULL; - } -#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 == Co_NULL) /* Is there no free TCB */ - { - OsSchedUnlock(); /* Yes,unlock schedule */ - return Co_NULL; /* 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 == Co_NULL) - { - return E_CREATE_FAIL; - } - if(stk == Co_NULL) - { - 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 != Co_NULL) - return E_CREATE_FAIL; -#endif - - stkTopPtr = InitTaskContext(task,argv,stk); /* Initialize task context. */ - - ptcb = AssignTCB(); /* Get free TCB to use */ - - if(ptcb == Co_NULL) /* 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 = Co_NULL; /* Initialize TCB link in READY list */ - ptcb->TCBprev = Co_NULL; - -#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 = Co_NULL; /* Initialize task as no flag waiting */ -#endif - -#if CFG_EVENT_EN > 0 - ptcb->eventID = INVALID_ID; /* Initialize task as no event waiting*/ - ptcb->pmail = Co_NULL; - ptcb->waitNext = Co_NULL; - ptcb->waitPrev = Co_NULL; -#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 != Co_NULL) /* Is task in flag waiting list? */ - { - /* Yes,remove task from flag waiting list */ - RemoveLinkNode(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 +/** + ******************************************************************************* + * @file task.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief task management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + +/*---------------------------- 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 = Co_NULL; /*!< pointer to free TCB */ +P_OSTCB TCBRdy = Co_NULL; /*!< Pointer to the READY list. */ +P_OSTCB TCBNext = Co_NULL; /*!< Poniter to task that next scheduled by OS */ +P_OSTCB TCBRunning = Co_NULL; /*!< 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 = Co_NULL; + 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<=num*8; cnt--) + { + if( (tmp&(1<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 = Co_NULL; /* Yes,set READY list as Co_NULL */ +#if CFG_ORDER_LIST_SCHEDULE_EN ==0 + isChange = Co_TRUE; +#endif + } + else if(ptcb->TCBprev == Co_NULL) /* 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 = Co_NULL; + TCBRdy->TCBprev = Co_NULL; +#if CFG_ORDER_LIST_SCHEDULE_EN ==0 + if(TCBRdy->prio != prio) + isChange = Co_TRUE; + +#endif + } + else if( ptcb->TCBnext == Co_NULL) /* 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 = Co_NULL; + ptcb->TCBprev = Co_NULL; + } + 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 = Co_NULL; + ptcb->TCBprev = Co_NULL; + } +#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 == Co_NULL) /* Is there no free TCB */ + { + OsSchedUnlock(); /* Yes,unlock schedule */ + return Co_NULL; /* 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 == Co_NULL) + { + return E_CREATE_FAIL; + } + if(stk == Co_NULL) + { + 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 != Co_NULL) + return E_CREATE_FAIL; +#endif + + stkTopPtr = InitTaskContext(task,argv,stk); /* Initialize task context. */ + + ptcb = AssignTCB(); /* Get free TCB to use */ + + if(ptcb == Co_NULL) /* 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 = Co_NULL; /* Initialize TCB link in READY list */ + ptcb->TCBprev = Co_NULL; + +#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 = Co_NULL; /* Initialize task as no flag waiting */ +#endif + +#if CFG_EVENT_EN > 0 + ptcb->eventID = INVALID_ID; /* Initialize task as no event waiting*/ + ptcb->pmail = Co_NULL; + ptcb->waitNext = Co_NULL; + ptcb->waitPrev = Co_NULL; +#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 != Co_NULL) /* Is task in flag waiting list? */ + { + /* Yes,remove task from flag waiting list */ + RemoveLinkNode(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 diff --git a/radio/src/CoOS/kernel/time.c b/radio/src/CoOS/kernel/time.c index 7a9591c28..9b609c293 100644 --- a/radio/src/CoOS/kernel/time.c +++ b/radio/src/CoOS/kernel/time.c @@ -1,376 +1,399 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - - -/*---------------------------- Include ---------------------------------------*/ -#include - -#if CFG_TASK_WAITTING_EN > 0 - -/*---------------------------- Variable Define -------------------------------*/ -P_OSTCB DlyList = Co_NULL; /*!< 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 == Co_NULL) /* 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 != Co_NULL) - { - /* Get delta ticks with previous item */ - deltaTicks -= dlyNext->delayTick; - if(deltaTicks < 0) /* Is delta ticks<0? */ - { - /* Yes,get correct place */ - if(dlyNext->TCBprev != Co_NULL) /* 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 == Co_NULL) ) - { - 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 == Co_NULL) && ( ptcb->TCBnext == Co_NULL)) - { - DlyList = Co_NULL; /* Yes,set DELAY list as Co_NULL */ - } - else if(ptcb->TCBprev == Co_NULL) /* 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 = Co_NULL; - ptcb->TCBnext = Co_NULL; - - } - else if(ptcb->TCBnext == Co_NULL) /* Is the last item in DELAY list? */ - { - ptcb->TCBprev->TCBnext = Co_NULL; /* Yes,remove task form DELAY list */ - ptcb->TCBprev = Co_NULL; - } - else /* No, remove task from DELAY list */ - { - ptcb->TCBprev->TCBnext = ptcb->TCBnext; - ptcb->TCBnext->TCBprev = ptcb->TCBprev; - ptcb->TCBnext->delayTick += ptcb->delayTick; - ptcb->TCBnext = Co_NULL; - ptcb->TCBprev = Co_NULL; - } - 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 != Co_NULL) && (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 != Co_NULL) /* Is task in flag waiting list? */ - { - RemoveLinkNode(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 = Co_NULL; - - InsertToTCBRdyList(dlyList); /* Insert task into READY list */ - - dlyList = DlyList; /* Get the first item of DELAY list */ - if(dlyList != Co_NULL) /* Is DELAY list as Co_NULL? */ - { - dlyList->TCBprev = Co_NULL; /* 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 +/** + ******************************************************************************* + * @file time.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief time management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include + +#if CFG_TASK_WAITTING_EN > 0 + +/*---------------------------- Variable Define -------------------------------*/ +P_OSTCB DlyList = Co_NULL; /*!< 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 == Co_NULL) /* 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 != Co_NULL) + { + /* Get delta ticks with previous item */ + deltaTicks -= dlyNext->delayTick; + if(deltaTicks < 0) /* Is delta ticks<0? */ + { + /* Yes,get correct place */ + if(dlyNext->TCBprev != Co_NULL) /* 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 == Co_NULL) ) + { + 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 == Co_NULL) && ( ptcb->TCBnext == Co_NULL)) + { + DlyList = Co_NULL; /* Yes,set DELAY list as Co_NULL */ + } + else if(ptcb->TCBprev == Co_NULL) /* 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 = Co_NULL; + ptcb->TCBnext = Co_NULL; + + } + else if(ptcb->TCBnext == Co_NULL) /* Is the last item in DELAY list? */ + { + ptcb->TCBprev->TCBnext = Co_NULL; /* Yes,remove task form DELAY list */ + ptcb->TCBprev = Co_NULL; + } + else /* No, remove task from DELAY list */ + { + ptcb->TCBprev->TCBnext = ptcb->TCBnext; + ptcb->TCBnext->TCBprev = ptcb->TCBprev; + ptcb->TCBnext->delayTick += ptcb->delayTick; + ptcb->TCBnext = Co_NULL; + ptcb->TCBprev = Co_NULL; + } + 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 != Co_NULL) && (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 != Co_NULL) /* Is task in flag waiting list? */ + { + RemoveLinkNode(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 = Co_NULL; + + InsertToTCBRdyList(dlyList); /* Insert task into READY list */ + + dlyList = DlyList; /* Get the first item of DELAY list */ + if(dlyList != Co_NULL) /* Is DELAY list as Co_NULL? */ + { + dlyList->TCBprev = Co_NULL; /* 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 diff --git a/radio/src/CoOS/kernel/timer.c b/radio/src/CoOS/kernel/timer.c index efa4d87bc..acd868e4e 100644 --- a/radio/src/CoOS/kernel/timer.c +++ b/radio/src/CoOS/kernel/timer.c @@ -1,447 +1,470 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - - -/*---------------------------- Include ---------------------------------------*/ -#include - -/*---------------------------- 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<0 /* Check validity of parameter */ - if(tmrID >= CFG_MAX_TMR) - { - return E_INVALID_ID; - } - if( (TmrIDVessel & (1<0 /* Check validity of parameter */ - if(tmrID >= CFG_MAX_TMR) - { - return E_INVALID_ID; - } - if((TmrIDVessel & (1<0 /* Check validity of parameter */ - if(tmrID >= CFG_MAX_TMR) - { - return E_INVALID_ID; - } - if( (TmrIDVessel & (1<0 /* Check validity of parameter */ - if(tmrID >= CFG_MAX_TMR) - { - *perr = E_INVALID_ID; - return 0; - } - if((TmrIDVessel & (1<0 /* Check validity of parameter */ - if(tmrID >= CFG_MAX_TMR) - { - return E_INVALID_ID; - } - if( (TmrIDVessel & (1<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 +/** + ******************************************************************************* + * @file timer.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief timer management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + + +/*---------------------------- Include ---------------------------------------*/ +#include + +/*---------------------------- 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<0 /* Check validity of parameter */ + if(tmrID >= CFG_MAX_TMR) + { + return E_INVALID_ID; + } + if( (TmrIDVessel & (1<0 /* Check validity of parameter */ + if(tmrID >= CFG_MAX_TMR) + { + return E_INVALID_ID; + } + if((TmrIDVessel & (1<0 /* Check validity of parameter */ + if(tmrID >= CFG_MAX_TMR) + { + return E_INVALID_ID; + } + if( (TmrIDVessel & (1<0 /* Check validity of parameter */ + if(tmrID >= CFG_MAX_TMR) + { + *perr = E_INVALID_ID; + return 0; + } + if((TmrIDVessel & (1<0 /* Check validity of parameter */ + if(tmrID >= CFG_MAX_TMR) + { + return E_INVALID_ID; + } + if( (TmrIDVessel & (1<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 diff --git a/radio/src/CoOS/kernel/utility.c b/radio/src/CoOS/kernel/utility.c index 92f1c328d..520319c8d 100644 --- a/radio/src/CoOS/kernel/utility.c +++ b/radio/src/CoOS/kernel/utility.c @@ -1,86 +1,109 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -/*---------------------------- Include ---------------------------------------*/ -#include - -#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 */ +/** + ******************************************************************************* + * @file utility.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Utility management implementation code of CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +/*---------------------------- Include ---------------------------------------*/ +#include + +#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 */ diff --git a/radio/src/CoOS/kernel/utility.h b/radio/src/CoOS/kernel/utility.h index 07bbbd3f7..b35cfd825 100644 --- a/radio/src/CoOS/kernel/utility.h +++ b/radio/src/CoOS/kernel/utility.h @@ -1,39 +1,62 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 - +/** + ******************************************************************************* + * @file utility.h + * @version V1.1.6 + * @date 2014.05.23 + * @brief Utility function header file + * @details This file including some defines and declares related to utility + * function. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 + diff --git a/radio/src/CoOS/portable/GCC/port.c b/radio/src/CoOS/portable/GCC/port.c index 96640922c..90f950bbb 100644 --- a/radio/src/CoOS/portable/GCC/port.c +++ b/radio/src/CoOS/portable/GCC/port.c @@ -1,295 +1,332 @@ -/** - ******************************************************************************* - * @file prot.c - * @version V1.1.4 - * @date 2011.04.20 - * @brief Compiler adapter for CooCox CoOS kernel. - ******************************************************************************* - * @copy - * - * INTERNAL FILE,DON'T PUBLIC. - * - *

© COPYRIGHT 2010 CooCox

- ******************************************************************************* - */ - -/*---------------------------- Include ---------------------------------------*/ -#include "coocox.h" - - -//****************************************************************************** -// EQUATES -//****************************************************************************** -U32 NVIC_INT_CTRL = 0xE000ED04; // Interrupt control state register -U32 NVIC_PENDSVSET = 0x10000000; // Value to trigger PendSV exception -U32 INT_EXIT = 0xFFFFFFFC; - -//****************************************************************************** -// PUBLIC FUNCTIONS -//****************************************************************************** -extern U8 Inc8(volatile U8 *data) ; -extern U8 Dec8(volatile U8 *data) ; -extern void IRQ_ENABLE_RESTORE(void); -extern void IRQ_DISABLE_SAVE(void); -extern void SetEnvironment(OS_STK *pstk) __attribute__ ((naked)); -extern void SwitchContext(void) __attribute__ ((naked)); -extern void PendSV_Handler(void) __attribute__ ((naked)); - - -/** - ****************************************************************************** - * @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. - ****************************************************************************** - */ -U8 Inc8 (volatile U8 *data) -{ - register U8 result = 0; - - __asm volatile - ( - " PUSH {R1} \n" - " CPSID I \n" - " LDRB R1,[%1] \n" - " ADD R1,#1 \n" - " STRB R1,[%1] \n" - " CPSIE I \n" - " SUB R1,#0x1 \n" - " MOVS %0,R1 \n" - " POP {R1} \n" - :"=r"(result) - :"r"(data) - ); - return (result); - -} - - -/** - ****************************************************************************** - * @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. - ****************************************************************************** - */ -U8 Dec8 (volatile U8 *data) -{ - register U8 result = 0; - __asm volatile - ( - " PUSH {R1} \n" - " CPSID I \n" - " LDRB R1,[%1] \n" - " SUB R1,#1 \n" - " STRB R1,[%1] \n" - " CPSIE I \n" - " MOVS %0,R1 \n" - " POP {R1} \n" - :"=r"(result) - :"r"(data) - ); - return (result); -} - -/** - ****************************************************************************** - * @brief ENABLE Interrupt - * @param[in] None - * @param[out] None - * @retval None - * - * @par Description - * @details This function is called to ENABLE Interrupt. - ****************************************************************************** - */ -void IRQ_ENABLE_RESTORE(void) -{ - __asm volatile - ( - " CPSIE I \n" - ); - return; -} - -/** - ****************************************************************************** - * @brief Close Interrupt - * @param[in] None - * @param[out] None - * @retval None - * - * @par Description - * @details This function is called to close Interrupt. - ****************************************************************************** - */ -void IRQ_DISABLE_SAVE(void) -{ - __asm volatile - ( - " CPSID I \n" - ); - return; -} - - -/** - ****************************************************************************** - * @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. - ****************************************************************************** - */ -void SetEnvironment (OS_STK *pstk) -{ - __asm volatile - ( - " SUB R0,#28 \n" - " MSR PSP,R0 \n" - " BX LR \n" - ); - -} - - -/** - ****************************************************************************** - * @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 - ****************************************************************************** - */ -void SwitchContext(void) -{ - __asm volatile - ( - " LDR R3,=NVIC_INT_CTRL \n" - " LDR R3,[R3] \n" - " LDR R2,=NVIC_PENDSVSET \n" - " LDR R1,[R2] \n" - " STR R1, [R3] \n" - " BX LR \n" - ); - -} - - - -/** - ****************************************************************************** - * @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 -void PendSV_Handler(void) -{ - __asm volatile - ( - " LDR R3,=TCBRunning \n" - " LDR R1,[R3] \n" // R1 == running tcb - " LDR R2,=TCBNext \n" - " LDR R2,[R2] \n" // R2 == next tcb - - " CMP R1,R2 \n" - " BEQ exitPendSV \n" - " MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP ) - - " SUB R0,R0,#32 \n" - " STR R0,[R1] \n" // 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} \n" // Save old context (R4-R7) - " MOV R4,R8 \n" - " MOV R5,R9 \n" - " MOV R6,R10 \n" - " MOV R7,R11 \n" - " STMIA R0!,{R4-R7} \n" // Save old context (R8-R11) - - " popStk: \n" - " STR R2, [R3] \n" // TCBRunning = TCBNext; - " LDR R0, [R2] \n" // Get SP of task that be switch into. - - " ADD R0,R0,#16 \n" - " LDMIA R0!,{R4-R7} \n" // Restore new Context (R8-R11) - " MOV R8,R4 \n" - " MOV R9,R5 \n" - " MOV R10,R6 \n" - " MOV R11,R7 \n" - " SUB R0,R0,#32 \n" - " LDMIA R0!,{R4-R7} \n" // Restore new Context (R4-R7) - " ADD R0,R0,#16 \n" - " MSR PSP, R0 \n" // Mov new stack point to PSP - - " exitPendSV: \n" - " LDR R3,=OSSchedLock \n" - " MOV R0, #0x0 \n" - " STRB R0, [R3] \n" - - " LDR R3,=INT_EXIT \n" - " LDR R0, [R3] \n" - " BX R0 \n" // Exit interrupt - ); -} -#endif - -#if CFG_CHIP_TYPE == 1 -void PendSV_Handler(void) -{ -////////debug block ///////////////////////// - __asm volatile - ( - " LDR R3,=TCBRunning \n" - " LDR R1,[R3] \n" // R1 == running tcb - " LDR R2,=TCBNext \n" - " LDR R2,[R2] \n" // R2 == next tcb - - " CMP R1,R2 \n" - " BEQ exitPendSV \n" - - " MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP ) - " STMDB R0!,{R4-R11} \n" // Store r4-r11,r0 -= regCnt * 4,r0 is new stack - // top point (addr h->l r11,r10,...,r5,r4) - " STR R0,[R1] \n" // Save orig PSP - - " STR R2, [R3] \n" // TCBRunning = TCBNext; - " LDR R0, [R2] \n" // Get SP of task that be switch into. - " LDMIA R0!,{R4-R11} \n" // POP {R4-R11},R0 += regCnt * 4 - " MSR PSP, R0 \n" // Mov new stack point to PSP - - - " exitPendSV: \n" - " LDR R3,=OSSchedLock\n" - " MOVS R0, #0x0 \n" - " STRB R0, [R3] \n" - " ORR LR,LR,#0x04 \n" // Ensure exception return uses process stack - " BX LR \n" // Exit interrupt - ); -} -#endif - +/** + ******************************************************************************* + * @file prot.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief Compiler adapter for CooCox CoOS kernel. + ******************************************************************************* + * @copy + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +/*---------------------------- Include ---------------------------------------*/ +#include "coocox.h" + + +//****************************************************************************** +// EQUATES +//****************************************************************************** +U32 NVIC_INT_CTRL = 0xE000ED04; // Interrupt control state register +U32 NVIC_PENDSVSET = 0x10000000; // Value to trigger PendSV exception +U32 INT_EXIT = 0xFFFFFFFC; + +//****************************************************************************** +// PUBLIC FUNCTIONS +//****************************************************************************** +extern U8 Inc8(volatile U8 *data) ; +extern U8 Dec8(volatile U8 *data) ; +extern void IRQ_ENABLE_RESTORE(void); +extern void IRQ_DISABLE_SAVE(void); +extern void SetEnvironment(OS_STK *pstk) __attribute__ ((naked)); +extern void SwitchContext(void) __attribute__ ((naked)); +extern void PendSV_Handler(void) __attribute__ ((naked)); + + +/** + ****************************************************************************** + * @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. + ****************************************************************************** + */ +U8 Inc8 (volatile U8 *data) +{ + register U8 result = 0; + + __asm volatile + ( + " PUSH {R1} \n" + " CPSID I \n" + " LDRB R1,[%1] \n" + " ADD R1,#1 \n" + " STRB R1,[%1] \n" + " CPSIE I \n" + " SUB R1,#0x1 \n" + " MOVS %0,R1 \n" + " POP {R1} \n" + :"=r"(result) + :"r"(data) + ); + return (result); + +} + + +/** + ****************************************************************************** + * @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. + ****************************************************************************** + */ +U8 Dec8 (volatile U8 *data) +{ + register U8 result = 0; + __asm volatile + ( + " PUSH {R1} \n" + " CPSID I \n" + " LDRB R1,[%1] \n" + " SUB R1,#1 \n" + " STRB R1,[%1] \n" + " CPSIE I \n" + " MOVS %0,R1 \n" + " POP {R1} \n" + :"=r"(result) + :"r"(data) + ); + return (result); +} + +/** + ****************************************************************************** + * @brief ENABLE Interrupt + * @param[in] None + * @param[out] None + * @retval None + * + * @par Description + * @details This function is called to ENABLE Interrupt. + ****************************************************************************** + */ +void IRQ_ENABLE_RESTORE(void) +{ + __asm volatile + ( + " CPSIE I \n" + ); + return; +} + +/** + ****************************************************************************** + * @brief Close Interrupt + * @param[in] None + * @param[out] None + * @retval None + * + * @par Description + * @details This function is called to close Interrupt. + ****************************************************************************** + */ +void IRQ_DISABLE_SAVE(void) +{ + __asm volatile + ( + " CPSID I \n" + ); + return; +} + + +/** + ****************************************************************************** + * @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. + ****************************************************************************** + */ +void SetEnvironment (OS_STK *pstk) +{ + __asm volatile + ( +#if CFG_CHIP_TYPE == 3 + " SUB R0,#100 \n" +#else + " SUB R0,#28 \n" +#endif + " MSR PSP,R0 \n" + " BX LR \n" + ); + +} + + +/** + ****************************************************************************** + * @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 + ****************************************************************************** + */ +void SwitchContext(void) +{ + __asm volatile + ( + " LDR R3,=NVIC_INT_CTRL \n" + " LDR R3,[R3] \n" + " LDR R2,=NVIC_PENDSVSET \n" + " LDR R1,[R2] \n" + " STR R1, [R3] \n" + " BX LR \n" + ); + +} + + + +/** + ****************************************************************************** + * @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 +void PendSV_Handler(void) +{ + __asm volatile + ( + " LDR R3,=TCBRunning \n" + " LDR R1,[R3] \n" // R1 == running tcb + " LDR R2,=TCBNext \n" + " LDR R2,[R2] \n" // R2 == next tcb + + " CMP R1,R2 \n" + " BEQ exitPendSV \n" + " MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP ) + + " SUB R0,R0,#32 \n" + " STR R0,[R1] \n" // 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} \n" // Save old context (R4-R7) + " MOV R4,R8 \n" + " MOV R5,R9 \n" + " MOV R6,R10 \n" + " MOV R7,R11 \n" + " STMIA R0!,{R4-R7} \n" // Save old context (R8-R11) + + " popStk: \n" + " STR R2, [R3] \n" // TCBRunning = TCBNext; + " LDR R0, [R2] \n" // Get SP of task that be switch into. + + " ADD R0,R0,#16 \n" + " LDMIA R0!,{R4-R7} \n" // Restore new Context (R8-R11) + " MOV R8,R4 \n" + " MOV R9,R5 \n" + " MOV R10,R6 \n" + " MOV R11,R7 \n" + " SUB R0,R0,#32 \n" + " LDMIA R0!,{R4-R7} \n" // Restore new Context (R4-R7) + " ADD R0,R0,#16 \n" + " MSR PSP, R0 \n" // Mov new stack point to PSP + + " exitPendSV: \n" + " LDR R3,=OSSchedLock \n" + " MOV R0, #0x0 \n" + " STRB R0, [R3] \n" + + " LDR R3,=INT_EXIT \n" + " LDR R0, [R3] \n" + " BX R0 \n" // Exit interrupt + ); +} +#endif + +#if CFG_CHIP_TYPE == 1 || 3 == CFG_CHIP_TYPE +void PendSV_Handler(void) +{ +////////debug block ///////////////////////// + __asm volatile + ( + " LDR R3,=TCBRunning \n" + " LDR R1,[R3] \n" // R1 == running tcb + " LDR R2,=TCBNext \n" + " LDR R2,[R2] \n" // R2 == next tcb + + " CMP R1,R2 \n" + " BEQ exitPendSV \n" + + " MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP ) + " STMDB R0!,{R4-R11} \n" // Store r4-r11,r0 -= regCnt * 4,r0 is new stack + // top point (addr h->l r11,r10,...,r5,r4) +#if CFG_CHIP_TYPE == 3 + " VSTMDB R0!, {S16-S31} \n" // store remaining FPU registers +#endif // CFG_FPU_ENABLE + + " STR R0,[R1] \n" // Save orig PSP + + " STR R2, [R3] \n" // TCBRunning = TCBNext; + " LDR R0, [R2] \n" // Get SP of task that be switch into. + +#if CFG_CHIP_TYPE == 3 + " VLDMIA R0!, {S16-S31} \n" // load remaining FPU registers +#endif // CFG_FPU_ENABLE + + " LDMIA R0!,{R4-R11} \n" // POP {R4-R11},R0 += regCnt * 4 + " MSR PSP, R0 \n" // Mov new stack point to PSP + + " exitPendSV: \n" + " LDR R3,=OSSchedLock\n" + " MOVS R0, #0x0 \n" + " STRB R0, [R3] \n" + " ORR LR,LR,#0x04 \n" // Ensure exception return uses process stack +#if CFG_CHIP_TYPE == 3 + " LDR LR,=0xFFFFFFED \n" +#endif + " BX LR \n" // Exit interrupt + ); +} +#endif diff --git a/radio/src/CoOS/portable/OsArch.h b/radio/src/CoOS/portable/OsArch.h index b6e4529f2..4e20b52a3 100644 --- a/radio/src/CoOS/portable/OsArch.h +++ b/radio/src/CoOS/portable/OsArch.h @@ -1,50 +1,75 @@ -/** - ******************************************************************************* - * @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. - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - - -#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 +/** + ******************************************************************************* + * @file OsArch.h + * @version V1.1.6 + * @date 2014.05.23 + * @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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + + +#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 /* _CPU_H */ diff --git a/radio/src/CoOS/portable/arch.c b/radio/src/CoOS/portable/arch.c index 8ebe8b540..9ea864356 100644 --- a/radio/src/CoOS/portable/arch.c +++ b/radio/src/CoOS/portable/arch.c @@ -1,96 +1,126 @@ -/** - ******************************************************************************* - * @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 - * - *

© COPYRIGHT 2009 CooCox

- ******************************************************************************* - */ - -/*---------------------------- Include ---------------------------------------*/ -#include -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. - ******************************************************************************* - */ -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(); -} +/** + ******************************************************************************* + * @file arch.c + * @version V1.1.6 + * @date 2014.05.23 + * @brief This file provides InitTaskContext() and SysTick_Handler(). + ******************************************************************************* + * @copy + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + *

© COPYRIGHT 2014 CooCox

+ ******************************************************************************* + */ + +/*---------------------------- Include ---------------------------------------*/ +#include +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; +#if CFG_CHIP_TYPE == 3 + context = context - 18; +#endif + *(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; +#if CFG_CHIP_TYPE == 3 + context = context - 16; +#endif +// *(--context) = 0xfffffffd; /* LR */ + + 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. + ******************************************************************************* + */ +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(); +} diff --git a/radio/src/Makefile b/radio/src/Makefile index 0243a621b..f7d85322b 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -726,7 +726,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) ifeq ($(SPORT_FILE_LOG), YES) CPPDEFS += -DSPORT_FILE_LOG endif - INCDIRS += targets/sky9x CoOS/kernel CoOS/portable + INCDIRS += targets/sky9x CoOS CoOS/kernel CoOS/portable GUIGENERALSRC += gui/$(GUIDIRECTORY)/menu_general_hardware.cpp gui/$(GUIDIRECTORY)/menu_general_diagkeys.cpp gui/$(GUIDIRECTORY)/menu_general_diaganas.cpp BOARDSRC = main_arm.cpp targets/sky9x/board_sky9x.cpp EXTRABOARDSRC = targets/sky9x/lcd_driver.cpp @@ -840,7 +840,7 @@ ifeq ($(PCB), TARANIS) PPM_CENTER_ADJUSTABLE = YES DSM2 = PPM CPPDEFS += -DPCBTARANIS -DCPUARM -DCPUSTM32 -DVIRTUALINPUTS -DLUAINPUTS -DXCURVES -DEEPROM_VARIANT=0 -DAUDIO -DPXX - INCDIRS += targets/taranis CoOS/kernel CoOS/portable + INCDIRS += targets/taranis CoOS CoOS/kernel CoOS/portable ifeq ($(PCBREV), REV9E) CPPDEFS += -DSTM32F40_41xxx EXTRAINCDIRS += targets/taranis/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include targets/taranis/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/CMSIS/Include targets/taranis/STM32F4xx_DSP_StdPeriph_Lib_V1.4.0/Libraries/STM32F4xx_StdPeriph_Driver/inc