|
#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() |
|
#define | ZB_GET_OUT_BUF() zb_get_out_buf() |
|
#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) |
|
|
zb_uint8_t * | zb_buf_begin (zb_int_t file_id, zb_buf_t *zbbuf) |
| More...
|
|
zb_uint8_t | zb_buf_len (zb_int_t file_id, zb_buf_t *zbbuf) |
| More...
|
|
zb_buf_t * | zb_get_in_buf () |
|
zb_buf_t * | zb_get_out_buf () |
|
zb_buf_t * | zb_buf_from_ref (zb_uint8_t ref, zb_uint16_t from_file, zb_uint16_t from_line) |
| More...
|
|
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) |
| More...
|
|
zb_uint8_t | zb_buf_offset (zb_int_t file_id, zb_buf_t *zbbuf) |
| More...
|
|
zb_void_t * | zb_buf_initial_alloc (zb_buf_t *zbbuf, zb_uint8_t size) |
|
zb_void_t * | zb_buf_smart_alloc_left (zb_buf_t *zbbuf, zb_uint8_t size) |
|
zb_void_t * | zb_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_t * | zb_get_buf_tail (zb_buf_t *zbbuf, zb_uint8_t size) |
| More...
|
|
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...
|
|
zb_void_t | zb_switch_buf (zb_buf_t *buf, zb_uint8_t to_in) |
| More...
|
|
- 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, we will not split the packet: MAC transport will either have memory for entire packet or have no memory at all.
Allocate space at the beginning of buffer
- Parameters
-
zbbuf | - buffer |
size | - size to allocate |
ptr | - (out) pointer to the new buffer begin |
Allocate space at buffer end
- Parameters
-
zbbuf | - buffer |
size | - size to allocate |
ptr | - (out) pointer to the space allocated |
Return pointer to data stored in buffer
- Parameters
-
- Returns
- pointer to beginning of data in buffer
- Note
- see ZB_BUF_GET_ARRAY_PTR() which returns begining of buffer
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 |
Cut space at the end of buffer
- Parameters
-
zbbuf | - buffer |
size | - size to cut |
Calculate pointer of the buffer by buffer reference.
- Parameters
-
- Returns
- pointer to buffer header
#define ZB_BUF_GET_ARRAY_PTR |
( |
|
zbbuf | ) |
((zbbuf)->buf) |
Return pointer to the beginning of the buffer.
- Parameters
-
- Returns
- pointer to beginning of buffer
- Note
- see ZB_BUF_BEGIN(), which returns pointer to the beginning of data written
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
Return current buffer length
- Parameters
-
- Returns
- size of data placed in buffer
Return current buffer length by buffer reference.
Return current buffer offset
- Parameters
-
- Returns
- offset of the data in the buffer
Reuse previously used buffer.
- Parameters
-
Free packet buffer and put it into freelist.
Can be called from the main loop.
- Parameters
-
See any sample.
#define ZB_FREE_BUF_BY_REF |
( |
|
param | ) |
|
Value:do { \
if(param) \
{ \
} \
} while(0)
#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
ZB_IEEE_ADDR_COPY(req->
ieee_addr, g_ieee_addr_r4);
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
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
-
- Returns
- RET_OK or error code.
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
-
- Returns
- RET_OK or error code.
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.
get buffer reference which can be passed to scheduler callback
- Parameters
-
- 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
ZB_IEEE_ADDR_COPY(req.
ieee_addr, g_ieee_addr_r4);
#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 |
Reclassify buffer : IN to OUT or OUT to IN.
- Parameters
-
Buffer type (direction).
Enumerator |
---|
ZB_OUT_BUFFER |
Out buffer
|
ZB_IN_BUFFER |
In buffer
|
Return pointer to data stored in buffer
- Parameters
-
- Returns
- pointer to beginning of data in buffer
- Note
- see ZB_BUF_GET_ARRAY_PTR() which returns begining of buffer
Copy one buffer to another
- Parameters
-
src_buf | - source buffer |
dst_buf | - destination buffer |
Calculate pointer of the buffer by buffer reference.
- Parameters
-
- Returns
- pointer to buffer header
Initial space allocation in buffer.
Return current buffer length
- Parameters
-
- Returns
- size of data placed in buffer
Return current buffer offset
- Parameters
-
- Returns
- offset of the data in the buffer
Reuse previously used buffer.
- Parameters
-
Free packet buffer and put it into freelist.
Can be called from the main loop.
- Parameters
-
See any sample.
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.
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
Get IN buffer from the buffers list. If no buffers available, does not block.
- Returns
- pointer to the buffer or NULL if no buffer available.
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
-
- Returns
- RET_OK or error code.
Get OUT buffer from the buffers list. If no buffers available, does not block.
- Returns
- pointer to the buffer.
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
-
- Returns
- RET_OK or error code.
get buffer reference which can be passed to scheduler callback
- Parameters
-
- Returns
- reference to buffer
Reclassify buffer : IN to OUT or OUT to IN.
- Parameters
-