📄 os_event.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 + -