📄 os_core.c
字号:
#include <string.h>
#include "OS_DEF.H"
OS_MSG *OSMsgHd;
OS_STK *pSchedStk;
INT8U OSRunning;
INT8U OSEvtCode;
INT8U OSIntNesting; //-----
INT8U OSNoUse;
// For System runing and user program runing time Check
INT32U OSSumTick;
INT32U OSUseTick;
INT32U OSCurTime; // Use for system time
INT8U GetTskPrio(INT8U nTaskID);
INT8U RegSemID(void (*TskPtr)(INT16U, INT32U), SEMPROC *);
INT8U RegMsgID(void (*TskPtr)(INT16U, INT32U), MSGPROC *);
OS_TCB *GetActive(INT8U nTaskID);
/********************************************************************************************************
* INITIALIZATION
*
* Description: This function is used to create all events to system event array
*
* Arguments : INT8U nEventID - the Message ID
* OS_MSG pMsgPtr - one Message pointer
*
* Returns : INT8U Error code
*********************************************************************************************************
*/
INT8U CreateEvt(INT8U nEventID, void (*DefProc)(INT16U, INT32U), OS_MSG *pMsgPtr)
{
OS_MSG *pCurMsg, *pParent;
if (nEventID == 0 || pMsgPtr == NULL)
return OS_ERR_CODE;
pMsgPtr->OSMsgID = nEventID;
pMsgPtr->FstProc = NULL;
pMsgPtr->DefProc = DefProc;
pMsgPtr->pNextMsg = NULL;
pCurMsg = OSMsgHd, pParent = NULL;
while (pCurMsg != NULL) {
pParent = pCurMsg;
pCurMsg = pCurMsg->pNextMsg;
}
if (pParent == NULL) OSMsgHd = pMsgPtr;
else pParent->pNextMsg = pMsgPtr;
return OS_NO_ERR;
}
/********************************************************************************************************
* CREATE A TASK
*
* Description: This function is used to have EventOS manage the execution of a task. Tasks can either
* be created prior to the start of multitasking or by a running task. A task cannot be
* created by an ISR.
*
* Arguments : task is a pointer to the task's code
* pCurTCB - Gave one task control block, it has list datas:
* pCurTCB.OSTCBId = nID; is the task's ID (0..65535)
* pCurTCB.pStkPtr = pStkTop; pointer to the task's top
* pCurTCB.nStkSize = nStkSize; size of the stack in number of elements.
* pCurTCB.pParam = pData; a pointer to an optional data area which can be used to pass parameters
* pCurTCB.nTskPrio = nPrio; is the task's priority.
* pCurTCB.pTskName = pTskName;
*
* Returns : OS_NO_ERR if the function was successful.
* OS_PRIO_EXIT if the task priority already exist
* (each task MUST have a unique priority).
* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. > OS_LOWEST_PRIO)
*********************************************************************************************************
*/
INT8U CreateTask(INT8U nTaskID, void (*task)(INT16U, INT32U), INT8U nTskPrio, void *TskName, OS_TCB *pCurTcb)
{
OS_TCB *pTmpTcb, *pParent;
if (task == NULL || pCurTcb == NULL)
return OS_PARM_INVALID;
pTmpTcb = OSMsgHd->FstProc, pParent = NULL;
while (pTmpTcb != NULL) {
if (pTmpTcb->nTskPrio > pCurTcb->nTskPrio) break;
else pParent = pTmpTcb, pTmpTcb = (OS_TCB *)pTmpTcb->pTcbNext;
}
pCurTcb->pTskProg = task;
pCurTcb->TaskID = nTaskID;
pCurTcb->bStatus = OS_TSK_READY; /* Task is ready to run */
pCurTcb->nTskPrio = nTskPrio;
pCurTcb->nDelayCnt = 0;
pCurTcb->pTskName = TskName;
pCurTcb->pTcbNext = NULL; /* Init next pointer */
OS_ENTER_CRITICAL();
if (pParent == NULL) {
OSMsgHd->FstProc = pCurTcb;
} else {
pParent->pTcbNext = pCurTcb;
pCurTcb->pTcbNext = pTmpTcb;
}
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
/********************************************************************************************************
* CREATE SEMPHERE
*
* Description: This function is used to create one semphere for one process
*
* Arguments : INT8U nEventID - the Message ID
* SEMPROC pTheSemP - one Semphere struct pointer
*
* Returns : INT8U Error code
*********************************************************************************************************
*/
INT8U WaitForSem(INT8U nTaskID, INT8U nEventID, INT16U nMaxDelay, OS_STK *pStkPtr, INT16U nStkSize, SEMPROC *pTheSemP)
{
OS_MSG *pCurMsg;
SEMPROC *pTmpSemP, *pProSemP = NULL;
OS_STK *pStkTop;
INT8U nTskPrio;
if (nEventID < 2 || nEventID > 15 || pTheSemP == NULL)
return OS_ERR_CODE;
pCurMsg = OSMsgHd, pProSemP = NULL;
while (pCurMsg != NULL) {
if (nEventID == pCurMsg->OSMsgID) break;
pCurMsg = pCurMsg->pNextMsg;
if (pCurMsg->OSMsgID >= 16) pCurMsg = NULL;
}
if (pCurMsg == NULL) return OS_ERR_NOEVENT;
nTskPrio = GetTskPrio(nTaskID);
if (nTskPrio == 0) return OS_ERR_CODE;
pTheSemP->nTskPrio = nTskPrio;
pTmpSemP = (SEMPROC *)pCurMsg->FstProc;
while (pTmpSemP != NULL) {
if (pTmpSemP->nTskPrio > nTskPrio) {
break;
} else {
pProSemP = pTmpSemP;
pTmpSemP = pTmpSemP->pNextSemP;
}
}
memset(pStkPtr, 0, nStkSize*sizeof(OS_STK));
#if OS_STK_GROWTH == 1
pStkTop = pStkPtr;
#else
pStkTop = pStkPtr + nStkSize - 1;
#endif
pTheSemP->pStkPtr = pStkTop;
pTheSemP->nStkSize = nStkSize;
pTheSemP->nDelayCnt = nMaxDelay;
pTheSemP->pOS_Tcb = GetActive(pTheSemP->TaskID);
pTheSemP->pOS_Tcb->bStatus |= OS_TSK_SEM;
pTheSemP->pNextSemP = NULL;
OS_ENTER_CRITICAL();
if (pProSemP != NULL) {
pProSemP->pNextSemP = pTheSemP;
pTheSemP->pNextSemP = pTmpSemP;
} else {
pCurMsg->FstProc = (void *)pTheSemP;
}
OS_EXIT_CRITICAL();
pSchedStk = pStkTop;
return OSWaitSemIn(pStkTop, nStkSize);
}
/********************************************************************************************************
* CREATE MESSAGE STRUCT
*
* Description: This function is used to create one message struct for one event
*
* Arguments : INT8U nEventID - the Message ID
* MSGPROC pMsgPtr - one Message struct pointer
*
* Returns : INT8U Error code
*********************************************************************************************************
*/
INT8U CteateMsg(INT8U nTaskID, INT8U nEventID, void (*FuncProc)(INT16U, INT32U), MSGPROC *pTheMsgP)
{
OS_MSG *pCurMsg;
MSGPROC *pTmpMsgP, *pProMsgP;
INT8U nTskPrio;
if (nEventID < 16 || pTheMsgP == NULL)
return OS_ERR_CODE;
pCurMsg = OSMsgHd, pProMsgP = NULL;
while (pCurMsg != NULL) {
if (nEventID == pCurMsg->OSMsgID) break;
pCurMsg = pCurMsg->pNextMsg;
}
if (pCurMsg == NULL) return OS_ERR_NOEVENT;
nTskPrio = GetTskPrio(nTaskID);
if (nTskPrio == 0) return OS_ERR_CODE;
pTheMsgP->nTskPrio = nTskPrio;
pTmpMsgP = (MSGPROC *)pCurMsg->FstProc;
while (pTmpMsgP != NULL) {
if (pTmpMsgP->nTskPrio > nTskPrio) {
break;
} else {
pProMsgP = pTmpMsgP;
pTmpMsgP = pTmpMsgP->pNextMsgP;
}
}
pTheMsgP->pFuncProc = FuncProc;
pTheMsgP->pNextMsgP = NULL;
pTheMsgP->bStatus = OS_TSK_READY;
pTheMsgP->nDelayCnt = 0;
OS_ENTER_CRITICAL();
if (pProMsgP != NULL) {
pProMsgP->pNextMsgP = pTheMsgP;
pTheMsgP->pNextMsgP = pTmpMsgP;
} else {
pCurMsg->FstProc = pTheMsgP;
}
OS_EXIT_CRITICAL();
return OS_NO_ERR;
}
/********************************************************************************************************
* GET TASK ID
*
* Description: This function is used to Get the task id code
*
* Arguments : void (*TskPtr)() - is task Pointer
*
* Returns : the task prio
*********************************************************************************************************
*/
INT8U GetTaskID(void (*TskPtr)(INT16U, INT32U))
{
OS_TCB *pTmpTcb;
pTmpTcb = OSMsgHd->FstProc;
while (pTmpTcb != NULL) {
if (pTmpTcb->pTskProg == TskPtr) break;
else pTmpTcb = (OS_TCB *)pTmpTcb->pTcbNext;
}
if (pTmpTcb != NULL) {
return pTmpTcb->TaskID;
} else {
return 0;
}
}
/********************************************************************************************************
* GET TASK PRIO
*
* Description: This function is used to Get the task prio as Task ID
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -