#ifndef _PBUF_H #define _PBUF_H #include <stdint.h> #include <stddef.h> #include <assert.h> typedef void (*pbuf_callback_t)(void); //function pointer that will be called when a pbuf is freed in this pool struct pbuf_pool_s; typedef struct pbuf_s { uint8_t* payload; uint32_t length; uint32_t capacity; uint8_t* payload_memory; struct pbuf_s *next; //used to link pbufs struct pbuf_pool_s *pool; void *user; }pbuf_t; typedef struct pbuf_pool_s { pbuf_t* pbuf_memory; uint32_t pbuf_count; uint8_t* payload_memory; uint32_t payload_capacity; uint32_t pbufs_available; pbuf_t* free_list; pbuf_callback_t free_callback; }pbuf_pool_t; #define PBUF_DECLARE_POOL(pool_name, pbuf_count, pbuf_size) \ static uint8_t pool_name##_payload_memory[(pbuf_count) * (pbuf_size)] __attribute__((aligned(4))); \ static pbuf_t pool_name##_memory[pbuf_count]; \ pbuf_pool_t pool_name #define STATIC_PBUF_DECLARE_POOL(pool_name, pbuf_count, pbuf_size) \ static uint8_t pool_name##_payload_memory[(pbuf_count) * (pbuf_size)] __attribute__((aligned(4))); \ static pbuf_t pool_name##_memory[pbuf_count]; \ static pbuf_pool_t pool_name #define PBUF_INIT_POOL(pool_name) \ pbuf_pool_create(&pool_name, \ sizeof(pool_name##_memory) / sizeof(pbuf_t), \ pool_name##_memory, \ sizeof(pool_name##_payload_memory) / (sizeof(pool_name##_memory) / sizeof(pbuf_t)), \ pool_name##_payload_memory) /** \brief Creates a new pool of pbufs \param pool Pointer to a pbuf_pool_t structure that will be initialized \param pbuf_count Number of pbufs to create in the pbuf pool \param pbuf_memory Pointer to a statically allocated area of memory for storing the pbuf structures. \param payload_capacity Size of the pbuf payload. \param payload_memory Pointer to statically allocated memory that will be used for storing the pbuf attached buffers pbuf_memory needs to be a statically allocated memory chunk of size: pbuf_count * sizeof(pbuf_t) (bytes) payload_memory needs to be a statically allocated memory chunk of size: pbuf_count * pbuf_payload_size (bytes) */ void pbuf_pool_create(pbuf_pool_t *pool, uint32_t pbuf_count, void *pbuf_memory, uint32_t payload_capacity, void *payload_memory); void pbuf_pool_reset(pbuf_pool_t *pool); void pbuf_dump_pool(pbuf_pool_t *pool); static inline uint32_t pbuf_pool_get_available(pbuf_pool_t *pool) { return pool->pbufs_available; } static inline pbuf_t* pbuf_alloc(pbuf_pool_t *pool) { assert(pool); pbuf_t* p = pool->free_list; if (p) { pool->free_list = pool->free_list->next; //remove it from the list pool->pbufs_available--; p->payload = p->payload_memory; p->capacity = pool->payload_capacity; } return p; } static inline void pbuf_free(pbuf_t* p) { if (p) { p->next = p->pool->free_list; //add it back to the free list p->pool->free_list = p; p->pool->pbufs_available++; if (p->pool->free_callback) //call the hook if we have one p->pool->free_callback(); } } /* inline void pbuf_free_queue(pbuf_t *queue) { while(queue) { pbuf_t *p = queue; queue = queue->next; //free the pbuf p->next = p->pool->free_list; //add it back to the free list p->pool->free_list = p; } } */ #endif