📄 net_buf.c
字号:
* corrupt the buffer'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
* buffer resources from possible corruption since no asynchronous access from other
* network tasks is possible.
*
* (3) If a network buffer's unlink function is available, it is assumed that the function
* correctly unlinks the network buffer from any other network layer(s).
*
* (4) #### Since any single IP packet requires only a single network buffer to receive IP
* options (see 'net_ip.c NetIP_RxPktValidate() Note #1bC'), then no more than ONE
* network buffer should be linked as an IP options buffer from another buffer.
*********************************************************************************************************
*/
void NetBuf_Free (NET_BUF *pbuf)
{
#if ((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_BUF_HDR *pbuf_hdr;
NET_BUF **pbuf_pool;
NET_BUF *pbuf_ip_opt;
NET_STAT_POOL *pbuf_pool_stat;
CPU_FNCT_PTR unlink_fnct;
NET_ERR stat_err;
/*$PAGE*/
/* ------------------- VALIDATE PTR ------------------- */
if (pbuf == (NET_BUF *)0) {
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ---------------- VALIDATE BUF USED ----------------- */
pbuf_hdr = &pbuf->Hdr;
used = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_USED);
if (used != DEF_YES) { /* If buf NOT used, ... */
NET_CTR_ERR_INC(NetBuf_ErrNotUsedCtr);
return; /* ... rtn but do NOT free (see Note #2). */
}
#else
pbuf_hdr = &pbuf->Hdr;
#endif
/* ------------------- CFG BUF FREE ------------------- */
switch (pbuf_hdr->Type) {
#if (NET_BUF_CFG_NBR_SMALL > 0)
case NET_BUF_TYPE_SMALL:
pbuf_pool = (NET_BUF **)&NetBuf_SmallPoolPtr;
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_SmallPoolStat;
break;
#endif
#if (NET_BUF_CFG_NBR_LARGE > 0)
case NET_BUF_TYPE_LARGE:
pbuf_pool = (NET_BUF **)&NetBuf_LargePoolPtr;
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_LargePoolStat;
break;
#endif
case NET_BUF_TYPE_NONE:
default:
NetBuf_Discard(pbuf, NET_BUF_TYPE_NONE);
NET_CTR_ERR_INC(NetBuf_ErrInvalidTypeCtr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
pbuf_ip_opt = (NET_BUF *)pbuf_hdr->IP_OptPtr;
/* -------------------- UNLINK BUF -------------------- */
unlink_fnct = pbuf_hdr->UnlinkFnctPtr;
if (unlink_fnct != (CPU_FNCT_PTR)0) { /* If unlink fnct avail, .. */
unlink_fnct((void *)pbuf); /* .. unlink buf from other layer(s) [see Note #3]. */
}
/* ---------------------- CLR BUF --------------------- */
DEF_BIT_CLR(pbuf_hdr->Flags, NET_BUF_FLAG_USED); /* Set buf as NOT used. */
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
NetBuf_ClrHdr(pbuf_hdr);
#endif
/* --------------------- FREE BUF --------------------- */
pbuf_hdr->NextBufPtr = (void *)(*pbuf_pool);
*pbuf_pool = (NET_BUF *) pbuf;
/* -------------- UPDATE BUF POOL STATS --------------- */
NetStat_PoolEntryUsedDec(pbuf_pool_stat, &stat_err);
/* ----------------- FREE IP OPT BUF ------------------ */
NetBuf_Free(pbuf_ip_opt); /* See Note #4. */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetBuf_FreeBuf()
*
* Description : Free a network buffer.
*
* Argument(s) : pbuf Pointer to a network buffer.
*
* pctr Pointer to possible error counter.
*
* 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) #### Buffers are NOT validated for 'Type' or 'USED' before freeing.
*
* See also 'NetBuf_Free() Note #2'.
*
* (2) Buffers may be referenced by multiple layer(s). Therefore, the buffer's reference
* counter MUST be checked before freeing the buffer.
*********************************************************************************************************
*/
void NetBuf_FreeBuf (NET_BUF *pbuf,
NET_CTR *pctr)
{
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
NET_BUF_HDR *pbuf_hdr;
if (pbuf != (NET_BUF *)0) {
pbuf_hdr = &pbuf->Hdr;
if (pbuf_hdr->RefCtr > 1) { /* If buf ref'd by multiple layers (see Note #2), ..*/
pbuf_hdr->RefCtr--; /* .. dec buf ref ctr. */
} else { /* Else free buf. */
NetBuf_Free(pbuf);
}
}
if (pctr != (NET_CTR *)0) { /* If avail, ... */
NET_CTR_ERR_INC(*pctr); /* ... inc err ctr. */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetBuf_FreeBufList()
*
* Description : Free a network buffer list.
*
* (1) Network buffer lists are implemented as doubly-linked lists :
*
* (a) 'pbuf_list' points to the head of the buffer list.
*
* (b) Buffer's 'PrevBufPtr' & 'NextBufPtr' doubly-link each buffer in a buffer list.
*
*
* --- Head of -------
* ^ Buffer List ---->| |
* | | |
* | (see Note #1a) | |
* | | |
* | | |
* | -------
* | | ^
* | | |
* | v |
* -------
* Buffer List | |
* (see Note #1) | |
* | |
* | | |
* | | |
* | -------
* | | ^
* | NextBufPtr ---> | | <--- PrevBufPtr
* | (see Note #1b) v | (see Note #1b)
* | -------
* | | |
* v | |
* --- -------
*
*
* Argument(s) : pbuf_list Pointer to a buffer list.
*
* pctr Pointer to possible error counter.
*
* 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) #### Buffers are NOT validated for 'Type' or 'USED' before freeing.
*
* See also 'NetBuf_Free() Note #2'.
*
* (3) Buffers may be referenced by multiple layer(s). Therefore, the buffer's reference
* counter MUST be checked before freeing the buffer.
*
* (4) Buffers NOT freed are unlinked from other buffer fragment lists & compressed within
* their own buffer list. Ideally, buffer fragment lists SHOULD NEVER be compressed
* but should be unlinked in their entirety.
*********************************************************************************************************
*/
/*$PAGE*/
void NetBuf_FreeBufList (NET_BUF *pbuf_list,
NET_CTR *pctr)
{
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
NET_BUF *pbuf;
NET_BUF *pbuf_prev;
NET_BUF *pbuf_next;
NET_BUF_HDR *pbuf_hdr;
NET_BUF_HDR *pbuf_prev_hdr;
pbuf = (NET_BUF *)pbuf_list;
pbuf_prev = (NET_BUF *)0;
while (pbuf != (NET_BUF *)0) { /* Free ALL bufs in buf list. */
pbuf_hdr = &pbuf->Hdr;
pbuf_next = (NET_BUF *)pbuf_hdr->NextBufPtr;
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
pbuf_hdr->PrevPrimListPtr = (void *)0;
pbuf_hdr->NextPrimListPtr = (void *)0;
#endif
if (pbuf_hdr->RefCtr > 1) { /* If buf ref'd by multiple layers (see Note #3), ..*/
pbuf_hdr->RefCtr--; /* .. dec buf ref ctr. */
pbuf_hdr->PrevBufPtr = (void *)pbuf_prev;
pbuf_hdr->NextBufPtr = (void *)0;
if (pbuf_prev != (NET_BUF *)0) { /* If prev buf non-NULL, ... */
pbuf_prev_hdr = &pbuf_prev->Hdr;
pbuf_prev_hdr->NextBufPtr = (void *)pbuf; /* ... set prev buf's next ptr to cur buf. */
}
pbuf_prev = (NET_BUF *)pbuf; /* Set cur buf as new prev buf (see Note #4). */
} else { /* Else free buf. */
NetBuf_Free(pbuf);
}
if (pctr != (NET_CTR *)0) { /* If avail, ... */
NET_CTR_ERR_INC(*pctr); /* ... inc err ctr. */
}
pbuf = pbuf_next;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetBuf_FreeBufQ_PrimList()
*
* Description : Free a network buffer queue, organized by the buffers' primary buffer lists.
*
* (1) Network buffer queues are implemented as multiply-linked lists :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -