⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_core.c

📁 EventOS操作系统核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -