| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
os_mem.c
Go to the documentation of this file.
1 /*
2 ************************************************************************************************************************
3 * uC/OS-III
4 * The Real-Time Kernel
5 *
6 * (c) Copyright 2009-2012; Micrium, Inc.; Weston, FL
7 * All rights reserved. Protected by international copyright laws.
8 *
9 * MEMORY PARTITION MANAGEMENT
10 *
11 * File : OS_MEM.C
12 * By : JJL
13 * Version : V3.03.00
14 *
15 * LICENSING TERMS:
16 * ---------------
17 * uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
18 * for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
19 * product then, you need to contact Micrium to properly license uC/OS-III for its use in your
20 * application/product. We provide ALL the source code for your convenience and to help you
21 * experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
22 * it commercially without paying a licensing fee.
23 *
24 * Knowledge of the source code may NOT be used to develop a similar product.
25 *
26 * Please help us continue to provide the embedded community with the finest software available.
27 * Your honesty is greatly appreciated.
28 *
29 * You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
30 ************************************************************************************************************************
31 */
32
33 #define MICRIUM_SOURCE
34 #include <os.h>
35
36 #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
37 const CPU_CHAR *os_mem__c = "$Id: $";
38 #endif
39
40
41 #if OS_CFG_MEM_EN > 0u
42 /*
43 ************************************************************************************************************************
44 * CREATE A MEMORY PARTITION
45 *
46 * Description : Create a fixed-sized memory partition that will be managed by uC/OS-III.
47 *
48 * Arguments : p_mem is a pointer to a memory partition control block which is allocated in user memory space.
49 *
50 * p_name is a pointer to an ASCII string to provide a name to the memory partition.
51 *
52 * p_addr is the starting address of the memory partition
53 *
54 * n_blks is the number of memory blocks to create from the partition.
55 *
56 * blk_size is the size (in bytes) of each block in the memory partition.
57 *
58 * p_err is a pointer to a variable containing an error message which will be set by this function to
59 * either:
60 *
61 * OS_ERR_NONE if the memory partition has been created correctly.
62 * OS_ERR_ILLEGAL_CREATE_RUN_TIME if you are trying to create the memory partition after you
63 * called OSSafetyCriticalStart().
64 * OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2)
65 * OS_ERR_MEM_INVALID_P_ADDR if you are specifying an invalid address for the memory
66 * storage of the partition or, the block does not align on a
67 * pointer boundary
68 * OS_ERR_MEM_INVALID_SIZE user specified an invalid block size
69 * - must be greater than the size of a pointer
70 * - must be able to hold an integral number of pointers
71 * Returns : none
72 ************************************************************************************************************************
73 */
74
75 void OSMemCreate (OS_MEM *p_mem,
76 CPU_CHAR *p_name,
77 void *p_addr,
78 OS_MEM_QTY n_blks,
79 OS_MEM_SIZE blk_size,
80 OS_ERR *p_err)
81 {
82 #if OS_CFG_ARG_CHK_EN > 0u
83 CPU_DATA align_msk;
84 #endif
85 OS_MEM_QTY i;
86 OS_MEM_QTY loops;
87 CPU_INT08U *p_blk;
88 void **p_link;
89 CPU_SR_ALLOC();
90
91
92
93 #ifdef OS_SAFETY_CRITICAL
94 if (p_err == (OS_ERR *)0) {
95 OS_SAFETY_CRITICAL_EXCEPTION();
96 return;
97 }
98 #endif
99
100 #ifdef OS_SAFETY_CRITICAL_IEC61508
101 if (OSSafetyCriticalStartFlag == DEF_TRUE) {
102 *p_err = OS_ERR_ILLEGAL_CREATE_RUN_TIME;
103 return;
104 }
105 #endif
106
107 #if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
108 if (OSIntNestingCtr > (OS_NESTING_CTR)0) { /* Not allowed to call from an ISR */
109 *p_err = OS_ERR_MEM_CREATE_ISR;
110 return;
111 }
112 #endif
113
114 #if OS_CFG_ARG_CHK_EN > 0u
115 if (p_addr == (void *)0) { /* Must pass a valid address for the memory part. */
116 *p_err = OS_ERR_MEM_INVALID_P_ADDR;
117 return;
118 }
119 if (n_blks < (OS_MEM_QTY)2) { /* Must have at least 2 blocks per partition */
120 *p_err = OS_ERR_MEM_INVALID_BLKS;
121 return;
122 }
123 if (blk_size < sizeof(void *)) { /* Must contain space for at least a pointer */
124 *p_err = OS_ERR_MEM_INVALID_SIZE;
125 return;
126 }
127 align_msk = sizeof(void *) - 1u;
128 if (align_msk > 0) {
129 if (((CPU_ADDR)p_addr & align_msk) != 0u){ /* Must be pointer size aligned */
130 *p_err = OS_ERR_MEM_INVALID_P_ADDR;
131 return;
132 }
133 if ((blk_size & align_msk) != 0u) { /* Block size must be a multiple address size */
134 *p_err = OS_ERR_MEM_INVALID_SIZE;
135 return;
136 }
137 }
138 #endif
139
140 p_link = (void **)p_addr; /* Create linked list of free memory blocks */
141 p_blk = (CPU_INT08U *)p_addr;
142 loops = n_blks - 1u;
143 for (i = 0u; i < loops; i++) {
144 p_blk += blk_size;
145 *p_link = (void *)p_blk; /* Save pointer to NEXT block in CURRENT block */
146 p_link = (void **)(void *)p_blk; /* Position to NEXT block */
147 }
148 *p_link = (void *)0; /* Last memory block points to NULL */
149
150 OS_CRITICAL_ENTER();
151 p_mem->Type = OS_OBJ_TYPE_MEM; /* Set the type of object */
152 p_mem->NamePtr = p_name; /* Save name of memory partition */
153 p_mem->AddrPtr = p_addr; /* Store start address of memory partition */
154 p_mem->FreeListPtr = p_addr; /* Initialize pointer to pool of free blocks */
155 p_mem->NbrFree = n_blks; /* Store number of free blocks in MCB */
156 p_mem->NbrMax = n_blks;
157 p_mem->BlkSize = blk_size; /* Store block size of each memory blocks */
158
159 #if OS_CFG_DBG_EN > 0u
160 OS_MemDbgListAdd(p_mem);
161 #endif
162
163 OSMemQty++;
164
165 OS_CRITICAL_EXIT_NO_SCHED();
166 *p_err = OS_ERR_NONE;
167 }
168
169 /*$PAGE*/
170 /*
171 ************************************************************************************************************************
172 * GET A MEMORY BLOCK
173 *
174 * Description : Get a memory block from a partition
175 *
176 * Arguments : p_mem is a pointer to the memory partition control block
177 *
178 * p_err is a pointer to a variable containing an error message which will be set by this function to
179 * either:
180 *
181 * OS_ERR_NONE if the memory partition has been created correctly.
182 * OS_ERR_MEM_INVALID_P_MEM if you passed a NULL pointer for 'p_mem'
183 * OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to the caller
184 *
185 * Returns : A pointer to a memory block if no error is detected
186 * A pointer to NULL if an error is detected
187 ************************************************************************************************************************
188 */
189
190 void *OSMemGet (OS_MEM *p_mem,
191 OS_ERR *p_err)
192 {
193 void *p_blk;
194 CPU_SR_ALLOC();
195
196
197
198 #ifdef OS_SAFETY_CRITICAL
199 if (p_err == (OS_ERR *)0) {
200 OS_SAFETY_CRITICAL_EXCEPTION();
201 return ((void *)0);
202 }
203 #endif
204
205 #if OS_CFG_ARG_CHK_EN > 0u
206 if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
207 *p_err = OS_ERR_MEM_INVALID_P_MEM;
208 return ((void *)0);
209 }
210 #endif
211
212 CPU_CRITICAL_ENTER();
213 if (p_mem->NbrFree == (OS_MEM_QTY)0) { /* See if there are any free memory blocks */
214 CPU_CRITICAL_EXIT();
215 *p_err = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */
216 return ((void *)0); /* Return NULL pointer to caller */
217 }
218 p_blk = p_mem->FreeListPtr; /* Yes, point to next free memory block */
219 p_mem->FreeListPtr = *(void **)p_blk; /* Adjust pointer to new free list */
220 p_mem->NbrFree--; /* One less memory block in this partition */
221 CPU_CRITICAL_EXIT();
222 *p_err = OS_ERR_NONE; /* No error */
223 return (p_blk); /* Return memory block to caller */
224 }
225
226 /*$PAGE*/
227 /*
228 ************************************************************************************************************************
229 * RELEASE A MEMORY BLOCK
230 *
231 * Description : Returns a memory block to a partition
232 *
233 * Arguments : p_mem is a pointer to the memory partition control block
234 *
235 * p_blk is a pointer to the memory block being released.
236 *
237 * p_err is a pointer to a variable that will contain an error code returned by this function.
238 *
239 * OS_ERR_NONE if the memory block was inserted into the partition
240 * OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory
241 * partition (You freed more blocks than you allocated!)
242 * OS_ERR_MEM_INVALID_P_BLK if you passed a NULL pointer for the block to release.
243 * OS_ERR_MEM_INVALID_P_MEM if you passed a NULL pointer for 'p_mem'
244 ************************************************************************************************************************
245 */
246
247 void OSMemPut (OS_MEM *p_mem,
248 void *p_blk,
249 OS_ERR *p_err)
250 {
251 CPU_SR_ALLOC();
252
253
254
255 #ifdef OS_SAFETY_CRITICAL
256 if (p_err == (OS_ERR *)0) {
257 OS_SAFETY_CRITICAL_EXCEPTION();
258 return;
259 }
260 #endif
261
262 #if OS_CFG_ARG_CHK_EN > 0u
263 if (p_mem == (OS_MEM *)0) { /* Must point to a valid memory partition */
264 *p_err = OS_ERR_MEM_INVALID_P_MEM;
265 return;
266 }
267 if (p_blk == (void *)0) { /* Must release a valid block */
268 *p_err = OS_ERR_MEM_INVALID_P_BLK;
269 return;
270 }
271 #endif
272
273 CPU_CRITICAL_ENTER();
274 if (p_mem->NbrFree >= p_mem->NbrMax) { /* Make sure all blocks not already returned */
275 CPU_CRITICAL_EXIT();
276 *p_err = OS_ERR_MEM_FULL;
277 return;
278 }
279 *(void **)p_blk = p_mem->FreeListPtr; /* Insert released block into free block list */
280 p_mem->FreeListPtr = p_blk;
281 p_mem->NbrFree++; /* One more memory block in this partition */
282 CPU_CRITICAL_EXIT();
283 *p_err = OS_ERR_NONE; /* Notify caller that memory block was released */
284 }
285
286 /*$PAGE*/
287 /*
288 ************************************************************************************************************************
289 * ADD MEMORY PARTITION TO DEBUG LIST
290 *
291 * Description : This function is called by OSMemCreate() to add the memory partition to the debug table.
292 *
293 * Arguments : p_mem Is a pointer to the memory partition
294 *
295 * Returns : none
296 *
297 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
298 ************************************************************************************************************************
299 */
300
301 #if OS_CFG_DBG_EN > 0u
302 void OS_MemDbgListAdd (OS_MEM *p_mem)
303 {
304 p_mem->DbgPrevPtr = (OS_MEM *)0;
305 if (OSMemDbgListPtr == (OS_MEM *)0) {
306 p_mem->DbgNextPtr = (OS_MEM *)0;
307 } else {
308 p_mem->DbgNextPtr = OSMemDbgListPtr;
309 OSMemDbgListPtr->DbgPrevPtr = p_mem;
310 }
311 OSMemDbgListPtr = p_mem;
312 }
313 #endif
314
315 /*$PAGE*/
316 /*
317 ************************************************************************************************************************
318 * INITIALIZE MEMORY PARTITION MANAGER
319 *
320 * Description : This function is called by uC/OS-III to initialize the memory partition manager. Your
321 * application MUST NOT call this function.
322 *
323 * Arguments : none
324 *
325 * Returns : none
326 *
327 * Note(s) : This function is INTERNAL to uC/OS-III and your application should not call it.
328 ************************************************************************************************************************
329 */
330
331 void OS_MemInit (OS_ERR *p_err)
332 {
333 #ifdef OS_SAFETY_CRITICAL
334 if (p_err == (OS_ERR *)0) {
335 OS_SAFETY_CRITICAL_EXCEPTION();
336 return;
337 }
338 #endif
339
340 #if OS_CFG_DBG_EN > 0u
341 OSMemDbgListPtr = (OS_MEM *)0;
342 #endif
343
344 OSMemQty = (OS_OBJ_QTY)0;
345 *p_err = OS_ERR_NONE;
346 }
347 #endif