ChibiOS 21.11.4
chmemcore.c
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chmemcore.c
22 * @brief Core memory manager code.
23 *
24 * @addtogroup oslib_memcore
25 * @details Core Memory Manager related APIs and services.
26 * <h2>Operation mode</h2>
27 * The core memory manager is a simplified allocator that only
28 * allows to allocate memory blocks without the possibility to
29 * free them.<br>
30 * This allocator is meant as a memory blocks provider for the
31 * other allocators such as:
32 * - C-Runtime allocator (through a compiler specific adapter module).
33 * - Heap allocator (see @ref oslib_memheaps).
34 * - Memory pools allocator (see @ref oslib_mempools).
35 * .
36 * By having a centralized memory provider the various allocators
37 * can coexist and share the main memory.<br>
38 * This allocator, alone, is also useful for very simple
39 * applications that just require a simple way to get memory
40 * blocks.
41 * @pre In order to use the core memory manager APIs the @p CH_CFG_USE_MEMCORE
42 * option must be enabled in @p chconf.h.
43 * @note Compatible with RT and NIL.
44 * @{
45 */
46
47#include "ch.h"
48
49#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
50
51/*===========================================================================*/
52/* Module exported variables. */
53/*===========================================================================*/
54
55/**
56 * @brief Memory core descriptor.
57 */
59
60/*===========================================================================*/
61/* Module local types. */
62/*===========================================================================*/
63
64/*===========================================================================*/
65/* Module local variables. */
66/*===========================================================================*/
67
68/*===========================================================================*/
69/* Module local functions. */
70/*===========================================================================*/
71
72/*===========================================================================*/
73/* Module exported functions. */
74/*===========================================================================*/
75
76/**
77 * @brief Low level memory manager initialization.
78 *
79 * @notapi
80 */
81void __core_init(void) {
82#if CH_CFG_MEMCORE_SIZE == 0
83 extern uint8_t __heap_base__[];
84 extern uint8_t __heap_end__[];
85
86 /*lint -save -e9033 [10.8] Required cast operations.*/
87 ch_memcore.basemem = __heap_base__;
88 ch_memcore.topmem = __heap_end__;
89 /*lint restore*/
90#else
91 static uint8_t static_heap[CH_CFG_MEMCORE_SIZE];
92
93 ch_memcore.basemem = &static_heap[0];
94 ch_memcore.topmem = &static_heap[CH_CFG_MEMCORE_SIZE];
95#endif
96}
97
98/**
99 * @brief Allocates a memory block starting from the lowest address upward.
100 * @details This function allocates a block of @p offset + @p size bytes. The
101 * returned pointer has @p offset bytes before its address and
102 * @p size bytes after.
103 *
104 * @param[in] size the size of the block to be allocated.
105 * @param[in] align desired memory alignment
106 * @param[in] offset aligned pointer offset
107 * @return A pointer to the allocated memory block.
108 * @retval NULL allocation failed, core memory exhausted.
109 *
110 * @iclass
111 */
112void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset) {
113 uint8_t *p, *next;
114
117
118 p = (uint8_t *)MEM_ALIGN_NEXT(ch_memcore.basemem + offset, align);
119 next = p + size;
120
121 /* Considering also the case where there is numeric overflow.*/
122 if ((next > ch_memcore.topmem) || (next < ch_memcore.basemem)) {
123 return NULL;
124 }
125
126 ch_memcore.basemem = next;
127
128 return p;
129}
130
131/**
132 * @brief Allocates a memory block starting from the top address downward.
133 * @details This function allocates a block of @p offset + @p size bytes. The
134 * returned pointer has @p offset bytes before its address and
135 * @p size bytes after.
136 *
137 * @param[in] size the size of the block to be allocated.
138 * @param[in] align desired memory alignment
139 * @param[in] offset aligned pointer offset
140 * @return A pointer to the allocated memory block.
141 * @retval NULL allocation failed, core memory exhausted.
142 *
143 * @iclass
144 */
145void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset) {
146 uint8_t *p, *prev;
147
150
151 p = (uint8_t *)MEM_ALIGN_PREV(ch_memcore.topmem - size, align);
152 prev = p - offset;
153
154 /* Considering also the case where there is numeric overflow.*/
155 if ((prev < ch_memcore.basemem) || (prev > ch_memcore.topmem)) {
156 return NULL;
157 }
158
159 ch_memcore.topmem = prev;
160
161 return p;
162}
163
164/**
165 * @brief Allocates a memory block starting from the lowest address upward.
166 * @details This function allocates a block of @p offset + @p size bytes. The
167 * returned pointer has @p offset bytes before its address and
168 * @p size bytes after.
169 *
170 * @param[in] size the size of the block to be allocated.
171 * @param[in] align desired memory alignment
172 * @param[in] offset aligned pointer offset
173 * @return A pointer to the allocated memory block.
174 * @retval NULL allocation failed, core memory exhausted.
175 *
176 * @api
177 */
178void *chCoreAllocFromBase(size_t size, unsigned align, size_t offset) {
179 void *p;
180
181 chSysLock();
182 p = chCoreAllocFromBaseI(size, align, offset);
183 chSysUnlock();
184
185 return p;
186}
187
188/**
189 * @brief Allocates a memory block starting from the top address downward.
190 * @details This function allocates a block of @p offset + @p size bytes. The
191 * returned pointer has @p offset bytes before its address and
192 * @p size bytes after.
193 *
194 * @param[in] size the size of the block to be allocated.
195 * @param[in] align desired memory alignment
196 * @param[in] offset aligned pointer offset
197 * @return A pointer to the allocated memory block.
198 * @retval NULL allocation failed, core memory exhausted.
199 *
200 * @api
201 */
202void *chCoreAllocFromTop(size_t size, unsigned align, size_t offset) {
203 void *p;
204
205 chSysLock();
206 p = chCoreAllocFromTopI(size, align, offset);
207 chSysUnlock();
208
209 return p;
210}
211
212/**
213 * @brief Core memory status.
214 *
215 * @return The size, in bytes, of the free core memory.
216 *
217 * @xclass
218 */
219size_t chCoreGetStatusX(void) {
220
221 /*lint -save -e9033 [10.8] The cast is safe.*/
222 return (size_t)(ch_memcore.topmem - ch_memcore.basemem);
223 /*lint -restore*/
224}
225#endif /* CH_CFG_USE_MEMCORE == TRUE */
226
227/** @} */
#define chSysUnlock()
Leaves the kernel lock state.
#define chSysLock()
Enters the kernel lock state.
#define chDbgCheck(c)
Function parameters check.
Definition chdebug.h:118
#define chDbgCheckClassI()
Definition chdebug.h:99
#define CH_CFG_MEMCORE_SIZE
Managed RAM size.
#define MEM_ALIGN_PREV(p, a)
Aligns to the previous aligned memory address.
Definition chalign.h:69
#define MEM_IS_VALID_ALIGNMENT(a)
Returns whatever a constant is a valid alignment.
Definition chalign.h:99
#define MEM_ALIGN_NEXT(p, a)
Aligns to the next aligned memory address.
Definition chalign.h:80
void * chCoreAllocFromTop(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the top address downward.
Definition chmemcore.c:202
void * chCoreAllocFromBase(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the lowest address upward.
Definition chmemcore.c:178
size_t chCoreGetStatusX(void)
Core memory status.
Definition chmemcore.c:219
memcore_t ch_memcore
Memory core descriptor.
Definition chmemcore.c:58
void * chCoreAllocFromTopI(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the top address downward.
Definition chmemcore.c:145
void * chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the lowest address upward.
Definition chmemcore.c:112
void __core_init(void)
Low level memory manager initialization.
Definition chmemcore.c:81
Type of memory core object.
Definition chmemcore.h:81