Created memory manager class to netsocket and updated lwip to use it

instead of old memory interface.
pull/6847/head
Mika Leppänen 2017-12-21 11:07:48 +02:00 committed by Kevin Bracey
parent f584ac3b59
commit bc5d4d1c0d
11 changed files with 514 additions and 240 deletions

View File

@ -22,6 +22,7 @@
#include <stdbool.h>
#include <string.h>
#include <new>
#include <stdint.h>
#include "lwip/opt.h"
#include "lwip/api.h"
@ -335,6 +336,7 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
return NSAPI_ERROR_NO_MEMORY;
}
interface->emac = &emac;
interface->memory_manager = &memory_manager;
interface->ppp = false;
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
@ -481,7 +483,6 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne
client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
}
netif_set_up(&netif);
if (ppp) {
err_t err = ppp_lwip_connect(hw);
if (err) {

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
#include "emac_stack_mem.h"
#include "lwip/tcpip.h"
#include "lwip/tcp.h"
#include "lwip/ip.h"
@ -29,12 +28,16 @@
err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p)
{
/* Increase reference counter since lwip stores handle to pbuf and frees
it after output */
pbuf_ref(p);
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
bool ret = mbed_if->emac->link_out(p);
return ret ? ERR_OK : ERR_IF;
}
void LWIP::Interface::emac_input(emac_stack_mem_t *buf)
void LWIP::Interface::emac_input(emac_mem_buf_t *buf)
{
struct pbuf *p = static_cast<struct pbuf *>(buf);
@ -136,6 +139,7 @@ err_t LWIP::Interface::emac_if_init(struct netif *netif)
int err = ERR_OK;
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
mbed_if->emac->set_memory_manager(*mbed_if->memory_manager);
mbed_if->emac->set_link_input_cb(mbed::callback(mbed_if, &LWIP::Interface::emac_input));
mbed_if->emac->set_link_state_cb(mbed::callback(mbed_if, &LWIP::Interface::emac_state_change));

View File

@ -0,0 +1,153 @@
/* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "pbuf.h"
#include "LWIPMemoryManager.h"
emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
{
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
if (pbuf == NULL) {
return NULL;
}
align_memory(pbuf, align);
return static_cast<emac_mem_buf_t *>(pbuf);
}
emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
{
uint32_t total_align = count_total_align(size, align);
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + total_align, PBUF_POOL);
if (pbuf == NULL) {
return NULL;
}
align_memory(pbuf, align);
return static_cast<emac_mem_buf_t *>(pbuf);
}
uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
{
uint32_t alloc_unit = LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) - align;
return alloc_unit;
}
void LWIPMemoryManager::free(emac_mem_buf_t *buf)
{
pbuf_free(static_cast<struct pbuf *>(buf));
}
uint32_t LWIPMemoryManager::get_total_len(const emac_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->tot_len;
}
void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf)
{
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
}
void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
{
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));
}
emac_mem_buf_t *LWIPMemoryManager::get_next(const emac_mem_buf_t *buf) const
{
if (!buf) {
return NULL;
}
struct pbuf *next = (static_cast<const struct pbuf *>(buf))->next;
return static_cast<emac_mem_buf_t *>(next);
}
void *LWIPMemoryManager::get_ptr(const emac_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->payload;
}
uint32_t LWIPMemoryManager::get_len(const emac_mem_buf_t *buf) const
{
return (static_cast<const struct pbuf *>(buf))->len;
}
void LWIPMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len)
{
struct pbuf *pbuf = static_cast<struct pbuf *>(buf);
pbuf->len = len;
set_total_len(pbuf);
}
uint32_t LWIPMemoryManager::count_total_align(uint32_t size, uint32_t align)
{
uint32_t buffers = size / get_pool_alloc_unit(align);
if (size % get_pool_alloc_unit(align) != 0) {
buffers++;
}
return buffers * align;
}
void LWIPMemoryManager::align_memory(struct pbuf *pbuf, uint32_t align)
{
if (!align) {
return;
}
struct pbuf *pbuf_start = pbuf;
while (pbuf) {
uint32_t remainder = reinterpret_cast<uint32_t>(pbuf->payload) % align;
if (remainder) {
uint32_t offset = align - remainder;
if (offset >= align) {
offset = align;
}
pbuf->payload = static_cast<char *>(pbuf->payload) + offset;
}
pbuf->len -= align;
pbuf = pbuf->next;
}
// Correct total lengths
set_total_len(pbuf_start);
}
void LWIPMemoryManager::set_total_len(struct pbuf *pbuf)
{
if (!pbuf->next) {
pbuf->tot_len = pbuf->len;
return;
}
uint32_t total_len;
struct pbuf *pbuf_tailing;
while (pbuf) {
total_len = pbuf->len;
pbuf_tailing = pbuf->next;
while (pbuf_tailing) {
total_len += pbuf_tailing->len;
pbuf_tailing = pbuf_tailing->next;
}
pbuf->tot_len = total_len;
pbuf = pbuf->next;
}
}

View File

@ -0,0 +1,175 @@
/* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LWIP_MEMORY_MANAGER_H
#define LWIP_MEMORY_MANAGER_H
#include "EMACMemoryManager.h"
class LWIPMemoryManager : public EMACMemoryManager {
public:
/**
* Allocates memory buffer from the heap
*
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
*
* @param size Size of the memory to allocate in bytes
* @param align Memory alignment requirement in bytes
* @return Allocated memory buffer, or NULL in case of error
*/
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
/**
* Allocates memory buffer chain from a pool
*
* Memory allocated from pool is contiguous if size is equal or less than
* (aligned) allocation unit, otherwise may be chained. Will typically come from
* fixed-size packet pool memory.
*
* @param size Total size of the memory to allocate in bytes
* @param align Memory alignment requirement for each buffer in bytes
* @return Allocated memory buffer chain, or NULL in case of error
*/
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
/**
* Get memory buffer pool allocation unit
*
* Returns the maximum size of contiguous memory that can be allocated from a pool.
*
* @param align Memory alignment requirement in bytes
* @return Contiguous memory size
*/
virtual uint32_t get_pool_alloc_unit(uint32_t align) const;
/**
* Free memory buffer chain
*
* If memory buffer is chained must point to the start of the chain. Frees all buffers
* from the chained list.
*
* @param buf Memory buffer chain to be freed.
*/
virtual void free(emac_mem_buf_t *buf);
/**
* Return total length of a memory buffer chain
*
* Returns a total length of this buffer and any following buffers in the chain.
*
* @param buf Memory buffer chain
* @return Total length in bytes
*/
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const;
/**
* Copy a memory buffer chain
*
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
* of the copied-to memory buffer chain, so chain total lengths must be the same.
*
* @param to_buf Memory buffer chain to copy to
* @param from_buf Memory buffer chain to copy from
*/
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
/**
* Concatenate two memory buffer chains
*
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
*
* @param to_buf Memory buffer chain to concatenate to
* @param cat_buf Memory buffer chain to concatenate
*/
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf);
/**
* Returns the next buffer
*
* Returns the next buffer from the memory buffer chain.
*
* @param buf Memory buffer
* @return The next memory buffer, or NULL if last
*/
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const;
/**
* Return pointer to the payload of the buffer
*
* @param buf Memory buffer
* @return Pointer to the payload
*/
virtual void *get_ptr(const emac_mem_buf_t *buf) const;
/**
* Return payload size of the buffer
*
* @param buf Memory buffer
* @return Size in bytes
*/
virtual uint32_t get_len(const emac_mem_buf_t *buf) const;
/**
* Sets the payload size of the buffer
*
* The allocated payload size will not change. It is not permitted
* to change the length of a buffer that is not the first (or only) in a chain.
*
* @param buf Memory buffer
* @param len Payload size, must be less or equal allocated size
*/
virtual void set_len(emac_mem_buf_t *buf, uint32_t len);
private:
/**
* Returns a total memory alignment size
*
* Calculates the total memory alignment size for a memory buffer chain.
* Used internally on pool allocation.
*
* @param size Size of the memory to allocate in bytes
* @param align Memory alignment requirement for each buffer in bytes
* @return Total alignment needed in bytes
*/
uint32_t count_total_align(uint32_t size, uint32_t align);
/**
* Aligns a memory buffer chain
*
* Aligns a memory buffer chain and updates lengths and total lengths
* accordingly. There needs to be enough overhead to do the alignment
* for all buffers.
*
* @param pbuf Memory buffer
* @param align Memory alignment requirement for each buffer in bytes
*/
void align_memory(struct pbuf *pbuf, uint32_t align);
/**
* Sets total lengths of a memory buffer chain
*
* Sets total length fields for a memory buffer chain based on buffer
* length fields. All total lengths are calculated again.
*
* @param pbuf Memory buffer
*/
void set_total_len(struct pbuf *pbuf);
};
#endif /* LWIP_MEMORY_MANAGER_H */

View File

@ -17,7 +17,6 @@
#ifndef LWIPSTACK_H_
#define LWIPSTACK_H_
#include "emac_stack_mem.h"
#include "lwip/tcpip.h"
#include "lwip/tcp.h"
#include "lwip/ip.h"
@ -27,6 +26,7 @@
#include "netsocket/nsapi_types.h"
#include "netsocket/EMAC.h"
#include "netsocket/OnboardNetworkStack.h"
#include "LWIPMemoryManager.h"
class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
@ -119,8 +119,9 @@ public:
static void netif_link_irq(struct netif *netif);
static void netif_status_irq(struct netif *netif);
#if LWIP_ETHERNET
static err_t emac_low_level_output(struct netif *netif, struct pbuf *p);
void emac_input(emac_stack_mem_t *buf);
void emac_input(emac_mem_buf_t *buf);
void emac_state_change(bool up);
#if LWIP_IGMP
static err_t emac_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group, enum netif_mac_filter_action action);
@ -130,9 +131,12 @@ public:
#endif
static err_t emac_if_init(struct netif *netif);
#endif
union {
#if LWIP_ETHERNET
EMAC *emac; /**< HW specific emac implementation */
#endif
void *hw; /**< alternative implementation pointer - used for PPP */
};
@ -161,6 +165,7 @@ public:
bool ppp;
mbed::Callback<void(nsapi_event_t, intptr_t)> client_callback;
struct netif netif;
LWIPMemoryManager *memory_manager;
};
/** Register a network interface with the IP stack
@ -417,6 +422,7 @@ protected:
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level,
int optname, void *optval, unsigned *optlen);
private:
struct mbed_lwip_socket {
bool in_use;
@ -471,6 +477,7 @@ private:
static void tcpip_init_irq(void *handle);
rtos::Semaphore tcpip_inited;
Interface *default_interface;
LWIPMemoryManager memory_manager;
};
#endif /* LWIPSTACK_H_ */

View File

@ -1,93 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2016 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "emac_stack_mem.h"
#include "pbuf.h"
emac_stack_mem_t *emac_stack_mem_alloc(uint32_t size, uint32_t align)
{
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
if (pbuf == NULL) {
return NULL;
}
if (align) {
uint32_t remainder = (uint32_t)pbuf->payload % align;
uint32_t offset = align - remainder;
if (offset >= align) {
offset = align;
}
pbuf->payload = (void*)((char*)pbuf->payload + offset);
pbuf->tot_len -= offset;
pbuf->len -= offset;
}
return (emac_stack_mem_t*)pbuf;
}
void emac_stack_mem_free(emac_stack_mem_t *mem)
{
pbuf_free((struct pbuf*)mem);
}
void emac_stack_mem_copy(emac_stack_mem_t *to, emac_stack_mem_t *from)
{
pbuf_copy((struct pbuf*)to, (struct pbuf*)from);
}
void *emac_stack_mem_ptr(emac_stack_mem_t *mem)
{
return ((struct pbuf*)mem)->payload;
}
uint32_t emac_stack_mem_len(emac_stack_mem_t *mem)
{
return ((struct pbuf*)mem)->len;
}
void emac_stack_mem_set_len(emac_stack_mem_t *mem, uint32_t len)
{
struct pbuf *pbuf = (struct pbuf*)mem;
pbuf->len = len;
}
emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_mem_chain_t **chain)
{
struct pbuf **list = (struct pbuf**)chain;
struct pbuf *head = *list;
*list = (*list)->next;
return (emac_stack_mem_t *)head;
}
uint32_t emac_stack_mem_chain_len(emac_stack_mem_chain_t *chain)
{
return ((struct pbuf*)chain)->tot_len;
}
void emac_stack_mem_set_chain_len(emac_stack_mem_chain_t *chain, uint32_t len)
{
struct pbuf *pbuf = (struct pbuf*)chain;
pbuf->tot_len = len;
}
void emac_stack_mem_ref(emac_stack_mem_t *mem)
{
pbuf_ref((struct pbuf*)mem);
}

View File

@ -1,26 +0,0 @@
/* Copyright (C) 2015 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef LWIPOPTS_CONF_H
#define LWIPOPTS_CONF_H
#define LWIP_TRANSPORT_ETHERNET 1
#define MEM_SIZE (1600 * 16)
#endif

View File

@ -145,7 +145,7 @@
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#undef PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
#else
#ifndef PBUF_POOL_BUFSIZE
#if LWIP_IPV6

View File

@ -19,7 +19,7 @@
#include <stdbool.h>
#include "Callback.h"
#include "emac_stack_mem.h"
#include "EMACMemoryManager.h"
// Nuvoton platform headers define EMAC - avoid the collision
#undef EMAC
@ -44,8 +44,8 @@ public:
*
* @param buf Received data
*/
//typedef void (*emac_link_input_fn)(void *data, emac_stack_mem_chain_t *buf);
typedef mbed::Callback<void (emac_stack_mem_chain_t *buf)> emac_link_input_cb_t;
//typedef void (*emac_link_input_fn)(void *data, emac_mem_buf_t *buf);
typedef mbed::Callback<void (emac_mem_buf_t *buf)> emac_link_input_cb_t;
/**
* Callback to be register with Emac interface and to be called for link status changes
@ -112,7 +112,7 @@ public:
* @param buf Packet to be send
* @return True if the packet was send successfully, False otherwise
*/
virtual bool link_out(emac_stack_mem_chain_t *buf) = 0;
virtual bool link_out(emac_mem_buf_t *buf) = 0;
/**
* Initializes the HW
@ -147,6 +147,11 @@ public:
*/
virtual void add_multicast_group(uint8_t *address) = 0;
/** Sets memory manager that is used to handle memory buffers
*
* @param mem_mngr Pointer to memory manager
*/
virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0;
};

View File

@ -0,0 +1,159 @@
/* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EMAC_MEMORY_MANAGER_H
#define EMAC_MEMORY_MANAGER_H
/**
* Emac interface memory manager
*
* This interface provides abstraction for memory modules used in different IP stacks (often to accommodate zero
* copy). Emac interface is required to accept output packets and provide received data using this stack-
* independent API. This header should be implemented for each IP stack, so that we keep emacs module independent.
*
* Emac memory interface uses memory buffer chains to store data. Data passed in either direction
* may be either contiguous (a single-buffer chain), or may consist of multiple buffers.
* Chaining of the buffers is made using singly-linked list. The Emac data-passing APIs do not specify
* alignment or structure of the chain in either direction.
*
* Memory buffers can be allocated either from heap or from memory pools. Heap buffers are always contiguous.
* Memory pool buffers may be either contiguous or chained depending on allocation size.
*
* On Emac interface buffer chain ownership is transferred. Emac must free buffer chain that it is given for
* link output and the stack must free the buffer chain that it is given for link input.
*
*/
typedef void emac_mem_buf_t; // Memory buffer
class EMACMemoryManager {
public:
/**
* Allocates memory buffer from the heap
*
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
*
* @param size Size of the memory to allocate in bytes
* @param align Memory alignment requirement in bytes
* @return Allocated memory buffer, or NULL in case of error
*/
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align) = 0;
/**
* Allocates memory buffer chain from a pool
*
* Memory allocated from pool is contiguous if size is equal or less than
* (aligned) allocation unit, otherwise may be chained. Will typically come from
* fixed-size packet pool memory.
*
* @param size Total size of the memory to allocate in bytes
* @param align Memory alignment requirement for each buffer in bytes
* @return Allocated memory buffer chain, or NULL in case of error
*/
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align) = 0;
/**
* Get memory buffer pool allocation unit
*
* Returns the maximum size of contiguous memory that can be allocated from a pool.
*
* @param align Memory alignment requirement in bytes
* @return Contiguous memory size
*/
virtual uint32_t get_pool_alloc_unit(uint32_t align) const = 0;
/**
* Free memory buffer chain
*
* If memory buffer is chained must point to the start of the chain. Frees all buffers
* from the chained list.
*
* @param buf Memory buffer chain to be freed.
*/
virtual void free(emac_mem_buf_t *buf) = 0;
/**
* Return total length of a memory buffer chain
*
* Returns a total length of this buffer and any following buffers in the chain.
*
* @param buf Memory buffer chain
* @return Total length in bytes
*/
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const = 0;
/**
* Copy a memory buffer chain
*
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
* of the copied-to memory buffer chain, so chain total lengths must be the same.
*
* @param to_buf Memory buffer chain to copy to
* @param from_buf Memory buffer chain to copy from
*/
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf) = 0;
/**
* Concatenate two memory buffer chains
*
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
*
* @param to_buf Memory buffer chain to concatenate to
* @param cat_buf Memory buffer chain to concatenate
*/
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf) = 0;
/**
* Returns the next buffer
*
* Returns the next buffer from the memory buffer chain.
*
* @param buf Memory buffer
* @return The next memory buffer, or NULL if last
*/
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const = 0;
/**
* Return pointer to the payload of the buffer
*
* @param buf Memory buffer
* @return Pointer to the payload
*/
virtual void *get_ptr(const emac_mem_buf_t *buf) const = 0;
/**
* Return payload size of the buffer
*
* @param buf Memory buffer
* @return Size in bytes
*/
virtual uint32_t get_len(const emac_mem_buf_t *buf) const = 0;
/**
* Sets the payload size of the buffer
*
* The allocated payload size will not change. It is not permitted
* to change the length of a buffer that is not the first (or only) in a chain.
*
* @param buf Memory buffer
* @param len Payload size, must be less or equal allocated size
*/
virtual void set_len(emac_mem_buf_t *buf, uint32_t len) = 0;
};
#endif /* EMAC_MEMORY_MANAGER_H */

View File

@ -1,111 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2016 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_EMAC_STACK_MEM_H
#define MBED_EMAC_STACK_MEM_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Stack memory module
*
* This interface provides abstraction for memory modules used in different IP stacks (often to accommodate zero copy).
* Emac interface may be required to accept output packets and provide received data using this stack specific API.
* This header should be implemented for each IP stack, so that we keep emacs module independent.
*/
typedef void emac_stack_mem_t;
typedef void emac_stack_mem_chain_t;
/**
* Allocates stack memory
*
* @param size Size of memory to allocate
* @param align Memory alignment requirements
* @return Allocated memory struct, or NULL in case of error
*/
emac_stack_mem_t *emac_stack_mem_alloc(uint32_t size, uint32_t align);
/**
* Free memory allocated using @a stack_mem_alloc
*
* @param mem Memory to be freed
*/
void emac_stack_mem_free(emac_stack_mem_t *mem);
/**
* Copy memory
*
* @param to Memory to copy to
* @param from Memory to copy from
*/
void emac_stack_mem_copy(emac_stack_mem_t *to, emac_stack_mem_t *from);
/**
* Return pointer to the payload
*
* @param mem Memory structure
* @return Pointer to the payload
*/
void *emac_stack_mem_ptr(emac_stack_mem_t *mem);
/**
* Return actual payload size
*
* @param mem Memory structure
* @return Size in bytes
*/
uint32_t emac_stack_mem_len(emac_stack_mem_t *mem);
/**
* Sets the actual payload size (the allocated payload size will not change)
*
* @param mem Memory structure
* @param len Actual payload size
*/
void emac_stack_mem_set_len(emac_stack_mem_t *mem, uint32_t len);
/**
* Returns first memory structure from the list and move the head to point to the next node
*
* @param chain Pointer to the list
* @return First memory structure from the list
*/
emac_stack_mem_t *emac_stack_mem_chain_dequeue(emac_stack_mem_chain_t **chain);
/**
* Return total length of the memory chain
*
* @param chain Memory chain
* @return Chain length
*/
uint32_t emac_stack_mem_chain_len(emac_stack_mem_chain_t *chain);
/**
* Set total length of the memory chain
*
* @param chain Memory chain
* @param len Total chain length
*/
void emac_stack_mem_set_chain_len(emac_stack_mem_chain_t *chain, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif /* EMAC_MBED_STACK_MEM_h */