STM32F7 Ethernet interface for nucleo STM32F767

Embed: (wiki syntax)

« Back to documentation index

Packet buffers (PBUF)

Packet buffers (PBUF)

Packets are built from the pbuf data structure. More...

Enumerations

enum  pbuf_layer {
  PBUF_TRANSPORT, PBUF_IP, PBUF_LINK, PBUF_RAW_TX,
  PBUF_RAW
}
 

Enumeration of pbuf layers.

More...
enum  pbuf_type { PBUF_RAM, PBUF_ROM, PBUF_REF, PBUF_POOL }
 

Enumeration of pbuf types.

More...

Functions

struct pbufpbuf_alloc (pbuf_layer layer, u16_t length, pbuf_type type)
 Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
struct pbufpbuf_alloced_custom (pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, void *payload_mem, u16_t payload_mem_len)
 Initialize a custom pbuf (already allocated).
void pbuf_realloc (struct pbuf *p, u16_t new_len)
 Shrink a pbuf chain to a desired length.
u8_t pbuf_free (struct pbuf *p)
 Dereference a pbuf chain or queue and deallocate any no-longer-used pbufs at the head of this chain or queue.
void pbuf_ref (struct pbuf *p)
 Increment the reference count of the pbuf.
void pbuf_cat (struct pbuf *h, struct pbuf *t)
 Concatenate two pbufs (each may be a pbuf chain) and take over the caller's reference of the tail pbuf.
void pbuf_chain (struct pbuf *h, struct pbuf *t)
 Chain two pbufs (or pbuf chains) together.
err_t pbuf_copy (struct pbuf *p_to, const struct pbuf *p_from)
 Create PBUF_RAM copies of pbufs.
u16_t pbuf_copy_partial (const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
 Copy (part of) the contents of a packet buffer to an application supplied buffer.
struct pbufpbuf_skip (struct pbuf *in, u16_t in_offset, u16_t *out_offset)
 Skip a number of bytes at the start of a pbuf.
err_t pbuf_take (struct pbuf *buf, const void *dataptr, u16_t len)
 Copy application supplied data into a pbuf.
err_t pbuf_take_at (struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
 Same as pbuf_take() but puts data at an offset.
struct pbufpbuf_coalesce (struct pbuf *p, pbuf_layer layer)
 Creates a single pbuf out of a queue of pbufs.
u8_t pbuf_get_at (const struct pbuf *p, u16_t offset)
 Get one byte from the specified position in a pbuf WARNING: returns zero for offset >= p->tot_len.
int pbuf_try_get_at (const struct pbuf *p, u16_t offset)
 Get one byte from the specified position in a pbuf.
void pbuf_put_at (struct pbuf *p, u16_t offset, u8_t data)
 Put one byte to the specified position in a pbuf WARNING: silently ignores offset >= p->tot_len.
u16_t pbuf_memcmp (const struct pbuf *p, u16_t offset, const void *s2, u16_t n)
 Compare pbuf contents at specified offset with memory s2, both of length n.
u16_t pbuf_memfind (const struct pbuf *p, const void *mem, u16_t mem_len, u16_t start_offset)
 Find occurrence of mem (with length mem_len) in pbuf p, starting at offset start_offset.

Detailed Description

Packets are built from the pbuf data structure.

It supports dynamic memory allocation for packet contents or can reference externally managed packet contents both in RAM and ROM. Quick allocation for incoming packets is provided through pools with fixed sized pbufs.

A packet may span over multiple pbufs, chained as a singly linked list. This is called a "pbuf chain".

Multiple packets may be queued, also using this singly linked list. This is called a "packet queue".

So, a packet queue consists of one or more pbuf chains, each of which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE NOT SUPPORTED!!! Use helper structs to queue multiple packets.

The differences between a pbuf chain and a packet queue are very precise but subtle.

The last pbuf of a packet has a ->tot_len field that equals the ->len field. It can be found by traversing the list. If the last pbuf of a packet has a ->next field other than NULL, more packets are on the queue.

Therefore, looping through a pbuf of a single packet, has an loop end condition (tot_len == p->len), NOT (next == NULL).

Example of custom pbuf usage for zero-copy RX:

 {.c}
typedef struct my_custom_pbuf
{
   struct pbuf_custom p;
   void* dma_descriptor;
} my_custom_pbuf_t;

LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(my_custom_pbuf_t), "Zero-copy RX PBUF pool");

void my_pbuf_free_custom(void* p)
{
  my_custom_pbuf_t* my_puf = (my_custom_pbuf_t*)p;

  LOCK_INTERRUPTS();
  free_rx_dma_descriptor(my_pbuf->dma_descriptor);
  LWIP_MEMPOOL_FREE(RX_POOL, my_pbuf);
  UNLOCK_INTERRUPTS();
}

void eth_rx_irq()
{
  dma_descriptor*   dma_desc = get_RX_DMA_descriptor_from_ethernet();
  my_custom_pbuf_t* my_pbuf  = (my_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(RX_POOL);

  my_pbuf->p.custom_free_function = my_pbuf_free_custom;
  my_pbuf->dma_descriptor         = dma_desc;

  invalidate_cpu_cache(dma_desc->rx_data, dma_desc->rx_length);
  
  struct pbuf* p = pbuf_alloced_custom(PBUF_RAW,
     dma_desc->rx_length,
     PBUF_REF,
     &my_pbuf->p,
     dma_desc->rx_data,
     dma_desc->max_buffer_size);

  if(netif->input(p, netif) != ERR_OK) {
    pbuf_free(p);
  }
}

Enumeration Type Documentation

enum pbuf_layer

Enumeration of pbuf layers.

Enumerator:
PBUF_TRANSPORT 

Includes spare room for transport layer header, e.g.

UDP header. Use this if you intend to pass the pbuf to functions like udp_send().

PBUF_IP 

Includes spare room for IP header.

Use this if you intend to pass the pbuf to functions like raw_send().

PBUF_LINK 

Includes spare room for link layer header (ethernet header).

Use this if you intend to pass the pbuf to functions like ethernet_output().

See also:
PBUF_LINK_HLEN
PBUF_RAW_TX 

Includes spare room for additional encapsulation header before ethernet headers (e.g.

802.11). Use this if you intend to pass the pbuf to functions like netif->linkoutput().

See also:
PBUF_LINK_ENCAPSULATION_HLEN
PBUF_RAW 

Use this for input packets in a netif driver when calling netif->input() in the most common case - ethernet-layer netif driver.

Definition at line 72 of file pbuf.h.

enum pbuf_type

Enumeration of pbuf types.

Enumerator:
PBUF_RAM 

pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload are allocated in one piece of contiguous memory (so the first payload byte can be calculated from struct pbuf).

pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might change in future versions). This should be used for all OUTGOING packets (TX).

PBUF_ROM 

pbuf data is stored in ROM, i.e.

struct pbuf and its payload are located in totally different memory areas. Since it points to ROM, payload does not have to be copied when queued for transmission.

PBUF_REF 

pbuf comes from the pbuf pool.

Much like PBUF_ROM but payload might change so it has to be duplicated when queued before transmitting, depending on who has a 'ref' to it.

PBUF_POOL 

pbuf payload refers to RAM.

This one comes from a pool and should be used for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct pbuf and its payload are allocated in one piece of contiguous memory (so the first payload byte can be calculated from struct pbuf). Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing, you are unable to receive TCP acks!

Definition at line 101 of file pbuf.h.


Function Documentation

struct pbuf* pbuf_alloc ( pbuf_layer  layer,
u16_t  length,
pbuf_type  type 
) [read]

Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).

The actual memory allocated for the pbuf is determined by the layer at which the pbuf is allocated and the requested size (from the size parameter).

Parameters:
layerflag to define header size
lengthsize of the pbuf's payload
typethis parameter decides how and where the pbuf should be allocated as follows:
  • PBUF_RAM: buffer memory for pbuf is allocated as one large chunk. This includes protocol headers as well.
  • PBUF_ROM: no buffer memory is allocated for the pbuf, even for protocol headers. Additional headers must be prepended by allocating another pbuf and chain in to the front of the ROM pbuf. It is assumed that the memory used is really similar to ROM in that it is immutable and will not be changed. Memory which is dynamic should generally not be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  • PBUF_REF: no buffer memory is allocated for the pbuf, even for protocol headers. It is assumed that the pbuf is only being used in a single thread. If the pbuf gets queued, then pbuf_take should be called to copy the buffer.
  • PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from the pbuf pool that is allocated during pbuf_init().
Returns:
the allocated pbuf. If multiple pbufs where allocated, this is the first pbuf of a pbuf chain.

Definition at line 248 of file lwip_pbuf.c.

struct pbuf* pbuf_alloced_custom ( pbuf_layer  l,
u16_t  length,
pbuf_type  type,
struct pbuf_custom p,
void *  payload_mem,
u16_t  payload_mem_len 
) [read]

Initialize a custom pbuf (already allocated).

Parameters:
lflag to define header size
lengthsize of the pbuf's payload
typetype of the pbuf (only used to treat the pbuf accordingly, as this function allocates no memory)
ppointer to the custom pbuf to initialize (already allocated)
payload_mempointer to the buffer that is used for payload and headers, must be at least big enough to hold 'length' plus the header size, may be NULL if set later. ATTENTION: The caller is responsible for correct alignment of this buffer!!
payload_mem_lenthe size of the 'payload_mem' buffer, must be at least big enough to hold 'length' plus the header size

Definition at line 425 of file lwip_pbuf.c.

void pbuf_cat ( struct pbuf h,
struct pbuf t 
)

Concatenate two pbufs (each may be a pbuf chain) and take over the caller's reference of the tail pbuf.

Note:
The caller MAY NOT reference the tail pbuf afterwards. Use pbuf_chain() for that purpose.
See also:
pbuf_chain()

Definition at line 840 of file lwip_pbuf.c.

void pbuf_chain ( struct pbuf h,
struct pbuf t 
)

Chain two pbufs (or pbuf chains) together.

The caller MUST call pbuf_free(t) once it has stopped using it. Use pbuf_cat() instead if you no longer use t.

Parameters:
hhead pbuf (chain)
ttail pbuf (chain)
Note:
The pbufs MUST belong to the same packet.
MAY NOT be called on a packet queue.

The ->tot_len fields of all pbufs of the head chain are adjusted. The ->next field of the last pbuf of the head chain is adjusted. The ->ref field of the first pbuf of the tail chain is adjusted.

Definition at line 882 of file lwip_pbuf.c.

struct pbuf* pbuf_coalesce ( struct pbuf p,
pbuf_layer  layer 
) [read]

Creates a single pbuf out of a queue of pbufs.

Remarks:
: Either the source pbuf 'p' is freed by this function or the original pbuf 'p' is returned, therefore the caller has to check the result!
Parameters:
pthe source pbuf
layerpbuf_layer of the new pbuf
Returns:
a new, single pbuf (p->next is NULL) or the old pbuf if allocation fails

Definition at line 1229 of file lwip_pbuf.c.

err_t pbuf_copy ( struct pbuf p_to,
const struct pbuf p_from 
)

Create PBUF_RAM copies of pbufs.

Used to queue packets on behalf of the lwIP stack, such as ARP based queueing.

Note:
You MUST explicitly use p = pbuf_take(p);
Only one packet is copied, no packet queue!
Parameters:
p_topbuf destination of the copy
p_frompbuf source of the copy
Returns:
ERR_OK if pbuf was copied ERR_ARG if one of the pbufs is NULL or p_to is not big enough to hold p_from

Definition at line 948 of file lwip_pbuf.c.

u16_t pbuf_copy_partial ( const struct pbuf buf,
void *  dataptr,
u16_t  len,
u16_t  offset 
)

Copy (part of) the contents of a packet buffer to an application supplied buffer.

Parameters:
bufthe pbuf from which to copy data
dataptrthe application supplied buffer
lenlength of data to copy (dataptr must be big enough). No more than buf->tot_len will be copied, irrespective of len
offsetoffset into the packet buffer from where to begin copying len bytes
Returns:
the number of bytes copied, or 0 on failure

Definition at line 1015 of file lwip_pbuf.c.

u8_t pbuf_free ( struct pbuf p )

Dereference a pbuf chain or queue and deallocate any no-longer-used pbufs at the head of this chain or queue.

Decrements the pbuf reference count. If it reaches zero, the pbuf is deallocated.

For a pbuf chain, this is repeated for each pbuf in the chain, up to the first pbuf which has a non-zero reference count after decrementing. So, when all reference counts are one, the whole chain is free'd.

Parameters:
pThe pbuf (chain) to be dereferenced.
Returns:
the number of pbufs that were de-allocated from the head of the chain.
Note:
MUST NOT be called on a packet queue (Not verified to work yet).
the reference counter of a pbuf equals the number of pointers that refer to the pbuf (or into the pbuf).

Definition at line 715 of file lwip_pbuf.c.

u8_t pbuf_get_at ( const struct pbuf p,
u16_t  offset 
)

Get one byte from the specified position in a pbuf WARNING: returns zero for offset >= p->tot_len.

Parameters:
ppbuf to parse
offsetoffset into p of the byte to return
Returns:
byte at an offset into p OR ZERO IF 'offset' >= p->tot_len

Definition at line 1299 of file lwip_pbuf.c.

u16_t pbuf_memcmp ( const struct pbuf p,
u16_t  offset,
const void *  s2,
u16_t  n 
)

Compare pbuf contents at specified offset with memory s2, both of length n.

Parameters:
ppbuf to compare
offsetoffset into p at which to start comparing
s2buffer to compare
nlength of buffer to compare
Returns:
zero if equal, nonzero otherwise (0xffff if p is too short, diffoffset+1 otherwise)

Definition at line 1362 of file lwip_pbuf.c.

u16_t pbuf_memfind ( const struct pbuf p,
const void *  mem,
u16_t  mem_len,
u16_t  start_offset 
)

Find occurrence of mem (with length mem_len) in pbuf p, starting at offset start_offset.

Parameters:
ppbuf to search, maximum length is 0xFFFE since 0xFFFF is used as return value 'not found'
memsearch for the contents of this buffer
mem_lenlength of 'mem'
start_offsetoffset into p at which to start searching
Returns:
0xFFFF if substr was not found in p or the index where it was found

Definition at line 1404 of file lwip_pbuf.c.

void pbuf_put_at ( struct pbuf p,
u16_t  offset,
u8_t  data 
)

Put one byte to the specified position in a pbuf WARNING: silently ignores offset >= p->tot_len.

Parameters:
ppbuf to fill
offsetoffset into p of the byte to write
databyte to write at an offset into p

Definition at line 1339 of file lwip_pbuf.c.

void pbuf_realloc ( struct pbuf p,
u16_t  new_len 
)

Shrink a pbuf chain to a desired length.

Parameters:
ppbuf to shrink.
new_lendesired new length of pbuf chain

Depending on the desired length, the first few pbufs in a chain might be skipped and left unchanged. The new last pbuf in the chain will be resized, and any remaining pbufs will be freed.

Note:
If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
May not be called on a packet queue.
Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain).

Definition at line 493 of file lwip_pbuf.c.

void pbuf_ref ( struct pbuf p )

Increment the reference count of the pbuf.

Parameters:
ppbuf to increase reference counter of

Definition at line 820 of file lwip_pbuf.c.

struct pbuf* pbuf_skip ( struct pbuf in,
u16_t  in_offset,
u16_t *  out_offset 
) [read]

Skip a number of bytes at the start of a pbuf.

Parameters:
ininput pbuf
in_offsetoffset to skip
out_offsetresulting offset in the returned pbuf
Returns:
the pbuf in the queue where the offset is

Definition at line 1131 of file lwip_pbuf.c.

err_t pbuf_take ( struct pbuf buf,
const void *  dataptr,
u16_t  len 
)

Copy application supplied data into a pbuf.

This function can only be used to copy the equivalent of buf->tot_len data.

Parameters:
bufpbuf to fill with data
dataptrapplication supplied data buffer
lenlength of the application supplied data buffer
Returns:
ERR_OK if successful, ERR_MEM if the pbuf is not big enough

Definition at line 1149 of file lwip_pbuf.c.

err_t pbuf_take_at ( struct pbuf buf,
const void *  dataptr,
u16_t  len,
u16_t  offset 
)

Same as pbuf_take() but puts data at an offset.

Parameters:
bufpbuf to fill with data
dataptrapplication supplied data buffer
lenlength of the application supplied data buffer
offsetoffset in pbuf where to copy dataptr to
Returns:
ERR_OK if successful, ERR_MEM if the pbuf is not big enough

Definition at line 1193 of file lwip_pbuf.c.

int pbuf_try_get_at ( const struct pbuf p,
u16_t  offset 
)

Get one byte from the specified position in a pbuf.

Parameters:
ppbuf to parse
offsetoffset into p of the byte to return
Returns:
byte at an offset into p [0..0xFF] OR negative if 'offset' >= p->tot_len

Definition at line 1317 of file lwip_pbuf.c.