📄 net_buf.c
字号:
* Null pointer & error code, on failure
*
* (2) The buffer pools are implemented as stacks :
*
* (a) 'NetBuf_SmallPoolPtr'/'NetBuf_LargePoolPtr' point to the heads of the buffer pools.
*
* (b) Buffers' 'NextBufPtr's link each buffer to form the buffer pool stacks.
*
* (c) Buffers are inserted & removed at the heads of the buffer pool stacks.
*
*
* Buffers are
* inserted & removed
* at the head
* (see Note #2c)
*
* | NextBufPtr
* | (see Note #2b)
* v |
* |
* ------- ------- v ------- -------
* Buffer Pool ---->| |------>| |------>| |------>| |
* Pointer | | | | | | | |
* | | | | | | | |
* (see Note #2a) ------- ------- ------- -------
*
* | |
* |<------------ Pool of Free Buffers ----------->|
* | (see Note #2) |
*
*
* Argument(s) : size Requested buffer size to store buffer data.
*
* ix_start Requested buffer index to store buffer data.
*
* flags Flags to select buffer options; bit-field flags logically OR'd :
*
* NET_BUF_FLAG_NONE NO buffer flags selected.
* NET_BUF_FLAG_CLR_MEM Clear buffer memory (i.e. set each buffer
* data octet to 0x00).
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_BUF_ERR_NONE Network buffer successfully allocated & initialized.
* NET_BUF_ERR_INVALID_SIZE Requested size is greater then the maximum buffer
* size available.
* NET_BUF_ERR_INVALID_LEN Requested size & start index calculation overflows
* buffer's DATA area.
* NET_BUF_ERR_INVALID_TYPE Network buffer is NOT a valid buffer type.
* NET_BUF_ERR_NONE_AVAIL NO available buffers to allocate.
*
* Return(s) : Pointer to network buffer, 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).
*
* Note(s) : (3) (a) 'size' & 'ix_start' argument check NOT required unless 'NET_BUF_SIZE's native data
* type 'CPU_INT16U' is incorrectly configured as a signed integer in 'cpu.h'.
*
* (b) 'size' of 0 octets allowed.
*
* (4) The 'GET BUF : NO BUFS' pre-processor 'else'-conditional code will never be compiled/
* linked since 'net_buf.h' ensures that at least one of the two configuration constants
* (NET_BUF_CFG_NBR_SMALL or NET_BUF_CFG_NBR_LARGE) will be configured with a value greater
* than zero (see 'net_buf.h CONFIGURATION ERRORS'). The 'else'-conditional code is included
* for completeness & as an extra precaution in case 'net_buf.h' is incorrectly modified.
*
* (5) Buffer memory cleared in NetBuf_Get() instead of in NetBuf_Free() so that the data in
* any freed buffer in a buffer pool may be inspected until that buffer is next allocated.
*********************************************************************************************************
*/
/*$PAGE*/
NET_BUF *NetBuf_Get (NET_BUF_SIZE size,
NET_BUF_SIZE ix_start,
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
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
NET_TYPE buf_type;
#endif
NET_BUF_SIZE size_len;
NET_STAT_POOL *pbuf_pool_stat;
NET_BUF **pbuf_pool;
NET_BUF *pbuf;
NET_BUF_HDR *pbuf_hdr;
CPU_BOOLEAN buf_clr_mem;
NET_ERR stat_err;
#if 0 /* See Note #3. */
/* ------------------ VALIDATE SIZE ------------------- */
if (size < 0) { /* If neg size or ix req'd, rtn err (see Note #3a). */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
}
if (ix_start < 0) {
NET_CTR_ERR_INC(NetBuf_ErrIxCtr);
*perr = NET_BUF_ERR_INVALID_IX;
return ((NET_BUF *)0);
}
#endif
/*$PAGE*/
/* ----------------- GET BUF ------------------ */
size_len = size + ix_start; /* Calc tot req'd size from start ix. */
/* Discard possible size len ovf's. */
if (size_len < size) {
NET_CTR_ERR_INC(NetBuf_ErrLenCtr);
*perr = NET_BUF_ERR_INVALID_LEN;
return ((NET_BUF *)0);
}
if (size_len < ix_start) {
NET_CTR_ERR_INC(NetBuf_ErrLenCtr);
*perr = NET_BUF_ERR_INVALID_LEN;
return ((NET_BUF *)0);
}
#if ((NET_BUF_CFG_NBR_SMALL > 0) && (NET_BUF_CFG_NBR_LARGE > 0)) /* ------------ SMALL & LARGE BUFS ------------ */
if (size_len <= NET_BUF_CFG_DATA_SIZE_SMALL) { /* If size <= SMALL buf, ... */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
buf_type = NET_BUF_TYPE_SMALL;
#endif
pbuf_pool = (NET_BUF **)&NetBuf_SmallPoolPtr; /* ... get a SMALL buf. */
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_SmallPoolStat;
} else if (size_len <= NET_BUF_CFG_DATA_SIZE_LARGE) { /* If size <= LARGE buf, ... */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
buf_type = NET_BUF_TYPE_LARGE;
#endif
pbuf_pool = (NET_BUF **)&NetBuf_LargePoolPtr; /* ... get a LARGE buf. */
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_LargePoolStat;
} else { /* Else rtn err. */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
}
#elif ((NET_BUF_CFG_NBR_SMALL > 0) && (NET_BUF_CFG_NBR_LARGE == 0)) /* ------------- SMALL BUFS ONLY -------------- */
if (size_len <= NET_BUF_CFG_DATA_SIZE_SMALL) { /* If size <= SMALL buf, ... */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
buf_type = NET_BUF_TYPE_SMALL;
#endif
pbuf_pool = (NET_BUF **)&NetBuf_SmallPoolPtr; /* ... get a SMALL buf. */
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_SmallPoolStat;
} else { /* Else rtn err. */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
}
#elif ((NET_BUF_CFG_NBR_SMALL == 0) && (NET_BUF_CFG_NBR_LARGE > 0)) /* ------------- LARGE BUFS ONLY -------------- */
if (size_len <= NET_BUF_CFG_DATA_SIZE_LARGE) { /* If size <= LARGE buf, ... */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
buf_type = NET_BUF_TYPE_LARGE;
#endif
pbuf_pool = (NET_BUF **)&NetBuf_LargePoolPtr; /* ... get a LARGE buf. */
pbuf_pool_stat = (NET_STAT_POOL *)&NetBuf_LargePoolStat;
} else { /* Else none avail, rtn err. */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
}
#else /* ----------------- NO BUFS ------------------ */
/* See Note #4. */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
#endif
/*$PAGE*/
if (*pbuf_pool != (NET_BUF *)0) { /* If buf pool NOT empty, get buf from pool. */
pbuf = *pbuf_pool;
pbuf_hdr = &pbuf->Hdr;
*pbuf_pool = (NET_BUF *)pbuf_hdr->NextBufPtr;
} else { /* If NO buf avail, rtn err. */
NET_CTR_ERR_INC(NetBuf_ErrNoneAvailCtr);
*perr = NET_BUF_ERR_NONE_AVAIL;
return ((NET_BUF *)0);
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------------- VALIDATE BUF ------------------- */
switch (pbuf_hdr->Type) { /* Validate buf Type/Size. */
case NET_BUF_TYPE_SMALL:
case NET_BUF_TYPE_LARGE:
if (pbuf_hdr->Size < NET_BUF_DATA_SIZE_MIN) { /* If buf size < NET_BUF_DATA_SIZE_MIN, ... */
NetBuf_Discard(pbuf, buf_type); /* ... buf size invalid; discard buf. */
NET_CTR_ERR_INC(NetBuf_ErrSizeCtr);
*perr = NET_BUF_ERR_INVALID_SIZE;
return ((NET_BUF *)0);
}
break;
case NET_BUF_TYPE_NONE: /* If invalid buf type, discard buf. */
default:
NetBuf_Discard(pbuf, NET_BUF_TYPE_NONE);
NET_CTR_ERR_INC(NetBuf_ErrInvalidTypeCtr);
*perr = NET_BUF_ERR_INVALID_TYPE;
return ((NET_BUF *)0); /* Prevent 'break NOT reachable' compiler warning. */
}
#endif
/* --------------------- INIT BUF --------------------- */
NetBuf_ClrHdr(pbuf_hdr);
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_USED); /* Set buf as used. */
pbuf_hdr->RefCtr = 1; /* Set ref ctr to 1; NetBuf_Get() caller is first ref. */
/* Clr ALL buf data octets to 0x00 (see Note #5). */
#if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)
(void)&flags; /* Prevent compiler warning. */
buf_clr_mem = DEF_YES;
#else
buf_clr_mem = DEF_BIT_IS_SET(flags, NET_BUF_FLAG_CLR_MEM);
#endif
if (buf_clr_mem == DEF_YES) {
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_CLR_MEM);
Mem_Clr((void *)&pbuf->Data[0],
(CPU_SIZE_T) pbuf_hdr->Size);
}
/* --------------- UPDATE BUF POOL STATS -------------- */
NetStat_PoolEntryUsedInc(pbuf_pool_stat, &stat_err);
*perr = NET_BUF_ERR_NONE;
return (pbuf); /* --------------------- RTN BUF ---------------------- */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetBuf_Free()
*
* Description : (1) Free a network buffer :
*
* (a) Configure buffer free by buffer type
* (b) Unlink buffer from network layer(s) See Note #3
* (c) Clear buffer controls
* (d) Free buffer back to buffer pool
* (e) Update buffer pool statistics
* (f) Free IP option buffer See Note #4
*
*
* Argument(s) : pbuf Pointer to a network buffer.
*
* 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 buffer already freed via auxiliary pointer(s), NetBuf_Free()
* checks the buffer's 'USED' flag BEFORE freeing the buffer.
*
* This prevention is only best-effort since any invalid duplicate buffer frees MAY be
* asynchronous to potentially valid buffer gets. Thus the invalid buffer free(s) MAY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -