nRF5 SDK for Thread and Zigbee v3.2.0
Data Structures | Macros | Typedefs | Enumerations | Functions
Packet buffers pool

Data Structures

struct  zb_buf_hdr_s
 
struct  zb_buf_s
 

Macros

#define ZB_BUF_GET_ARRAY_PTR(zbbuf)   ((zbbuf)->buf)
 Return pointer to the beginning of the buffer. More...
 
#define ZB_GET_IN_BUF()   zb_get_in_buf()
 Get IN buffer from the buffers list. If there is no buffer available, the function does not block the process. More...
 
#define ZB_GET_OUT_BUF()   zb_get_out_buf()
 Get OUT buffer from the buffers list. If there is no buffer available, the function does not block the process. More...
 
#define ZB_BUF_FROM_REF(ref)   (zb_buf_from_ref((ref), ZB_TRACE_FILE_ID, __LINE__))
 
#define ZB_REF_FROM_BUF(buf)   zb_ref_from_buf(buf)
 get buffer reference which can be passed to scheduler callback More...
 
#define ZB_BUF_BEGIN(zbbuf)   zb_buf_begin(ZB_TRACE_FILE_ID, zbbuf)
 
#define ZB_BUF_LEN(zbbuf)   zb_buf_len(ZB_TRACE_FILE_ID, zbbuf)
 
#define ZB_BUF_LEN_BY_REF(param)   ZB_BUF_LEN(ZB_BUF_FROM_REF(param))
 
#define ZB_BUF_BEGIN_FROM_REF(_ref)   ZB_BUF_BEGIN(ZB_BUF_FROM_REF(_ref))
 
#define ZB_BUF_COPY(dst_buf, src_buf)   zb_buf_copy(dst_buf, src_buf)
 
#define ZB_BUF_OFFSET(zbbuf)   zb_buf_offset(ZB_TRACE_FILE_ID, zbbuf)
 
#define ZB_BUF_INITIAL_ALLOC(zbbuf, size, ptr)   (ptr) = zb_buf_initial_alloc((zbbuf), (size))
 Initial space allocation in buffer. More...
 
#define ZB_BUF_ALLOC_LEFT(zbbuf, size, ptr)   (ptr) = zb_buf_smart_alloc_left((zbbuf), (size))
 
#define ZB_BUF_ALLOC_RIGHT(zbbuf, size, ptr)   (ptr) = zb_buf_smart_alloc_right((zbbuf), (size))
 
#define ZB_BUF_CUT_LEFT(zbbuf, size, ptr)   (ptr) = zb_buf_cut_left((zbbuf), (size))
 
#define ZB_BUF_CUT_LEFT2(zbbuf, size)   zb_buf_cut_left2(ZB_TRACE_FILE_ID, zbbuf, size)
 
#define ZB_BUF_CUT_RIGHT(zbbuf, size)   zb_buf_cut_right((zbbuf), (size))
 
#define ZB_GET_BUF_TAIL(zbbuf, size)   zb_get_buf_tail(zbbuf, size)
 
#define ZB_GET_BUF_PARAM(zbbuf, type)   ((type *)ZB_GET_BUF_TAIL((zbbuf), sizeof(type)))
 
#define ZB_SET_BUF_PARAM(zbbuf, param, type)   ( ZB_BUF_IS_BUSY_INLINE(ZB_REF_FROM_BUF(zbbuf)) *((type *)ZB_GET_BUF_TAIL(zbbuf, sizeof(type))) = (param) )
 
#define ZB_SET_BUF_PARAM_PTR(zbbuf, param, type)   ( ZB_MEMCPY((type *)ZB_GET_BUF_TAIL(zbbuf, sizeof(type)), (param), sizeof(type)) )
 
#define ZB_BUF_REUSE(zbbuf)   zb_buf_reuse(zbbuf)
 Reuse previously used buffer. More...
 
#define ZB_FREE_BUF(buf)   zb_free_buf(buf)
 Free packet buffer and put it into freelist. More...
 
#define ZB_FREE_BUF_BY_REF(param)
 
#define ZB_GET_IN_BUF_DELAYED(callback)   zb_get_in_buf_delayed(callback)
 Allocate IN buffer, call a callback when the buffer is available. More...
 
#define ZB_GET_OUT_BUF_DELAYED(callback)   zb_get_out_buf_delayed(callback)
 Allocate OUT buffer, call a callback when the buffer is available. More...
 
#define ZB_GET_OUT_BUF_DELAYED2(callback, user_param)   zb_get_buf_delayed_2param(callback, ZB_OUT_BUFFER, ZB_TRUE, user_param)
 Allocate out buffer, call a callback with extra user parameter when the buffer is available. More...
 
#define ZB_SWITCH_BUF(buf, to_in)   zb_switch_buf(buf,to_in)
 

Typedefs

typedef struct zb_buf_hdr_s zb_buf_hdr_t
 
typedef struct zb_buf_s zb_buf_t
 

Enumerations

enum  zb_buffer_types_e { ZB_OUT_BUFFER = 0, ZB_IN_BUFFER = 1 }
 

Functions

zb_buf_tzb_get_out_buf (void)
 
zb_buf_tzb_buf_from_ref (zb_uint8_t ref, zb_uint16_t from_file, zb_uint16_t from_line)
 
zb_uint8_t zb_ref_from_buf (zb_buf_t *buf)
 get buffer reference which can be passed to scheduler callback More...
 
void zb_buf_copy (zb_buf_t *dst_buf, zb_buf_t *src_buf)
 
zb_uint8_t zb_buf_offset (zb_int_t file_id, zb_buf_t *zbbuf)
 
zb_void_tzb_buf_initial_alloc (zb_buf_t *zbbuf, zb_uint8_t size)
 
zb_void_tzb_buf_smart_alloc_left (zb_buf_t *zbbuf, zb_uint8_t size)
 
zb_void_tzb_buf_smart_alloc_right (zb_buf_t *zbbuf, zb_uint8_t size)
 
void * zb_buf_cut_left (zb_buf_t *zbbuf, zb_uint8_t size)
 
void zb_buf_cut_left2 (zb_int_t file_id, zb_buf_t *zbbuf, zb_uint8_t size)
 
void zb_buf_cut_right (zb_buf_t *zbbuf, zb_uint8_t size)
 
zb_void_tzb_get_buf_tail (zb_buf_t *zbbuf, zb_uint8_t size)
 
zb_void_t zb_buf_reuse (zb_buf_t *zbbuf)
 Reuse previously used buffer. More...
 
void zb_free_buf (zb_buf_t *buf)
 Free packet buffer and put it into freelist. More...
 
zb_ret_t zb_get_in_buf_delayed (zb_callback_t callback)
 Allocate IN buffer, call a callback when the buffer is available. More...
 
zb_ret_t zb_get_out_buf_delayed (zb_callback_t callback)
 Allocate OUT buffer, call a callback when the buffer is available. More...
 
zb_ret_t zb_get_buf_delayed_2param (zb_callback2_t callback, enum zb_buffer_types_e buf_type, zb_bool_t use_2_param, zb_uint16_t user_param)
 Allocate buffer of given type and call a callback with extra user parameter when buffer of this type is available. More...
 

Detailed Description

Packet buffers

The main idea is to be simple, CPU effective and eliminate data copy when possible (again, to decrease CPU load).

One of the main data structure is memory buffer used for ZigBee packet.

ZigBee packets has limited size (127 bytes).

Zigbee packets are usually not fragmented, excluding possible fragmentation of big packets at APS layer (not currently implemented). So, can use same buffer for a single packet going down-up or up-down.

In the future will handle long ASP packets specially (buffer chains?).

Stack uses pool (list) of the fixed-size memory buffers: get buffer from it when necessary, put back when buffer not used anymore.

Every buffer has a header. Header fields: " current layer data pointer " current layer length " 'status' for 'confirm' interface " 'handle' for data and confirm interfaces " flags

When passing packet up, remove lower layers packet parts by correcting pointer and length, so passing packet up does not require data copy. When passing packet down, first fill data "inside" the buffer keeping reserve at its begin and end. It will be later filled by the lower layers.

At least 2 bytes must be reserved at the packet begin for the MAC transport: when sending all over UART, place 2 bytes header (type/length) before every packet.

Packet buffer tail has some space reserved for MAC layer: MAC adds UZ registers access after filling FIFO.

When stack works as router, packet first passed up from the MAC layer, some its parts (destination address etc) modified, then packet passed down to the MAC - exclude data copy when routing (note, that does not work with security: most re-encrypt each time buffer relayed).

Will use common packet buffers pool but limit buffers usage for IN and OUT buffers. The idea is to prevent using of all buffers for IN and stack hang due to impossibility to send anything.

Pass parameters via packet buffers

Usual sequence of the data send/receive primitives is APS-NWK-MAC down and up packet pass. Packets passed not by direct function calls but via scheduler to limit used stack size. Callback has single parameter only. Pass packet buffer as parameter. When possible, pass parameters by filling lower layer header (it is possible for nwk-mac data primitive). But usually will need a place for some additional arguments. Will put it into packet tail. Does not formally 'allocate' space at packet tail - just use it. Packet must have size enough to keep biggest possible frame + parameters. Function for getting packet tail for parameters checks for overflow and move data left if it is possible to free space at packet buffer tail.

Management calls have no data. All parameters passed via packet buffers.

Blockable memory allocation, reaction on memory absence

Main limited resource is RAM: controller has 16k only.

RAM used for i/o (packet) buffers, routing tables, neighbor tables, (what else?) and smaller data structures.

Packet buffers pool is common for in and out but its usage for In and Out is limited (50/50 initially, maybe, will tune it). The rationale is to prevent stack stop due to inability to send data due to buffers absence if all buffers "eaten" as input.

Packet buffer allocation could be asynchronous operation - it means, allocate call does not return directly but via scheduler (callback call). It allows packet allocation to block. In general, all allocation inside stack are blocked.

Output packets allocates at some upper layers (ZD0, ZCL, application etc). It packet pool is empty, it means some buffers are sitting in the output queue or indirect transmit queue waiting for send. When it will be sent and freed, allocation operation unblocks (callback calls) and goes thru.

Input packets are always allocated in the MAC. If no space available, MAC receive blocks. It does not begin packet read if no space for it. If it blocks for a short time, it will be ok. If it blocks for long time, transceiver will probably skip next packet receive. Anyway, the packet should not be split: MAC transport will either have memory for entire packet or have no memory at all.

Macro Definition Documentation

#define ZB_BUF_ALLOC_LEFT (   zbbuf,
  size,
  ptr 
)    (ptr) = zb_buf_smart_alloc_left((zbbuf), (size))

Allocate space at the beginning of buffer

Parameters
zbbuf- buffer
size- size to allocate
ptr- (out) pointer to the new buffer begin
#define ZB_BUF_ALLOC_RIGHT (   zbbuf,
  size,
  ptr 
)    (ptr) = zb_buf_smart_alloc_right((zbbuf), (size))

Allocate space at buffer end

Parameters
zbbuf- buffer
size- size to allocate
ptr- (out) pointer to the space allocated
#define ZB_BUF_BEGIN (   zbbuf)    zb_buf_begin(ZB_TRACE_FILE_ID, zbbuf)

Return pointer to data stored in buffer

Parameters
zbbuf- buffer
Returns
pointer to beginning of data in buffer
Note
see ZB_BUF_GET_ARRAY_PTR() which returns begining of buffer
#define ZB_BUF_BEGIN_FROM_REF (   _ref)    ZB_BUF_BEGIN(ZB_BUF_FROM_REF(_ref))

Return pointer to data stored in buffer by buffer reference.

#define ZB_BUF_COPY (   dst_buf,
  src_buf 
)    zb_buf_copy(dst_buf, src_buf)

Copy one buffer to another

Parameters
src_buf- source buffer
dst_buf- destination buffer
#define ZB_BUF_CUT_LEFT (   zbbuf,
  size,
  ptr 
)    (ptr) = zb_buf_cut_left((zbbuf), (size))

Cut space at the beginning of buffer

Parameters
zbbuf- buffer
size- size to cut
ptr- (out) pointer to the new buffer begin
#define ZB_BUF_CUT_RIGHT (   zbbuf,
  size 
)    zb_buf_cut_right((zbbuf), (size))

Cut space at the end of buffer

Parameters
zbbuf- buffer
size- size to cut
#define ZB_BUF_FROM_REF (   ref)    (zb_buf_from_ref((ref), ZB_TRACE_FILE_ID, __LINE__))

Calculate pointer of the buffer by buffer reference.

Parameters
ref- buffer reference
Returns
pointer to buffer header
#define ZB_BUF_GET_ARRAY_PTR (   zbbuf)    ((zbbuf)->buf)

Return pointer to the beginning of the buffer.

Parameters
zbbuf- pointer to buffer zb_buf_t
Returns
pointer to beginning of buffer
Note
see ZB_BUF_BEGIN(), which returns pointer to the beginning of data written
#define ZB_BUF_INITIAL_ALLOC (   zbbuf,
  size,
  ptr 
)    (ptr) = zb_buf_initial_alloc((zbbuf), (size))

Initial space allocation in buffer.

Allocate space in the buffer center (keep space in both buffer head and tail). Use it at upper layers before filling buffer by data. Old buffer contents is lost.

Parameters
zbbuf- buffer
size- size to allocate
ptr- (out) pointer to the new buffer begin
Returns
pointer to the allocated space
#define ZB_BUF_LEN (   zbbuf)    zb_buf_len(ZB_TRACE_FILE_ID, zbbuf)

Return current buffer length

Parameters
zbbuf- pointer to buffer
Returns
size of data placed in buffer
#define ZB_BUF_LEN_BY_REF (   param)    ZB_BUF_LEN(ZB_BUF_FROM_REF(param))

Return current buffer length by buffer reference.

#define ZB_BUF_OFFSET (   zbbuf)    zb_buf_offset(ZB_TRACE_FILE_ID, zbbuf)

Return current buffer offset

Parameters
zbbuf- pointer to buffer
Returns
offset of the data in the buffer
#define ZB_BUF_REUSE (   zbbuf)    zb_buf_reuse(zbbuf)

Reuse previously used buffer.

Parameters
zbbuf- buffer
#define ZB_FREE_BUF (   buf)    zb_free_buf(buf)

Free packet buffer and put it into freelist.

Can be called from the main loop.

Parameters
buf- packet buffer.

See any sample.

#define ZB_FREE_BUF_BY_REF (   param)
Value:
do { \
if(param) \
{ \
} \
} while(0)
void zb_free_buf(zb_buf_t *buf)
Free packet buffer and put it into freelist.
#define ZB_BUF_FROM_REF(ref)
Definition: zboss_api_core.h:733
#define ZB_GET_BUF_PARAM (   zbbuf,
  type 
)    ((type *)ZB_GET_BUF_TAIL((zbbuf), sizeof(type)))

Get buffer tail of size sizeof(type)

Usually used to place external information (some parameters) to the buffer

Parameters
zbbuf- buffer
type- data type that will be placed at the buffer end
Returns
pointer to the buffer tail casted to (type*)

Example

req->dst_addr = 0xffff;
ZB_IEEE_ADDR_COPY(req->ieee_addr, g_ieee_addr_r4);
req->start_index = 0;
req->request_type = 0x00;
#define ZB_GET_BUF_TAIL (   zbbuf,
  size 
)    zb_get_buf_tail(zbbuf, size)

Get buffer tail of size 'size'

Usually used to place external information (some parameters) to the buffer.

Parameters
zbbuf- buffer
size- requested size
Returns
pointer to the buffer tail
#define ZB_GET_IN_BUF ( )    zb_get_in_buf()

Get IN buffer from the buffers list. If there is no buffer available, the function does not block the process.

Note
This function is synchronous, so it is preferable to use ZB_GET_IN_BUF_DELAYED(callback).
Returns
The pointer to the buffer or NULL if no buffer is available.
#define ZB_GET_IN_BUF_DELAYED (   callback)    zb_get_in_buf_delayed(callback)

Allocate IN buffer, call a callback when the buffer is available.

If buffer is available, schedules callback for execution immediately. If no buffers are available now, schedule callback later, when buffer will be available.

Parameters
callbackto call.
Returns
RET_OK or error code.
ZB_GET_IN_BUF_DELAYED(new_buffer_allocated);
#define ZB_GET_OUT_BUF ( )    zb_get_out_buf()

Get OUT buffer from the buffers list. If there is no buffer available, the function does not block the process.

Note
This function is synchronous, so it is preferable to use ZB_GET_OUT_BUF_DELAYED(callback).
Returns
The pointer to the buffer or NULL if no buffer is available.
#define ZB_GET_OUT_BUF_DELAYED (   callback)    zb_get_out_buf_delayed(callback)

Allocate OUT buffer, call a callback when the buffer is available.

If buffer is available, schedules callback for execution immediatly. If no buffers are available now, schedule callback later, when buffer will be available.

Parameters
callbackto call.
Returns
RET_OK or error code.
ZB_GET_OUT_BUF_DELAYED(new_buffer_allocated);
#define ZB_GET_OUT_BUF_DELAYED2 (   callback,
  user_param 
)    zb_get_buf_delayed_2param(callback, ZB_OUT_BUFFER, ZB_TRUE, user_param)

Allocate out buffer, call a callback with extra user parameter when the buffer is available.

If buffer is available, schedules callback for execution immediatly. If no buffers are available now, schedule callback later, when buffer will be available.

Parameters
callback- callback to call
user_param- will be passed to callback.
Returns
RET_OK or error code.
ZB_GET_OUT_BUF_DELAYED2(new_buffer_allocated, user_data);
#define ZB_REF_FROM_BUF (   buf)    zb_ref_from_buf(buf)

get buffer reference which can be passed to scheduler callback

Parameters
buf- buffer of interest
Returns
reference to buffer
#define ZB_SET_BUF_PARAM (   zbbuf,
  param,
  type 
)    ( ZB_BUF_IS_BUSY_INLINE(ZB_REF_FROM_BUF(zbbuf)) *((type *)ZB_GET_BUF_TAIL(zbbuf, sizeof(type))) = (param) )

Place data of size sizeof(type) at the end of buffer

Macro used to copy external information (some data) at the end of buffer

Parameters
zbbuf- buffer
param- data to be placed in the end of buffer
type- data type that will be placed at the buffer end

Example

req.dst_addr = 0xffff;
ZB_IEEE_ADDR_COPY(req.ieee_addr, g_ieee_addr_r4);
req.start_index = 0;
req.request_type = 0x00;
#define ZB_SET_BUF_PARAM_PTR (   zbbuf,
  param,
  type 
)    ( ZB_MEMCPY((type *)ZB_GET_BUF_TAIL(zbbuf, sizeof(type)), (param), sizeof(type)) )

Place data of size sizeof(type) at the end of buffer

Macro used to copy external information (some data) at the end of buffer

Parameters
zbbuf- buffer
param- data to be placed in the end of buffer
type- data type that will be placed at the buffer end
#define ZB_SWITCH_BUF (   buf,
  to_in 
)    zb_switch_buf(buf,to_in)

Reclassify buffer : IN to OUT or OUT to IN.

Parameters
buf- buffer ptr (see zb_buf_t)
to_in- buffer type to set (see zb_buffer_types_e)

Typedef Documentation

typedef struct zb_buf_hdr_s zb_buf_hdr_t

Packet buffer header.

typedef struct zb_buf_s zb_buf_t

Packet buffer

Enumeration Type Documentation

Buffer type (direction).

Enumerator
ZB_OUT_BUFFER 

Out buffer

ZB_IN_BUFFER 

In buffer

Function Documentation

void zb_buf_copy ( zb_buf_t dst_buf,
zb_buf_t src_buf 
)

Copy one buffer to another

Parameters
src_buf- source buffer
dst_buf- destination buffer
Note
don't call it directly, use ZB_BUF_COPY() instead
void* zb_buf_cut_left ( zb_buf_t zbbuf,
zb_uint8_t  size 
)
Parameters
zbbuf- buffer
size- size to cut
Note
don't call it directly, use ZB_BUF_CUT_LEFT() instead
void zb_buf_cut_right ( zb_buf_t zbbuf,
zb_uint8_t  size 
)
Parameters
zbbuf- buffer
size- size to cut
Note
don't call it directly, use ZB_BUF_CUT_RIGHT() instead
zb_buf_t* zb_buf_from_ref ( zb_uint8_t  ref,
zb_uint16_t  from_file,
zb_uint16_t  from_line 
)

Calculate pointer of the buffer by buffer reference.

Parameters
ref- buffer reference
Returns
pointer to buffer header
Note
Don't call it directly, use ZB_BUF_FROM_REF() instead.
Parameters
from_file- TRACE_ID of the file from which function is invoked
from_line- line from which function is invoked
zb_void_t* zb_buf_initial_alloc ( zb_buf_t zbbuf,
zb_uint8_t  size 
)

Initial space allocation in buffer.

Parameters
zbbuf- buffer
size- size to allocate
Note
don't call it directly, use ZB_BUF_INITIAL_ALLOC() instead
zb_uint8_t zb_buf_offset ( zb_int_t  file_id,
zb_buf_t zbbuf 
)

Return current buffer offset

Parameters
zbbuf- pointer to buffer
Returns
offset of the data in the buffer
Parameters
file_id- TRACE_ID of the file from which function is invoked
Note
don't call it directly, use ZB_BUF_OFFSET() instead
zb_void_t zb_buf_reuse ( zb_buf_t zbbuf)

Reuse previously used buffer.

Parameters
zbbuf- buffer
Note
Don't call directly, use ZB_BUF_REUSE() instead
zb_void_t* zb_buf_smart_alloc_left ( zb_buf_t zbbuf,
zb_uint8_t  size 
)
Parameters
zbbuf- buffer
size- size to allocate
Note
don't call it directly, use ZB_BUF_ALLOC_LEFT() instead
zb_void_t* zb_buf_smart_alloc_right ( zb_buf_t zbbuf,
zb_uint8_t  size 
)
Parameters
zbbuf- buffer
size- size to allocate
Note
don't call it directly, use ZB_BUF_ALLOC_RIGHT() instead
void zb_free_buf ( zb_buf_t buf)

Free packet buffer and put it into freelist.

Can be called from the main loop.

Parameters
buf- packet buffer.

See any sample.

Note
Don't call it directly, use ZB_FREE_BUF() instead
zb_ret_t zb_get_buf_delayed_2param ( zb_callback2_t  callback,
enum zb_buffer_types_e  buf_type,
zb_bool_t  use_2_param,
zb_uint16_t  user_param 
)

Allocate buffer of given type and call a callback with extra user parameter when buffer of this type is available.

If buffer is available, schedules callback for execution immediatly. If no buffers are available now, schedule callback later, when buffer will be available.

Note
Don't call it directly, use ZB_GET_OUT_BUF_DELAYED2() (for out buffers) instead
Parameters
callback- callback to call
buf_type- buffer type (either input or output)
use_2_param- whether additional param is used
user_param- will be passed to callback.
Returns
RET_OK or error code.
zb_void_t* zb_get_buf_tail ( zb_buf_t zbbuf,
zb_uint8_t  size 
)

Get buffer tail of size 'size'

Usually used to place external information (some parameters) to the buffer.

Parameters
zbbuf- buffer
size- requested size
Returns
pointer to the buffer tail
Note
don't call directly, use ZB_GET_BUF_TAIL() instead
zb_ret_t zb_get_in_buf_delayed ( zb_callback_t  callback)

Allocate IN buffer, call a callback when the buffer is available.

If buffer is available, schedules callback for execution immediately. If no buffers are available now, schedule callback later, when buffer will be available.

Parameters
callbackto call.
Returns
RET_OK or error code.
ZB_GET_IN_BUF_DELAYED(new_buffer_allocated);
Note
Don't call it directly, use ZB_GET_IN_BUF_DELAYED() instead
zb_ret_t zb_get_out_buf_delayed ( zb_callback_t  callback)

Allocate OUT buffer, call a callback when the buffer is available.

If buffer is available, schedules callback for execution immediatly. If no buffers are available now, schedule callback later, when buffer will be available.

Parameters
callbackto call.
Returns
RET_OK or error code.
ZB_GET_OUT_BUF_DELAYED(new_buffer_allocated);
Note
Don't call it directly, use ZB_GET_OUT_BUF_DELAYED() instead
zb_uint8_t zb_ref_from_buf ( zb_buf_t buf)

get buffer reference which can be passed to scheduler callback

Parameters
buf- buffer of interest
Returns
reference to buffer
Note
don't call it directly, use ZB_REF_FROM_BUF() instead

Documentation feedback | Developer Zone | Subscribe | Updated