Moyka/OS/uc/tcpip/Source/net_tmr.c
dimoniche f74fdcceac первый коммит
первый коммит
2019-05-27 23:42:26 +03:00

1018 lines
45 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* uC/TCP-IP
* The Embedded TCP/IP Suite
*
* (c) Copyright 2003-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/TCP-IP is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/TCP-IP in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to help
* you experience uC/TCP-IP. The fact that the source code is provided does
* NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* NETWORK TIMER MANAGEMENT
*
* Filename : net_tmr.c
* Version : V1.89
* Programmer(s) : ITJ
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define NET_TMR_MODULE
#include <net.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
static void NetTmr_Clr (NET_TMR *ptmr);
#endif
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
static void NetTmr_Discard (NET_TMR *ptmr);
static void NetTmr_DiscardTaskTmr(void);
#endif
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_Init()
*
* Description : (1) Initialize Network Timer Management Module :
*
* (a) Perform Timer Module/OS initialization
* (b) Initialize timer pool
* (c) Initialize timer table
* (d) Initialize timer task list pointer
* (e) Initialize timer error counters
*
*
* Argument(s) : perr Pointer to variable that will receive the return error code from this function :
*
* NET_TMR_ERR_NONE Network timer module successfully initialized.
*
* ------- RETURNED BY NetOS_Tmr_Init() : -------
* NET_OS_ERR_INIT_TMR_TASK Network timer task NOT successfully
* initialized.
* NET_OS_ERR_INIT_TMR_TASK_NAME Network timer task name NOT successfully
* configured.
*
* Return(s) : none.
*
* Caller(s) : Net_Init().
*
* This function is an INTERNAL network protocol suite function & MUST NOT be called by
* application function(s).
*
* Note(s) : (2) Timer pool MUST be initialized PRIOR to initializing the pool with pointers to timers.
*********************************************************************************************************
*/
/*$PAGE*/
void NetTmr_Init (NET_ERR *perr)
{
NET_TMR *ptmr;
NET_TMR_QTY i;
NET_ERR err;
/* --------------- PERFORM TMR/OS INIT ---------------- */
NetOS_Tmr_Init(perr); /* Create Tmr Task. */
if (*perr != NET_OS_ERR_NONE) {
return;
}
/* ------------------ INIT TMR POOL ------------------- */
NetTmr_PoolPtr = (NET_TMR *)0; /* Init-clr net tmr pool (see Note #2). */
NetStat_PoolInit((NET_STAT_POOL *)&NetTmr_PoolStat,
(NET_STAT_POOL_QTY) NET_TMR_CFG_NBR_TMR,
(NET_ERR *)&err);
/* ------------------ INIT TMR TBL -------------------- */
ptmr = &NetTmr_Tbl[0];
for (i = 0; i < NET_TMR_CFG_NBR_TMR; i++) {
ptmr->Type = NET_TMR_TYPE_TMR; /* Init each tmr type/id--NEVER modify. */
ptmr->ID = (NET_BUF_QTY)i;
ptmr->Flags = NET_TMR_FLAG_NONE; /* Init each tmr as NOT used. */
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
NetTmr_Clr(ptmr);
#endif
ptmr->NextPtr = (void *)NetTmr_PoolPtr; /* Free each tmr to tmr pool (see Note #2). */
NetTmr_PoolPtr = ptmr;
ptmr++;
}
/* -------------- INIT TMR TASK LIST PTR -------------- */
NetTmr_TaskListHead = (NET_TMR *)0;
NetTmr_TaskListPtr = (NET_TMR *)0;
/* ---------------- INIT TMR ERR CTRS ----------------- */
#if (NET_CTR_CFG_ERR_EN == DEF_ENABLED)
NetTmr_ErrNoneAvailCtr = 0;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
NetTmr_ErrNullPtrCtr = 0;
NetTmr_ErrNullObjCtr = 0;
NetTmr_ErrNullFnctCtr = 0;
NetTmr_ErrNotUsedCtr = 0;
NetTmr_ErrInvalidTypeCtr = 0;
#endif
#endif
*perr = NET_TMR_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_TaskHandler()
*
* Description : Decrement every timer in Timer Task List & execute timer's expiration function for any
* timer that expires.
*
* (1) (a) Timers are managed in a doubly-linked Timer List.
*
* (1) 'NetTmr_TaskListHead' points to the head of the Timer List.
*
* (2) Timers' 'PrevPtr' & 'NextPtr' doubly-link each timer to form the Timer List.
*
* (b) New timers are added at the head of the Timer List.
*
* (c) As timers are added into the list, older timers migrate to the tail of the Timer
* List. Once a timer expires or is discarded, it is removed from the Timer List.
*
*
* | |
* |<-------------- List of Timers --------------->|
* | (see Note #1a) |
*
* New Timers
* inserted at head Oldest Timer in List
* (see Note #1b) (see Note #1c)
*
* | NextPtr |
* | (see Note #1a2) |
* v | v
* |
* Head of ------- ------- v ------- -------
* Timer List ---->| |------>| |------>| |------>| |
* | |<------| |<------| |<------| |
* (see Note #1a1) ------- ------- ^ ------- -------
* |
* |
* PrevPtr
* (see Note #1a2)
*
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : NetOS_Tmr_Task() [see 'net_os.c'].
*
* This function is a network protocol suite to operating system (OS) function & SHOULD be
* 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 'NET_TMR_TICK' ticks) [see 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);
}
if (fnct == (CPU_FNCT_PTR)0) {
NET_CTR_ERR_INC(NetTmr_ErrNullFnctCtr);
*perr = NET_TMR_ERR_NULL_FNCT;
return ((NET_TMR *)0);
}
#endif
/* --------------------- GET TMR ---------------------- */
if (NetTmr_PoolPtr != (NET_TMR *)0) { /* If tmr pool NOT empty, get tmr from pool. */
ptmr = (NET_TMR *)NetTmr_PoolPtr;
NetTmr_PoolPtr = (NET_TMR *)ptmr->NextPtr;
} else { /* If none avail, rtn err. */
NET_CTR_ERR_INC(NetTmr_ErrNoneAvailCtr);
*perr = NET_TMR_ERR_NONE_AVAIL;
return ((NET_TMR *)0);
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE TMR ------------------- */
if (ptmr->Type != NET_TMR_TYPE_TMR) {
NetTmr_Discard(ptmr);
NET_CTR_ERR_INC(NetTmr_ErrInvalidTypeCtr);
*perr = NET_TMR_ERR_INVALID_TYPE;
return ((NET_TMR *)0);
}
#endif
/* --------------------- INIT TMR --------------------- */
ptmr->PrevPtr = (void *)0;
ptmr->NextPtr = (void *)NetTmr_TaskListHead;
ptmr->Obj = obj;
ptmr->Fnct = fnct;
ptmr->TmrVal = time; /* Set tmr val (in ticks). */
ptmr->Flags = NET_TMR_FLAG_NONE;
DEF_BIT_SET(ptmr->Flags, NET_TMR_FLAG_USED); /* Set tmr as used. */
/* ---------- INSERT TMR INTO TMR TASK LIST ----------- */
if (NetTmr_TaskListHead != (NET_TMR *)0) { /* If list NOT empty, insert before head. */
NetTmr_TaskListHead->PrevPtr = (void *)ptmr;
}
NetTmr_TaskListHead = ptmr; /* Insert tmr @ list head. */
/* --------------- UPDATE TMR POOL STATS -------------- */
NetStat_PoolEntryUsedInc(&NetTmr_PoolStat, &stat_err);
*perr = NET_TMR_ERR_NONE;
return (ptmr); /* --------------------- RTN TMR ---------------------- */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_Free()
*
* Description : (1) Free a network timer :
*
* (a) Remove timer from Timer Task List
* (b) Clear timer controls
* (c) Free timer back to timer pool
* (d) Update timer pool statistics
*
*
* Argument(s) : ptmr Pointer to a network timer.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
* application function(s).
*
* Note(s) : (2) #### To prevent freeing a timer already freed via previous timer free, NetTmr_Free()
* checks the timer's 'USED' flag BEFORE freeing the timer.
*
* This prevention is only best-effort since any invalid duplicate timer frees MAY be
* asynchronous to potentially valid timer gets. Thus the invalid timer free(s) MAY
* corrupt the timer's valid operation(s).
*
* However, since the primary tasks of the network protocol suite are prevented from
* running concurrently (see 'net.h Note #2'), it is NOT necessary to protect network
* timer resources from possible corruption since no asynchronous access from other
* network tasks is possible.
*
* (3) 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) Whenever the Timer Task List timer is freed, the Timer Task List timer MUST be
* advanced to the next valid & available timer in the Timer Task List.
*
* See also 'NetTmr_TaskHandler() Note #5a2'.
*********************************************************************************************************
*/
/*$PAGE*/
void NetTmr_Free (NET_TMR *ptmr)
{
#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 *pprev;
NET_TMR *pnext;
NET_ERR stat_err;
/* ------------------ VALIDATE PTR -------------------- */
if (ptmr == (NET_TMR *)0) {
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------------ VALIDATE TYPE ------------------- */
if (ptmr->Type != NET_TMR_TYPE_TMR) {
NetTmr_Discard(ptmr);
NET_CTR_ERR_INC(NetTmr_ErrInvalidTypeCtr);
return;
}
/* ---------------- VALIDATE TMR USED ----------------- */
used = DEF_BIT_IS_SET(ptmr->Flags, NET_TMR_FLAG_USED);
if (used != DEF_YES) { /* If tmr NOT used, ... */
NET_CTR_ERR_INC(NetTmr_ErrNotUsedCtr);
return; /* ... rtn but do NOT free (see Note #2). */
}
#endif
/* ----------- REMOVE TMR FROM TMR TASK LIST ---------- */
if (ptmr == NetTmr_TaskListPtr) { /* If tmr is next Tmr Task tmr to update, ... */
pnext = (NET_TMR *)NetTmr_TaskListPtr->NextPtr;
NetTmr_TaskListPtr = (NET_TMR *)pnext; /* ... adv Tmr Task ptr to skip this tmr (see Note #3a).*/
}
pprev = (NET_TMR *)ptmr->PrevPtr;
pnext = (NET_TMR *)ptmr->NextPtr;
if (pprev != (NET_TMR *)0) { /* If ptmr is NOT the head of Tmr Task List, ... */
pprev->NextPtr = (void *)pnext; /* ... set pprev's NextPtr to skip ptmr. */
} else { /* Else set pnext as head of Tmr Task List. */
NetTmr_TaskListHead = (NET_TMR *)pnext;
}
if (pnext != (NET_TMR *)0) { /* If ptmr is NOT @ the tail of Tmr Task List, ... */
pnext->PrevPtr = (void *)pprev; /* ... set pnext's PrevPtr to skip ptmr. */
}
/* ---------------------- CLR TMR --------------------- */
DEF_BIT_CLR(ptmr->Flags, NET_TMR_FLAG_USED); /* Set tmr as NOT used. */
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
NetTmr_Clr(ptmr);
#endif
/* --------------------- FREE TMR --------------------- */
ptmr->NextPtr = (void *)NetTmr_PoolPtr;
NetTmr_PoolPtr = (NET_TMR *)ptmr;
/* -------------- UPDATE TMR POOL STATS --------------- */
NetStat_PoolEntryUsedDec(&NetTmr_PoolStat, &stat_err);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_Set()
*
* Description : Update a network timer with a new expiration function & timer value.
*
* Argument(s) : ptmr Pointer to a network timer.
*
* fnct Pointer to object function to execute when timer expires (see Note #2).
*
* time Update timer value (in seconds expressed in 'NET_TMR_TICK' ticks)
* [see also Note #3].
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_TMR_ERR_NONE Network timer time successfully updated.
* NET_TMR_ERR_NULL_PTR Argument 'ptmr' passed a NULL pointer.
* NET_TMR_ERR_NULL_FNCT Argument 'fnct' passed a NULL pointer.
* NET_TMR_ERR_INVALID_TYPE Invalid timer type.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
* application function(s).
*
* Note(s) : (1) Assumes network timer is ALREADY owned by a valid network object.
*
* (2) 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.
*
* See also 'NetTmr_Get() Note #3'.
*
* (3) Timer value of 0 ticks/seconds allowed; next tick will expire timer.
*
* See also 'NetTmr_TaskHandler() Note #6'.
*********************************************************************************************************
*/
/*$PAGE*/
void NetTmr_Set (NET_TMR *ptmr,
CPU_FNCT_PTR fnct,
NET_TMR_TICK time,
NET_ERR *perr)
{
#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)
/* ------------------ VALIDATE PTRS ------------------- */
if (ptmr == (NET_TMR *)0) {
NET_CTR_ERR_INC(NetTmr_ErrNullPtrCtr);
*perr = NET_TMR_ERR_NULL_PTR;
return;
}
if (fnct == (CPU_FNCT_PTR)0) {
NET_CTR_ERR_INC(NetTmr_ErrNullFnctCtr);
*perr = NET_TMR_ERR_NULL_FNCT;
return;
}
/* ------------------ VALIDATE TYPE ------------------- */
if (ptmr->Type != NET_TMR_TYPE_TMR) {
NetTmr_Discard(ptmr);
NET_CTR_ERR_INC(NetTmr_ErrInvalidTypeCtr);
*perr = NET_TMR_ERR_INVALID_TYPE;
return;
}
#endif
ptmr->Fnct = fnct;
ptmr->TmrVal = time;
*perr = NET_TMR_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_PoolStatGet()
*
* Description : Get network timer statistics pool.
*
* Argument(s) : none.
*
* Return(s) : Network timer statistics pool, if NO errors.
*
* NULL statistics pool, otherwise.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) NetTmr_PoolStatGet() blocked until network initialization completes; return NULL
* statistics pool.
*********************************************************************************************************
*/
NET_STAT_POOL NetTmr_PoolStatGet (void)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
NET_ERR err;
#endif
NET_STAT_POOL stat_pool;
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (Net_InitDone != DEF_YES) { /* If init NOT complete, ... */
NetStat_PoolClr(&stat_pool, &err);
return (stat_pool); /* ... rtn NULL stat pool (see Note #1). */
}
#endif
CPU_CRITICAL_ENTER();
stat_pool = NetTmr_PoolStat;
CPU_CRITICAL_EXIT();
return (stat_pool);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_PoolStatResetMaxUsed()
*
* Description : Reset network timer statistics pool's maximum number of entries used.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : none.
*********************************************************************************************************
*/
void NetTmr_PoolStatResetMaxUsed (void)
{
NET_ERR err;
NetStat_PoolResetUsedMax(&NetTmr_PoolStat, &err);
}
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* NetTmr_Clr()
*
* Description : Clear network timer controls.
*
* Argument(s) : ptmr Pointer to a network timer.
* ---- Argument validated in NetTmr_Init(),
* NetTmr_Free().
*
* Return(s) : none.
*
* Caller(s) : NetTmr_Init(),
* NetTmr_Free().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
static void NetTmr_Clr (NET_TMR *ptmr)
{
ptmr->PrevPtr = (void *)0;
ptmr->NextPtr = (void *)0;
ptmr->Obj = (void *)0;
ptmr->Fnct = (CPU_FNCT_PTR)0;
ptmr->TmrVal = NET_TMR_TIME_0S;
ptmr->Flags = NET_TMR_FLAG_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_Discard()
*
* Description : (1) Discard an invalid/corrupted network timer :
*
* (a) Discard timer from available timer pool See Note #2
* (b) Update timer pool statistics
*
* (2) Assumes timer is invalid/corrupt & MUST be removed. Timer removed simply by NOT
* returning the timer back to the timer pool.
*
*
* Argument(s) : ptmr Pointer to an invalid/corrupted network timer.
* ---- Argument checked in NetTmr_Get(),
* NetTmr_Free(),
* NetTmr_Set().
*
* Return(s) : none.
*
* Caller(s) : NetTmr_Get(),
* NetTmr_Free(),
* NetTmr_Set().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
static void NetTmr_Discard (NET_TMR *ptmr)
{
NET_ERR stat_err;
/* ------------------- DISCARD TMR -------------------- */
(void)&ptmr; /* Prevent compiler warning (see Note #2). */
/* --------------- UPDATE DISCARD STATS --------------- */
NetStat_PoolEntryLostInc(&NetTmr_PoolStat, &stat_err);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* NetTmr_DiscardTaskTmr()
*
* Description : (1) Discard a corrupted Timer Task List timer :
*
* (a) Unlink Timer Task timer from Timer Task List
*
* (1) Consequently, any valid or corrupted network timers that may have been linked
* following the corrupted Timer Task timer in the Timer Task List are :
*
* (A) Unlinked from the Timer Task List; ...
* (B) Discarded/lost without :
* (1) possibility of recovery; ...
* (2) measure of the number of network timers lost.
*
* See also 'NetTmr_TaskHandler() Note #4b1A'.
*
* (b) Discard Timer Task timer
*
* (1) Discard the following invalid/corrupted timers :
*
* (A) Invalid Timer Type
*
* (2) Do NOT discard the following invalid timers :
*
* (A) Unused timers
*
* (c) Clear Timer Task timer pointer
*
*
* (2) (a) Assumes Timer Task List timer ('NetTmr_TaskListPtr') is already corrupted.
*
* (b) Assumes ALL timers in Timer Task List prior to Timer Task List timer are valid.
*
* See also 'NetTmr_TaskHandler() Note #4b'.
*
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : NetTmr_TaskHandler().
*
* Note(s) : none.
*********************************************************************************************************
*/
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
static void NetTmr_DiscardTaskTmr (void)
{
NET_TMR *ptmr;
NET_TMR *pprev;
CPU_BOOLEAN discard;
ptmr = (NET_TMR *)NetTmr_TaskListHead;
pprev = (NET_TMR *)0;
while ((ptmr != (NET_TMR *)0) && /* Srch entire Tmr Task List ... */
(ptmr != (NET_TMR *)NetTmr_TaskListPtr)) { /* ... for corrupted tmr task ptr (see Note #2a). */
pprev = (NET_TMR *)ptmr;
ptmr = (NET_TMR *)ptmr->NextPtr;
}
/* Unlink corrupted tmr task ptr from Tmr Task List : */
if (pprev != (NET_TMR *)0) { /* If NOT @ head of Tmr Task List, ... */
pprev->NextPtr = (void *)0; /* ... clr prev tmr's next tmr. */
} else { /* Else clr Tmr Task List. */
NetTmr_TaskListHead = (NET_TMR *)0;
}
/* Discard invalid Tmr Task tmr (see Note #1b1). */
discard = (NetTmr_TaskListPtr->Type != NET_TMR_TYPE_TMR) ? DEF_YES : DEF_NO;
if (discard == DEF_YES) {
NetTmr_Discard(NetTmr_TaskListPtr);
}
NetTmr_TaskListPtr = (NET_TMR *)0; /* Clr Tmr Task ptr. */
}
#endif