?? os_tmr.c
字號:
OSTmrSem = OSSemCreate(1);
OSTmrSemSignal = OSSemCreate(0);
#if OS_EVENT_NAME_SIZE > 18
OSEventNameSet(OSTmrSem, (INT8U *)"uC/OS-II TmrLock", &err);/* Assign names to semaphores */
#else
#if OS_EVENT_NAME_SIZE > 10
OSEventNameSet(OSTmrSem, (INT8U *)"OS-TmrLock", &err);
#endif
#endif
#if OS_EVENT_NAME_SIZE > 18
OSEventNameSet(OSTmrSemSignal, (INT8U *)"uC/OS-II TmrSignal", &err);
#else
#if OS_EVENT_NAME_SIZE > 10
OSEventNameSet(OSTmrSemSignal, (INT8U *)"OS-TmrSig", &err);
#endif
#endif
OSTmr_InitTask();
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* INITIALIZE THE TIMER MANAGEMENT TASK
*
* Description: This function is called by OSTmrInit() to create the timer management task.
*
* Arguments : none
*
* Returns : none
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
static void OSTmr_InitTask (void)
{
#if OS_TASK_NAME_SIZE > 6
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0
#if OS_STK_GROWTH == 1
(void)OSTaskCreateExt(OSTmr_Task,
(void *)0, /* No arguments passed to OSTmrTask() */
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Top-Of-Stack */
OS_TASK_TMR_PRIO,
OS_TASK_TMR_ID,
&OSTmrTaskStk[0], /* Set Bottom-Of-Stack */
OS_TASK_TMR_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */
#else
(void)OSTaskCreateExt(OSTmr_Task,
(void *)0, /* No arguments passed to OSTmrTask() */
&OSTmrTaskStk[0], /* Set Top-Of-Stack */
OS_TASK_TMR_PRIO,
OS_TASK_TMR_ID,
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1], /* Set Bottom-Of-Stack */
OS_TASK_TMR_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */
#endif
#else
#if OS_STK_GROWTH == 1
(void)OSTaskCreate(OSTmr_Task,
(void *)0,
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1],
OS_TASK_TMR_PRIO);
#else
(void)OSTaskCreate(OSTmr_Task,
(void *)0,
&OSTmrTaskStk[0],
OS_TASK_TMR_PRIO);
#endif
#endif
#if OS_TASK_NAME_SIZE > 12
OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"uC/OS-II Tmr", &err);
#else
#if OS_TASK_NAME_SIZE > 6
OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)"OS-Tmr", &err);
#endif
#endif
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* INSERT A TIMER INTO THE TIMER WHEEL
*
* Description: This function is called to insert the timer into the timer wheel. The timer is always inserted at the
* beginning of the list.
*
* Arguments : ptmr Is a pointer to the timer to insert.
*
* type Is either:
* OS_TMR_LINK_PERIODIC Means to re-insert the timer after a period expired
* OS_TMR_LINK_DLY Means to insert the timer the first time
*
* Returns : none
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
static void OSTmr_Link (OS_TMR *ptmr, INT8U type)
{
OS_TMR *ptmr1;
OS_TMR_WHEEL *pspoke;
INT16U spoke;
ptmr->OSTmrState = OS_TMR_STATE_RUNNING;
if (type == OS_TMR_LINK_PERIODIC) { /* Determine when timer will expire */
ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
} else {
if (ptmr->OSTmrDly == 0) {
ptmr->OSTmrMatch = ptmr->OSTmrPeriod + OSTmrTime;
} else {
ptmr->OSTmrMatch = ptmr->OSTmrDly + OSTmrTime;
}
}
spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
pspoke = &OSTmrWheelTbl[spoke];
if (pspoke->OSTmrFirst == (OS_TMR *)0) { /* Link into timer wheel */
pspoke->OSTmrFirst = ptmr;
ptmr->OSTmrNext = (OS_TMR *)0;
pspoke->OSTmrEntries = 1;
} else {
ptmr1 = pspoke->OSTmrFirst; /* Point to first timer in the spoke */
pspoke->OSTmrFirst = ptmr;
ptmr->OSTmrNext = (void *)ptmr1;
ptmr1->OSTmrPrev = (void *)ptmr;
pspoke->OSTmrEntries++;
}
ptmr->OSTmrPrev = (void *)0; /* Timer always inserted as first node in list */
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* REMOVE A TIMER FROM THE TIMER WHEEL
*
* Description: This function is called to remove the timer from the timer wheel.
*
* Arguments : ptmr Is a pointer to the timer to remove.
*
* Returns : none
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
static void OSTmr_Unlink (OS_TMR *ptmr)
{
OS_TMR *ptmr1;
OS_TMR *ptmr2;
OS_TMR_WHEEL *pspoke;
INT16U spoke;
spoke = (INT16U)(ptmr->OSTmrMatch % OS_TMR_CFG_WHEEL_SIZE);
pspoke = &OSTmrWheelTbl[spoke];
if (pspoke->OSTmrFirst == ptmr) { /* See if timer to remove is at the beginning of list */
ptmr1 = (OS_TMR *)ptmr->OSTmrNext;
pspoke->OSTmrFirst = (OS_TMR *)ptmr1;
if (ptmr1 != (OS_TMR *)0) {
ptmr1->OSTmrPrev = (void *)0;
}
} else {
ptmr1 = (OS_TMR *)ptmr->OSTmrPrev; /* Remove timer from somewhere in the list */
ptmr2 = (OS_TMR *)ptmr->OSTmrNext;
ptmr1->OSTmrNext = ptmr2;
if (ptmr2 != (OS_TMR *)0) {
ptmr2->OSTmrPrev = (void *)ptmr1;
}
}
ptmr->OSTmrState = OS_TMR_STATE_STOPPED;
ptmr->OSTmrNext = (void *)0;
ptmr->OSTmrPrev = (void *)0;
pspoke->OSTmrEntries--;
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* TIMER MANAGER DATA STRUCTURE LOCKING MECHANISM
*
* Description: These functions are used to gain exclusive access to timer management data structures.
*
* Arguments : none
*
* Returns : none
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
static void OSTmr_Lock (void)
{
INT8U err;
OSSemPend(OSTmrSem, 0, &err);
(void)err;
}
#endif
#if OS_TMR_EN > 0
static void OSTmr_Unlock (void)
{
(void)OSSemPost(OSTmrSem);
}
#endif
/*$PAGE*/
/*
************************************************************************************************************************
* TIMER MANAGEMENT TASK
*
* Description: This task is created by OSTmrInit().
*
* Arguments : none
*
* Returns : none
************************************************************************************************************************
*/
#if OS_TMR_EN > 0
static void OSTmr_Task (void *p_arg)
{
INT8U err;
OS_TMR *ptmr;
OS_TMR *ptmr_next;
OS_TMR_CALLBACK pfnct;
OS_TMR_WHEEL *pspoke;
INT16U spoke;
(void)p_arg; /* Not using 'p_arg', prevent compiler warning */
for (;;) {
OSSemPend(OSTmrSemSignal, 0, &err); /* Wait for signal indicating time to update timers */
OSTmr_Lock();
OSTmrTime++; /* Increment the current time */
spoke = (INT16U)(OSTmrTime % OS_TMR_CFG_WHEEL_SIZE); /* Position on current timer wheel entry */
pspoke = &OSTmrWheelTbl[spoke];
ptmr = pspoke->OSTmrFirst;
while (ptmr != (OS_TMR *)0) {
ptmr_next = (OS_TMR *)ptmr->OSTmrNext; /* Point to next timer to update because current ... */
/* ... timer could get unlinked from the wheel. */
if (OSTmrTime == ptmr->OSTmrMatch) { /* Process each timer that expires */
pfnct = ptmr->OSTmrCallback; /* Execute callback function if available */
if (pfnct != (OS_TMR_CALLBACK)0) {
(*pfnct)((void *)ptmr, ptmr->OSTmrCallbackArg);
}
OSTmr_Unlink(ptmr); /* Remove from current wheel spoke */
if (ptmr->OSTmrOpt == OS_TMR_OPT_PERIODIC) {
OSTmr_Link(ptmr, OS_TMR_LINK_PERIODIC); /* Recalculate new position of timer in wheel */
} else {
ptmr->OSTmrState = OS_TMR_STATE_COMPLETED; /* Indicate that the timer has completed */
}
}
ptmr = ptmr_next;
}
OSTmr_Unlock();
}
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -