mirror of
https://github.com/dimoniche/solarium.vlad.git
synced 2026-01-30 04:53:30 +03:00
1018 lines
45 KiB
C
1018 lines
45 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* 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
|
||
|