📄 net_tmr.c
字号:
* called only by appropriate network-operating system port function(s).
*
* Note(s) : (2) NetTmr_TaskHandler() blocked until network initialization completes.
*
* (3) NetTmr_TaskHandler() blocks ALL other network protocol tasks by pending on & acquiring
* the global network lock (see 'net.h Note #2').
*
* (4) (a) NetTmr_TaskHandler() handles all valid timers in Timer Task List, up to the first
* corrupted timer in the Timer Task List, if any.
*
* (b) #### If ANY timer(s) in Timer Task List are corrupted :
*
* (1) Discard/unlink current Timer Task timer.
* (A) Consequently, any remaining valid timers in Timer Task List are :
* (1) Unlinked from Timer Task List, ...
* (2) NOT handled.
*
* (2) Timer Task is aborted.
*
* (5) Since NetTmr_TaskHandler() is asynchronous to NetTmr_Free() [via execution of certain
* timer expiration functions], the Timer Task List timer ('NetTmr_TaskListPtr') MUST be
* coordinated with NetTmr_Free() to avoid Timer Task List corruption :
*
* (a) (1) Timer Task List timer is typically advanced by NetTmr_TaskHandler() to the next
* timer in the Timer Task List.
*
* (2) However, whenever the Timer Task List timer is freed by an asynchronous timer
* expiration function, the Timer Task List timer MUST be advanced to the next
* valid & available timer in the Timer Task List.
*
* See also 'NetTmr_Free() Note #3a'.
*
* (b) Timer Task List timer MUST be cleared after handling the Timer Task List.
*
* (1) However, Timer Task List timer is implicitly cleared after handling the
* Timer Task List.
*
* See also 'NetTmr_DiscardTaskTmr() Note #1c'.
*
* (6) Since NetTmr_TaskHandler() is asynchronous to ANY timer Get/Set, one additional tick
* is added to each timer's count-down so that the requested timeout is ALWAYS satisfied.
* This additional tick is added by NOT checking for zero ticks after decrementing; any
* timer that expires is recognized at the next tick.
*
* (7) When a network timer expires, the timer SHOULD be freed PRIOR to executing the timer
* expiration function. This ensures that at least one timer is available if the timer
* expiration function requires a timer.
*********************************************************************************************************
*/
/*$PAGE*/
void NetTmr_TaskHandler (void)
{
#if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \
(NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
CPU_BOOLEAN used;
#endif
NET_TMR *ptmr;
void *obj;
CPU_FNCT_PTR fnct;
NET_ERR err;
if (Net_InitDone != DEF_YES) { /* If init NOT complete, ... */
NetOS_InitWait(&err); /* ... wait on net init (see Note #2). */
if (err != NET_OS_ERR_NONE) {
return;
}
}
NetOS_Lock(&err); /* Acquire net lock (see Note #3). */
if (err != NET_OS_ERR_NONE) {
return;
}
NetTmr_TaskListPtr = NetTmr_TaskListHead; /* Start @ Tmr Task List head. */
while (NetTmr_TaskListPtr != (NET_TMR *)0) { /* Handle Tmr Task List tmrs (see Note #4a). */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* -------------- VALIDATE TYPE --------------- */
if (NetTmr_TaskListPtr->Type != NET_TMR_TYPE_TMR) { /* If tmr type invalid; ... */
NetTmr_DiscardTaskTmr(); /* ... discard tmr task tmr (see Note #4b1) ... */
NET_CTR_ERR_INC(NetTmr_ErrInvalidTypeCtr);
NetOS_Unlock();
return; /* ... & abort tmr task (see Note #4b2). */
}
/* ------------ VALIDATE TMR USED ------------- */
used = DEF_BIT_IS_SET(NetTmr_TaskListPtr->Flags, NET_TMR_FLAG_USED);
if (used != DEF_YES) { /* If tmr NOT used, ... */
NetTmr_DiscardTaskTmr(); /* ... discard tmr task tmr (see Note #4b1) ... */
NET_CTR_ERR_INC(NetTmr_ErrNotUsedCtr);
NetOS_Unlock();
return; /* ... & abort tmr task (see Note #4b2). */
}
#endif
ptmr = (NET_TMR *)NetTmr_TaskListPtr;
NetTmr_TaskListPtr = (NET_TMR *)NetTmr_TaskListPtr->NextPtr; /* Set next tmr to update (see Note #5a1). */
if (ptmr->TmrVal > 0) { /* If tmr val > 0, dec tmr val (see Note #6). */
ptmr->TmrVal--;
} else { /* Else tmr expired; ... */
obj = ptmr->Obj; /* Get obj for ... */
fnct = ptmr->Fnct; /* ... tmr expiration fnct. */
NetTmr_Free(ptmr); /* ... free tmr (see Note #7); ... */
if (fnct != (CPU_FNCT_PTR)0) { /* ... & if avail, ... */
fnct(obj); /* ... exec tmr expiration fnct. */
}
}
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* Clr tmr task ptr (see Note #5b1). */
NetTmr_TaskListPtr = (NET_TMR *)0;
#endif
NetOS_Unlock(); /* Release net lock. */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_Get()
*
* Description : (1) Allocate & initialize a network timer :
*
* (a) Get timer
* (b) Validate timer
* (c) Initialize timer
* (d) Insert timer at head of Timer Task List
* (e) Update timer pool statistics
* (f) Return pointer to timer
* OR
* Null pointer & error code, on failure
*
* (2) The timer pool is implemented as a stack :
*
* (a) 'NetTmr_PoolPtr' points to the head of the timer pool.
*
* (b) Timers' 'NextPtr's link each timer to form the timer pool stack.
*
* (c) Timers are inserted & removed at the head of the timer pool stack.
*
*
* Timers are
* inserted & removed
* at the head
* (see Note #2c)
*
* | NextPtr
* | (see Note #2b)
* v |
* |
* ------- ------- v ------- -------
* Timer Pool ---->| |------>| |------>| |------>| |
* Pointer | | | | | | | |
* | | | | | | | |
* (see Note #2a) ------- ------- ------- -------
*
* | |
* |<------------ Pool of Free Timers ------------>|
* | (see Note #2) |
*
*
* Argument(s) : obj Pointer to object that requests a timer.
*
* fnct Pointer to object function to execute when timer expires (see Note #3).
*
* time Initial timer value (in seconds expressed in 'NET_TMR_TICK' ticks)
* [see also Note #4].
*
* flags Flags to select timer options; bit-field flags logically OR'd :
*
* NET_TMR_FLAG_NONE NO timer flags selected.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_TMR_ERR_NONE Network timer successfully allocated & initialized.
* NET_TMR_ERR_NULL_OBJ Argument 'obj' passed a NULL pointer.
* NET_TMR_ERR_NULL_FNCT Argument 'fnct' passed a NULL pointer.
* NET_TMR_ERR_NONE_AVAIL NO available timers to allocate.
* NET_TMR_ERR_INVALID_TYPE Network timer is NOT a valid timer type.
*
* Return(s) : Pointer to network timer, if NO errors.
*
* Pointer to NULL, otherwise.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
* application function(s).
*$PAGE*
* Note(s) : (3) Ideally, network timer expiration functions could be defined as '[(void) (OBJECT *)]'
* type functions -- even though network timer API functions cast expiration functions
* to generic 'CPU_FNCT_PTR' type (i.e. '[(void) (void *)]').
*
* (a) (1) Unfortunately, ISO-IEC 9899-1999 ANSI-C, Section 6.3.2.3.7 states that "a
* pointer to an object ... may be converted to a pointer to a different object
* ... [but] if the resulting pointer is not correctly aligned ... the behavior
* is undefined".
*
* And since compilers may NOT correctly convert 'void' pointers to non-'void'
* pointer arguments, network timer expiration functions MUST avoid incorrect
* pointer conversion behavior between 'void' pointer parameters & non-'void'
* pointer arguments & therefore CANNOT be defined as '[(void) (OBJECT *)]'.
*
* (2) However, Section 6.3.2.3.1 states that "a pointer to void may be converted
* to or from a pointer to any ... object ... A pointer to any ... object ...
* may be converted to a pointer to void and back again; the result shall
* compare equal to the original pointer".
*
* (b) Therefore, to correctly convert 'void' pointer objects back to appropriate
* network object pointer objects, network timer expiration functions MUST :
*
* (1) Be defined as 'CPU_FNCT_PTR' type (i.e. '[(void) (void *)]'); & ...
* (2) Explicitly cast 'void' pointer arguments to specific object pointers.
*
* (4) Timer value of 0 ticks/seconds allowed; next tick will expire timer.
*
* See also 'NetTmr_TaskHandler() Note #6'.
*
* (5) #### 'flags' currently unused (remove if unnecessary).
*********************************************************************************************************
*/
/*$PAGE*/
NET_TMR *NetTmr_Get (void *obj,
CPU_FNCT_PTR fnct,
NET_TMR_TICK time,
CPU_INT16U flags,
NET_ERR *perr)
{
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
NET_TMR *ptmr;
NET_ERR stat_err;
(void)&flags; /* Prevent compiler warning (see Note #5). */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------------- VALIDATE PTRS ------------------ */
if (obj == (void *)0) {
NET_CTR_ERR_INC(NetTmr_ErrNullObjCtr);
*perr = NET_TMR_ERR_NULL_OBJ;
return ((NET_TMR *)0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -