Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
NanostackMemoryManager.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2016 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "nsdynmemLIB.h" 00018 #include <string.h> 00019 #include "mbed_assert.h" 00020 #include "NanostackMemoryManager.h" 00021 00022 struct ns_stack_mem_t { 00023 ns_stack_mem_t *next; 00024 void *payload; 00025 uint32_t len; 00026 uint8_t mem[]; 00027 }; 00028 00029 emac_mem_buf_t *NanostackMemoryManager::alloc_heap(uint32_t size, uint32_t align) 00030 { 00031 ns_stack_mem_t *buf = static_cast<ns_stack_mem_t *>(ns_dyn_mem_temporary_alloc(sizeof(ns_stack_mem_t) + size + align)); 00032 if (buf == NULL) { 00033 return NULL; 00034 } 00035 00036 buf->next = NULL; 00037 buf->payload = buf->mem; 00038 buf->len = size; 00039 00040 if (align) { 00041 uint32_t remainder = reinterpret_cast<uint32_t>(buf->payload) % align; 00042 if (remainder) { 00043 uint32_t offset = align - remainder; 00044 if (offset >= align) { 00045 offset = align; 00046 } 00047 00048 buf->payload = static_cast<char *>(buf->payload) + offset; 00049 } 00050 } 00051 00052 return static_cast<emac_mem_buf_t *>(buf); 00053 } 00054 00055 emac_mem_buf_t *NanostackMemoryManager::alloc_pool(uint32_t size, uint32_t align) 00056 { 00057 return alloc_heap(size, align); 00058 } 00059 00060 uint32_t NanostackMemoryManager::get_pool_alloc_unit(uint32_t align) const 00061 { 00062 return 1536; // arbitrary nicely-aligned number big enough for Ethernet 00063 } 00064 00065 void NanostackMemoryManager::free(emac_mem_buf_t *mem) 00066 { 00067 ns_dyn_mem_free(mem); 00068 } 00069 00070 uint32_t NanostackMemoryManager::get_total_len(const emac_mem_buf_t *buf) const 00071 { 00072 const ns_stack_mem_t *mem = static_cast<const ns_stack_mem_t *>(buf); 00073 uint32_t total = 0; 00074 00075 while (mem) { 00076 total += mem->len; 00077 mem = mem->next; 00078 } 00079 return total; 00080 } 00081 00082 void NanostackMemoryManager::copy(emac_mem_buf_t *to, const emac_mem_buf_t *from) 00083 { 00084 ns_stack_mem_t *to_mem = static_cast<ns_stack_mem_t *>(to); 00085 const ns_stack_mem_t *from_mem = static_cast<const ns_stack_mem_t *>(from); 00086 MBED_ASSERT(get_total_len(to) >= get_total_len(from)); 00087 00088 uint32_t to_offset = 0; 00089 uint32_t from_offset = 0; 00090 while (from_mem) { 00091 uint32_t to_avail = to_mem->len - to_offset; 00092 uint32_t from_avail = from_mem->len - from_offset; 00093 uint32_t chunk = to_avail < from_avail ? to_avail : from_avail; 00094 uint8_t *to_ptr = static_cast<uint8_t *>(to_mem->payload) + to_offset; 00095 const uint8_t *from_ptr = static_cast<const uint8_t *>(from_mem->payload) + from_offset; 00096 memcpy(to_ptr, from_ptr, chunk); 00097 to_offset += chunk; 00098 if (to_offset == to_mem->len) { 00099 to_mem = to_mem->next; 00100 to_offset = 0; 00101 } 00102 from_offset += chunk; 00103 if (from_offset == from_mem->len) { 00104 from_mem = from_mem->next; 00105 from_offset = 0; 00106 } 00107 } 00108 } 00109 00110 void NanostackMemoryManager::cat(emac_mem_buf_t *to_buf, emac_mem_buf_t *cat_buf) 00111 { 00112 ns_stack_mem_t *to_mem = static_cast<ns_stack_mem_t *>(to_buf); 00113 ns_stack_mem_t *cat_mem = static_cast<ns_stack_mem_t *>(cat_buf); 00114 00115 while (to_mem->next) { 00116 to_mem = to_mem->next; 00117 } 00118 00119 to_mem->next = cat_mem; 00120 } 00121 00122 emac_mem_buf_t *NanostackMemoryManager::get_next(const emac_mem_buf_t *buf) const 00123 { 00124 return static_cast<const ns_stack_mem_t *>(buf)->next; 00125 } 00126 00127 void *NanostackMemoryManager::get_ptr(const emac_mem_buf_t *buf) const 00128 { 00129 return static_cast<const ns_stack_mem_t *>(buf)->payload; 00130 } 00131 00132 uint32_t NanostackMemoryManager::get_len(const emac_mem_buf_t *buf) const 00133 { 00134 return static_cast<const ns_stack_mem_t *>(buf)->len; 00135 } 00136 00137 void NanostackMemoryManager::set_len(emac_mem_buf_t *buf, uint32_t len) 00138 { 00139 ns_stack_mem_t *mem = static_cast<ns_stack_mem_t *>(buf); 00140 00141 mem->len = len; 00142 }
Generated on Tue Jul 12 2022 13:54:36 by
