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

📄 os_event.c

📁 EventOS操作系统核心源码
💻 C
字号:
#include    <string.h>
#include    "OS_DEF.H"

#define OS_EVT_MAX_NUM           0x10
#define OS_EVT_STK_SIZE           400

OS_EVENT    OSEventAry[OS_EVT_MAX_NUM];
INT8U       OSnEvtTop;
INT8U       OSnEvtBut;
INT32U      OSOldTime;          // Use for save the checked time

extern  OS_MSG  *OSMsgHd;
extern  OS_STK  *pSchedStk;
extern  INT8U    OSEvtCode;
extern  INT32U   OSSumTick;
extern  INT32U   OSUseTick;
extern  INT32U   OSCurTime;   // Use for system time

extern  void    OSInit(void);
extern  INT8U   GetTaskSta(INT8U nTaskID);
extern  void    SetActive(INT8U nTaskID);
extern  void    OSTaskIdleHook(void);

void RunTask(OS_TCB *pTaskPnt, INT32U pParams);
void InVoke(MSGPROC *pMsgCurP, INT16U nParamL, INT32U pParamH);
void DefProc(void (*pSysProc)(INT16U, INT32U), INT16U nParamL, INT32U pParamH);
void Scheduler(SEMPROC *pSemCurP, INT16U nParamL, INT32U pParamH);
void TskInvoke(OS_TCB *pTskPnt, INT16U nParamL, INT32U pParamH);
void MsgInvoke(MSGPROC *pMsgCurP, INT16U nParamL, INT32U pParamH);
void DefInvoke(void (*pFuncProc)(INT16U, INT32U), INT16U nParamL, INT32U pParamH);


/*****************************************************************************************************
*                            System Event Memagement
* FUNCTION: PostEvent(INT8U OSEventID, INT16U nParamL, INT32U lParamM)
*           GetEvent(INT16U *pParamL, INT32U *pParamM)
*
* Description: Post one or Get one Event to System Event Stack
*
* Arguments  : INT8U   OSEventID - Event ID Code
*              INT16U  nParamL   - Event Short Code
*              INT32U  lParamM   - Event Large Code
*
* Returns   (1): == OS_NO_ERR : else ERROR
*           (2): == OS_NO_EVENT : else Event Code
*---------------------------------------------------------------------------------------------
*/
INT8U PutEvent(INT8U OSEventID, INT8U nTaskID, INT16U nParamL, INT32U pParamM)
{
    OS_MSG *pMsgPtr;
    INT8U   nCurPtr;
    
    pMsgPtr = OSMsgHd;
    while (pMsgPtr != NULL) {
        if (pMsgPtr->OSMsgID == OSEventID)
            break;
        pMsgPtr = pMsgPtr->pNextMsg;
    }
    if (pMsgPtr == NULL)
        return OS_INVALID_ID;
    OS_ENTER_CRITICAL();
    nCurPtr = (OSnEvtTop + 1) % OS_EVT_MAX_NUM;
    if (nCurPtr == OSnEvtBut) {
        OS_EXIT_CRITICAL();
        return OS_EVT_BUFFULL;
    }
    OSEventAry[nCurPtr].OSEventID = OSEventID;
    OSEventAry[nCurPtr].nTaskID = nTaskID;
    OSEventAry[nCurPtr].ParamL = nParamL;
    OSEventAry[nCurPtr].ParamM = pParamM;
    OSnEvtTop = nCurPtr;
    OS_EXIT_CRITICAL();
    return OS_NO_ERR;
}

INT8U GetEvent(INT8U *pTaskID, INT16U *pParamL, INT32U *pParamM)
{
    INT8U   nCurPtr;
    
    if (OSnEvtTop == OSnEvtBut) return OS_NO_EVENT;
    OS_ENTER_CRITICAL();
    OSnEvtBut++, OSnEvtBut %= OS_EVT_MAX_NUM;
    nCurPtr = OSnEvtBut;
    *pTaskID = OSEventAry[nCurPtr].nTaskID;
    *pParamL = OSEventAry[nCurPtr].ParamL;
    *pParamM = OSEventAry[nCurPtr].ParamM;
    nCurPtr  = OSEventAry[nCurPtr].OSEventID;
    OS_EXIT_CRITICAL();
    return nCurPtr;
}
/*****************************************************************************************************
*                                              IDLE TASK
*
* Description: This task is internal to EventOS and executes whenever no other higher priority tasks
*              executes because they are ALL waiting for event(s) to occur.
*
* Arguments  : none
* Returns    : none
*
* Note(s)    : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be
*                 enabled for at least a few instructions.  On some processors (ex. Philips XA), enabling
*                 and then disabling interrupts didn't allow the processor enough time to have interrupts
*                 enabled before they were disabled again.  uC/OS-II would thus never recognize
*                 interrupts.
*              2) This hook has been added to allow you to do such things as STOP the CPU to conserve 
*                 power.
*       事件类型:
         1、发给所有可执行任务:nTaskID = 0
         2、发给当前活动任务:  nTaskID = 0x8000
         3、发给指定任务:      nTaskID = pMsgCurp->nTaskID
*       任务状态:
         1、当前任务为活动状态:  xxx0,0000
         2、当前任务为非活动状态:xxx1,0000
         3、当前任务还未启动:    1xxx,0000
******************************************************************************************************
*/
int main(void)
{
    INT8U     nTaskID, nTskSta;
    INT16U    nParamL;
    INT32U    pParamH;    
    OS_MSG   *pCurMsg;
    OS_TCB   *pTaskPnt;
    MSGPROC  *pMsgCurP;
    SEMPROC  *pSemCurP;

    OSnEvtTop = 0, OSnEvtBut = 0;
    OSInit();                    // EventOS系统初始化
    for (;;) {
        OSEvtCode = GetEvent(&nTaskID, &nParamL, &pParamH);
        if (OSEvtCode > 0) {
            pCurMsg = OSMsgHd;
            while (pCurMsg != NULL) {
                if (pCurMsg->OSMsgID == OSEvtCode) break;
                pCurMsg = pCurMsg->pNextMsg;
            }
            if (pCurMsg != NULL) {
                if (OSEvtCode == 1) {               // 启动任务
                    pTaskPnt = pCurMsg->FstProc;
                    while (pTaskPnt != NULL) {
                        if (nTaskID == pTaskPnt->TaskID &&
                           (pTaskPnt->bStatus&OS_TSK_SEM) == 0) {
                            RunTask(pTaskPnt, pParamH);
                            break;
                        }
                        pTaskPnt = pTaskPnt->pTcbNext;
                    }
                } else if (OSEvtCode < 16) {
                    pSemCurP = pCurMsg->FstProc;
                    while (pSemCurP != NULL) {
                        if (nTaskID == 0 || nTaskID == pSemCurP->TaskID)
                            Scheduler(pSemCurP, nParamL, pParamH);
                        pSemCurP = pSemCurP->pNextSemP;
                    }
                } else {
                    pMsgCurP = pCurMsg->FstProc;
                    while (pMsgCurP != NULL) {
                        nTskSta = 0;
                        if (pMsgCurP->bStatus & OS_TSK_READY) {
                            if (nTaskID == pMsgCurP->TaskID) nTskSta = nTaskID;       //指定
                            else if ((nTaskID&0x7F) == 0) nTskSta = pMsgCurP->TaskID; //通用|活动
                        }
                        if (nTskSta != 0) {
                            nTskSta = GetTaskSta(nTskSta);  // 缺省为给活动任务的事件有效
                            if (nTaskID & OS_TSK_ACTIVE) {  // 仅对活动任务
                                if (nTskSta & OS_TSK_ACTIVE) nTskSta = 0;  
                            } else {                        // 对非活动任务,必须为有效的任务
                                if ((nTskSta & OS_TSK_READY) == 0) nTskSta = 0; 
                            }
                            if (nTskSta == 0) InVoke(pMsgCurP, nParamL, pParamH);
                        }
                        if (OSEvtCode == 0) pMsgCurP = NULL;
                        else pMsgCurP = pMsgCurP->pNextMsgP;
                    }
                    if (OSEvtCode > 0 && pCurMsg->DefProc != NULL)
                        DefProc(pCurMsg->DefProc, nParamL, pParamH);
                }
            }
            if (OSEvtCode == 0) {
                if (OSCurTime <  OSOldTime) OSCurTime += 100000;
                OSUseTick += OSCurTime - OSOldTime;
            }
        }
        
        OS_ENTER_CRITICAL();
        if (OSCurTime <  OSOldTime) OSCurTime += 100000;
        OSSumTick += OSCurTime - OSOldTime;
        OSOldTime = OSCurTime;
        if (OSSumTick > 100000)
            OSSumTick = 0, OSUseTick = 0;
        OS_EXIT_CRITICAL();
      #if OS_CPU_HOOKS_EN
        OSTaskIdleHook();      /* Call user definable HOOK  */
      #endif
    }
}
/*****************************************************************************************************
*                                      INVOKE
*
* Description: This Function is internal to EventOS and executes current Message process 
*              executes because the event that is waiting for is occured.
*
* Arguments  : none
* Returns    : none
*
* Note(s)    : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be
*                 enabled for at least a few instructions.  On some processors (ex. Philips XA), enabling
*                 and then disabling interrupts didn't allow the processor enough time to have interrupts
*                 enabled before they were disabled again.  uC/OS-II would thus never recognize
*                 interrupts.
*              2) This hook has been added to allow you to do such things as STOP the CPU to conserve 
*                 power.
------------------------------------------------------------------------------------------------------
*/
void RunTask(OS_TCB *pTaskPnt, INT32U pParams)
{
    pSchedStk = OSEvtInvokeInit((void *)TskInvoke, (void *)pTaskPnt, 0, pParams);
    pTaskPnt->bStatus = OS_TSK_ACTIVE;
    pTaskPnt->nDelayCnt = OS_SYS_MAXDLY;
    OSEvtSched();
}
void TskInvoke(OS_TCB *pTskPnt, INT16U nParamL, INT32U pParamH)
{
    (*pTskPnt->pTskProg)(nParamL, pParamH);
    pTskPnt->bStatus = OS_TSK_OVER;
    OSRtnSched();
}

void InVoke(MSGPROC *pMsgCurP, INT16U nParamL, INT32U pParamH)
{
    pSchedStk = OSEvtInvokeInit((void *)MsgInvoke, (void *)pMsgCurP, nParamL, pParamH);
    SetActive(pMsgCurP->TaskID);           // Set current task as Active
    pMsgCurP->bStatus = OS_TSK_RUN;
    pMsgCurP->nDelayCnt = OS_SYS_MAXDLY;
    OSEvtSched();
}
void MsgInvoke(MSGPROC *pMsgCurP, INT16U nParamL, INT32U pParamH)
{
    (*pMsgCurP->pFuncProc)(nParamL, pParamH);
    pMsgCurP->bStatus = OS_TSK_READY;
    OSRtnSched();
}

void DefProc(void (*pSysProc)(INT16U, INT32U), INT16U nParamL, INT32U pParamH)
{
    pSchedStk = OSEvtInvokeInit((void *)DefInvoke, (void *)pSysProc, nParamL, pParamH);
    OSEvtSched();
}
void DefInvoke(void (*pSysProc)(INT16U, INT32U), INT16U nParamL, INT32U pParamH)
{
    (*pSysProc)(nParamL, pParamH);

    OSRtnSched();
}

void Scheduler(SEMPROC *pSemCurP, INT16U nParamL, INT32U pParamH)
{
    pSchedStk = pSemCurP->pStkPtr;
    pSemCurP->pOS_Tcb->bStatus = OS_TSK_RUN;    
    SetActive(pSemCurP->TaskID);           // Set current task as Active
    OSSemSched(nParamL, pParamH);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -