ChibiOS  21.6.0
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  */
81 void __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  */
112 void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset) {
113  uint8_t *p, *next;
114 
115  chDbgCheckClassI();
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  */
145 void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset) {
146  uint8_t *p, *prev;
147 
148  chDbgCheckClassI();
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  */
178 void *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  */
202 void *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  */
219 size_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 /** @} */
memcore_t::basemem
uint8_t * basemem
Next free address.
Definition: chmemcore.h:85
CH_CFG_MEMCORE_SIZE
#define CH_CFG_MEMCORE_SIZE
Managed RAM size.
Definition: rt/templates/chconf.h:387
chCoreAllocFromBase
void * chCoreAllocFromBase(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the lowest address upward.
Definition: chmemcore.c:178
chDbgCheck
#define chDbgCheck(c)
Function parameters check.
Definition: chdebug.h:118
ch_memcore
memcore_t ch_memcore
Memory core descriptor.
Definition: chmemcore.c:58
memcore_t
Type of memory core object.
Definition: chmemcore.h:81
MEM_ALIGN_PREV
#define MEM_ALIGN_PREV(p, a)
Aligns to the previous aligned memory address.
Definition: chalign.h:69
MEM_ALIGN_NEXT
#define MEM_ALIGN_NEXT(p, a)
Aligns to the next aligned memory address.
Definition: chalign.h:80
chCoreAllocFromBaseI
void * chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the lowest address upward.
Definition: chmemcore.c:112
__core_init
void __core_init(void)
Low level memory manager initialization.
Definition: chmemcore.c:81
chCoreGetStatusX
size_t chCoreGetStatusX(void)
Core memory status.
Definition: chmemcore.c:219
chCoreAllocFromTop
void * chCoreAllocFromTop(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the top address downward.
Definition: chmemcore.c:202
memcore_t::topmem
uint8_t * topmem
Final address.
Definition: chmemcore.h:89
MEM_IS_VALID_ALIGNMENT
#define MEM_IS_VALID_ALIGNMENT(a)
Returns whatever a constant is a valid alignment.
Definition: chalign.h:99
chCoreAllocFromTopI
void * chCoreAllocFromTopI(size_t size, unsigned align, size_t offset)
Allocates a memory block starting from the top address downward.
Definition: chmemcore.c:145
chSysUnlock
#define chSysUnlock()
Leaves the kernel lock state.
Definition: nil/include/ch.h:1053
chSysLock
#define chSysLock()
Enters the kernel lock state.
Definition: nil/include/ch.h:1043