Skip to content

Commit 16c988c

Browse files
Mika Leppänenkjbracey
authored andcommitted
Created memory manager class to netsocket and updated lwip to use it
instead of old memory interface.
1 parent 0e8c098 commit 16c988c

File tree

11 files changed

+514
-240
lines changed

11 files changed

+514
-240
lines changed

features/FEATURE_LWIP/lwip-interface/LWIPInterface.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <stdbool.h>
2323
#include <string.h>
2424
#include <new>
25+
#include <stdint.h>
2526

2627
#include "lwip/opt.h"
2728
#include "lwip/api.h"
@@ -340,6 +341,7 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
340341
return NSAPI_ERROR_NO_MEMORY;
341342
}
342343
interface->emac = &emac;
344+
interface->memory_manager = &memory_manager;
343345
interface->ppp = false;
344346

345347
#if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
@@ -485,7 +487,6 @@ nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *ne
485487
client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
486488
}
487489

488-
netif_set_up(&netif);
489490
if (ppp) {
490491
err_t err = ppp_lwip_connect(hw);
491492
if (err) {

features/FEATURE_LWIP/lwip-interface/LWIPInterfaceEMAC.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "emac_stack_mem.h"
1817
#include "lwip/tcpip.h"
1918
#include "lwip/tcp.h"
2019
#include "lwip/ip.h"
@@ -29,12 +28,16 @@
2928

3029
err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p)
3130
{
31+
/* Increase reference counter since lwip stores handle to pbuf and frees
32+
it after output */
33+
pbuf_ref(p);
34+
3235
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
3336
bool ret = mbed_if->emac->link_out(p);
3437
return ret ? ERR_OK : ERR_IF;
3538
}
3639

37-
void LWIP::Interface::emac_input(emac_stack_mem_t *buf)
40+
void LWIP::Interface::emac_input(emac_mem_buf_t *buf)
3841
{
3942
struct pbuf *p = static_cast<struct pbuf *>(buf);
4043

@@ -136,6 +139,7 @@ err_t LWIP::Interface::emac_if_init(struct netif *netif)
136139
int err = ERR_OK;
137140
LWIP::Interface *mbed_if = static_cast<LWIP::Interface *>(netif->state);
138141

142+
mbed_if->emac->set_memory_manager(*mbed_if->memory_manager);
139143
mbed_if->emac->set_link_input_cb(mbed::callback(mbed_if, &LWIP::Interface::emac_input));
140144
mbed_if->emac->set_link_state_cb(mbed::callback(mbed_if, &LWIP::Interface::emac_state_change));
141145

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/* Copyright (c) 2017 ARM Limited
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "pbuf.h"
17+
#include "LWIPMemoryManager.h"
18+
19+
emac_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
20+
{
21+
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
22+
if (pbuf == NULL) {
23+
return NULL;
24+
}
25+
26+
align_memory(pbuf, align);
27+
28+
return static_cast<emac_mem_buf_t *>(pbuf);
29+
}
30+
31+
emac_mem_buf_t *LWIPMemoryManager::alloc_pool(uint32_t size, uint32_t align)
32+
{
33+
uint32_t total_align = count_total_align(size, align);
34+
35+
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + total_align, PBUF_POOL);
36+
if (pbuf == NULL) {
37+
return NULL;
38+
}
39+
40+
align_memory(pbuf, align);
41+
42+
return static_cast<emac_mem_buf_t *>(pbuf);
43+
}
44+
45+
uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
46+
{
47+
uint32_t alloc_unit = LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) - align;
48+
return alloc_unit;
49+
}
50+
51+
void LWIPMemoryManager::free(emac_mem_buf_t *buf)
52+
{
53+
pbuf_free(static_cast<struct pbuf *>(buf));
54+
}
55+
56+
uint32_t LWIPMemoryManager::get_total_len(const emac_mem_buf_t *buf) const
57+
{
58+
return (static_cast<const struct pbuf *>(buf))->tot_len;
59+
}
60+
61+
void LWIPMemoryManager::copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf)
62+
{
63+
pbuf_copy(static_cast<struct pbuf *>(to_buf), static_cast<const struct pbuf *>(from_buf));
64+
}
65+
66+
void LWIPMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf)
67+
{
68+
pbuf_cat(static_cast<struct pbuf *>(to_buf), static_cast<struct pbuf *>(cat_buf));
69+
}
70+
71+
emac_mem_buf_t *LWIPMemoryManager::get_next(const emac_mem_buf_t *buf) const
72+
{
73+
if (!buf) {
74+
return NULL;
75+
}
76+
struct pbuf *next = (static_cast<const struct pbuf *>(buf))->next;
77+
return static_cast<emac_mem_buf_t *>(next);
78+
}
79+
80+
void *LWIPMemoryManager::get_ptr(const emac_mem_buf_t *buf) const
81+
{
82+
return (static_cast<const struct pbuf *>(buf))->payload;
83+
}
84+
85+
uint32_t LWIPMemoryManager::get_len(const emac_mem_buf_t *buf) const
86+
{
87+
return (static_cast<const struct pbuf *>(buf))->len;
88+
}
89+
90+
void LWIPMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len)
91+
{
92+
struct pbuf *pbuf = static_cast<struct pbuf *>(buf);
93+
pbuf->len = len;
94+
set_total_len(pbuf);
95+
}
96+
97+
uint32_t LWIPMemoryManager::count_total_align(uint32_t size, uint32_t align)
98+
{
99+
uint32_t buffers = size / get_pool_alloc_unit(align);
100+
if (size % get_pool_alloc_unit(align) != 0) {
101+
buffers++;
102+
}
103+
return buffers * align;
104+
}
105+
106+
void LWIPMemoryManager::align_memory(struct pbuf *pbuf, uint32_t align)
107+
{
108+
if (!align) {
109+
return;
110+
}
111+
112+
struct pbuf *pbuf_start = pbuf;
113+
114+
while (pbuf) {
115+
uint32_t remainder = reinterpret_cast<uint32_t>(pbuf->payload) % align;
116+
if (remainder) {
117+
uint32_t offset = align - remainder;
118+
if (offset >= align) {
119+
offset = align;
120+
}
121+
pbuf->payload = static_cast<char *>(pbuf->payload) + offset;
122+
}
123+
pbuf->len -= align;
124+
pbuf = pbuf->next;
125+
}
126+
127+
// Correct total lengths
128+
set_total_len(pbuf_start);
129+
}
130+
131+
void LWIPMemoryManager::set_total_len(struct pbuf *pbuf)
132+
{
133+
if (!pbuf->next) {
134+
pbuf->tot_len = pbuf->len;
135+
return;
136+
}
137+
138+
uint32_t total_len;
139+
struct pbuf *pbuf_tailing;
140+
141+
while (pbuf) {
142+
total_len = pbuf->len;
143+
144+
pbuf_tailing = pbuf->next;
145+
while (pbuf_tailing) {
146+
total_len += pbuf_tailing->len;
147+
pbuf_tailing = pbuf_tailing->next;
148+
}
149+
150+
pbuf->tot_len = total_len;
151+
pbuf = pbuf->next;
152+
}
153+
}
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/* Copyright (c) 2017 ARM Limited
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#ifndef LWIP_MEMORY_MANAGER_H
17+
#define LWIP_MEMORY_MANAGER_H
18+
19+
#include "EMACMemoryManager.h"
20+
21+
class LWIPMemoryManager : public EMACMemoryManager {
22+
public:
23+
24+
/**
25+
* Allocates memory buffer from the heap
26+
*
27+
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
28+
*
29+
* @param size Size of the memory to allocate in bytes
30+
* @param align Memory alignment requirement in bytes
31+
* @return Allocated memory buffer, or NULL in case of error
32+
*/
33+
virtual emac_mem_buf_t *alloc_heap(uint32_t size, uint32_t align);
34+
35+
/**
36+
* Allocates memory buffer chain from a pool
37+
*
38+
* Memory allocated from pool is contiguous if size is equal or less than
39+
* (aligned) allocation unit, otherwise may be chained. Will typically come from
40+
* fixed-size packet pool memory.
41+
*
42+
* @param size Total size of the memory to allocate in bytes
43+
* @param align Memory alignment requirement for each buffer in bytes
44+
* @return Allocated memory buffer chain, or NULL in case of error
45+
*/
46+
virtual emac_mem_buf_t *alloc_pool(uint32_t size, uint32_t align);
47+
48+
/**
49+
* Get memory buffer pool allocation unit
50+
*
51+
* Returns the maximum size of contiguous memory that can be allocated from a pool.
52+
*
53+
* @param align Memory alignment requirement in bytes
54+
* @return Contiguous memory size
55+
*/
56+
virtual uint32_t get_pool_alloc_unit(uint32_t align) const;
57+
58+
/**
59+
* Free memory buffer chain
60+
*
61+
* If memory buffer is chained must point to the start of the chain. Frees all buffers
62+
* from the chained list.
63+
*
64+
* @param buf Memory buffer chain to be freed.
65+
*/
66+
virtual void free(emac_mem_buf_t *buf);
67+
68+
/**
69+
* Return total length of a memory buffer chain
70+
*
71+
* Returns a total length of this buffer and any following buffers in the chain.
72+
*
73+
* @param buf Memory buffer chain
74+
* @return Total length in bytes
75+
*/
76+
virtual uint32_t get_total_len(const emac_mem_buf_t *buf) const;
77+
78+
/**
79+
* Copy a memory buffer chain
80+
*
81+
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
82+
* of the copied-to memory buffer chain, so chain total lengths must be the same.
83+
*
84+
* @param to_buf Memory buffer chain to copy to
85+
* @param from_buf Memory buffer chain to copy from
86+
*/
87+
virtual void copy(emac_mem_buf_t *to_buf, const emac_mem_buf_t *from_buf);
88+
89+
/**
90+
* Concatenate two memory buffer chains
91+
*
92+
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
93+
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
94+
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
95+
*
96+
* @param to_buf Memory buffer chain to concatenate to
97+
* @param cat_buf Memory buffer chain to concatenate
98+
*/
99+
virtual void cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf);
100+
101+
/**
102+
* Returns the next buffer
103+
*
104+
* Returns the next buffer from the memory buffer chain.
105+
*
106+
* @param buf Memory buffer
107+
* @return The next memory buffer, or NULL if last
108+
*/
109+
virtual emac_mem_buf_t *get_next(const emac_mem_buf_t *buf) const;
110+
111+
/**
112+
* Return pointer to the payload of the buffer
113+
*
114+
* @param buf Memory buffer
115+
* @return Pointer to the payload
116+
*/
117+
virtual void *get_ptr(const emac_mem_buf_t *buf) const;
118+
119+
/**
120+
* Return payload size of the buffer
121+
*
122+
* @param buf Memory buffer
123+
* @return Size in bytes
124+
*/
125+
virtual uint32_t get_len(const emac_mem_buf_t *buf) const;
126+
127+
/**
128+
* Sets the payload size of the buffer
129+
*
130+
* The allocated payload size will not change. It is not permitted
131+
* to change the length of a buffer that is not the first (or only) in a chain.
132+
*
133+
* @param buf Memory buffer
134+
* @param len Payload size, must be less or equal allocated size
135+
*/
136+
virtual void set_len(emac_mem_buf_t *buf, uint32_t len);
137+
138+
private:
139+
140+
/**
141+
* Returns a total memory alignment size
142+
*
143+
* Calculates the total memory alignment size for a memory buffer chain.
144+
* Used internally on pool allocation.
145+
*
146+
* @param size Size of the memory to allocate in bytes
147+
* @param align Memory alignment requirement for each buffer in bytes
148+
* @return Total alignment needed in bytes
149+
*/
150+
uint32_t count_total_align(uint32_t size, uint32_t align);
151+
152+
/**
153+
* Aligns a memory buffer chain
154+
*
155+
* Aligns a memory buffer chain and updates lengths and total lengths
156+
* accordingly. There needs to be enough overhead to do the alignment
157+
* for all buffers.
158+
*
159+
* @param pbuf Memory buffer
160+
* @param align Memory alignment requirement for each buffer in bytes
161+
*/
162+
void align_memory(struct pbuf *pbuf, uint32_t align);
163+
164+
/**
165+
* Sets total lengths of a memory buffer chain
166+
*
167+
* Sets total length fields for a memory buffer chain based on buffer
168+
* length fields. All total lengths are calculated again.
169+
*
170+
* @param pbuf Memory buffer
171+
*/
172+
void set_total_len(struct pbuf *pbuf);
173+
};
174+
175+
#endif /* LWIP_MEMORY_MANAGER_H */

0 commit comments

Comments
 (0)