UCOS_TI_LM3S_Keil
 全部 结构体 文件 函数 变量 类型定义 宏定义 
os_mem.c
浏览该文件的文档.
1 /*
2 *********************************************************************************************************
3 * uC/OS-II
4 * The Real-Time Kernel
5 * MEMORY MANAGEMENT
6 *
7 * (c) Copyright 1992-2009, Micrium, Weston, FL
8 * All Rights Reserved
9 *
10 * File : OS_MEM.C
11 * By : Jean J. Labrosse
12 * Version : V2.89
13 *
14 * LICENSING TERMS:
15 * ---------------
16 * uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
17 * If you plan on using uC/OS-II in a commercial product you need to contact Micrim to properly license
18 * its use in your product. We provide ALL the source code for your convenience and to help you experience
19 * uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
20 * licensing fee.
21 *********************************************************************************************************
22 */
23 
24 #ifndef OS_MASTER_FILE
25 #include <ucos_ii.h>
26 #endif
27 
28 #if (OS_MEM_EN > 0u) && (OS_MAX_MEM_PART > 0u)
29 /*
30 *********************************************************************************************************
31 * CREATE A MEMORY PARTITION
32 *
33 * Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
34 *
35 * Arguments : addr is the starting address of the memory partition
36 *
37 * nblks is the number of memory blocks to create from the partition.
38 *
39 * blksize is the size (in bytes) of each block in the memory partition.
40 *
41 * perr is a pointer to a variable containing an error message which will be set by
42 * this function to either:
43 *
44 * OS_ERR_NONE if the memory partition has been created correctly.
45 * OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory
46 * storage of the partition or, the block does not align
47 * on a pointer boundary
48 * OS_ERR_MEM_INVALID_PART no free partitions available
49 * OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2)
50 * OS_ERR_MEM_INVALID_SIZE user specified an invalid block size
51 * - must be greater than the size of a pointer
52 * - must be able to hold an integral number of pointers
53 * Returns : != (OS_MEM *)0 is the partition was created
54 * == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no
55 * free partition is available.
56 *********************************************************************************************************
57 */
58 
59 OS_MEM *OSMemCreate (void *addr,
60  INT32U nblks,
61  INT32U blksize,
62  INT8U *perr)
63 {
64  OS_MEM *pmem;
65  INT8U *pblk;
66  void **plink;
67  INT32U i;
68 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
69  OS_CPU_SR cpu_sr = 0u;
70 #endif
71 
72 
73 
74 #if OS_ARG_CHK_EN > 0u
75  if (perr == (INT8U *)0) { /* Validate 'perr' */
76  return ((OS_MEM *)0);
77  }
78  if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/
80  return ((OS_MEM *)0);
81  }
82  if (((INT32U)addr & (sizeof(void *) - 1u)) != 0u){ /* Must be pointer size aligned */
84  return ((OS_MEM *)0);
85  }
86  if (nblks < 2u) { /* Must have at least 2 blocks per partition */
88  return ((OS_MEM *)0);
89  }
90  if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */
92  return ((OS_MEM *)0);
93  }
94 #endif
96  pmem = OSMemFreeList; /* Get next free memory partition */
97  if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */
99  }
101  if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */
102  *perr = OS_ERR_MEM_INVALID_PART;
103  return ((OS_MEM *)0);
104  }
105  plink = (void **)addr; /* Create linked list of free memory blocks */
106  pblk = (INT8U *)((INT32U)addr + blksize);
107  for (i = 0u; i < (nblks - 1u); i++) {
108  *plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */
109  plink = (void **)pblk; /* Position to NEXT block */
110  pblk = (INT8U *)((INT32U)pblk + blksize); /* Point to the FOLLOWING block */
111  }
112  *plink = (void *)0; /* Last memory block points to NULL */
113  pmem->OSMemAddr = addr; /* Store start address of memory partition */
114  pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */
115  pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */
116  pmem->OSMemNBlks = nblks;
117  pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */
118  *perr = OS_ERR_NONE;
119  return (pmem);
120 }
121 /*$PAGE*/
122 /*
123 *********************************************************************************************************
124 * GET A MEMORY BLOCK
125 *
126 * Description : Get a memory block from a partition
127 *
128 * Arguments : pmem is a pointer to the memory partition control block
129 *
130 * perr is a pointer to a variable containing an error message which will be set by this
131 * function to either:
132 *
133 * OS_ERR_NONE if the memory partition has been created correctly.
134 * OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
135 * OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
136 *
137 * Returns : A pointer to a memory block if no error is detected
138 * A pointer to NULL if an error is detected
139 *********************************************************************************************************
140 */
141 
142 void *OSMemGet (OS_MEM *pmem,
143  INT8U *perr)
144 {
145  void *pblk;
146 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
147  OS_CPU_SR cpu_sr = 0u;
148 #endif
149 
150 
151 
152 #if OS_ARG_CHK_EN > 0u
153  if (perr == (INT8U *)0) { /* Validate 'perr' */
154  return ((void *)0);
155  }
156  if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
157  *perr = OS_ERR_MEM_INVALID_PMEM;
158  return ((void *)0);
159  }
160 #endif
162  if (pmem->OSMemNFree > 0u) { /* See if there are any free memory blocks */
163  pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */
164  pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */
165  pmem->OSMemNFree--; /* One less memory block in this partition */
167  *perr = OS_ERR_NONE; /* No error */
168  return (pblk); /* Return memory block to caller */
169  }
171  *perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */
172  return ((void *)0); /* Return NULL pointer to caller */
173 }
174 /*$PAGE*/
175 /*
176 *********************************************************************************************************
177 * GET THE NAME OF A MEMORY PARTITION
178 *
179 * Description: This function is used to obtain the name assigned to a memory partition.
180 *
181 * Arguments : pmem is a pointer to the memory partition
182 *
183 * pname is a pointer to a pointer to an ASCII string that will receive the name of the memory partition.
184 *
185 * perr is a pointer to an error code that can contain one of the following values:
186 *
187 * OS_ERR_NONE if the name was copied to 'pname'
188 * OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
189 * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
190 * OS_ERR_NAME_GET_ISR You called this function from an ISR
191 *
192 * Returns : The length of the string or 0 if 'pmem' is a NULL pointer.
193 *********************************************************************************************************
194 */
195 
196 #if OS_MEM_NAME_EN > 0u
198  INT8U **pname,
199  INT8U *perr)
200 {
201  INT8U len;
202 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
203  OS_CPU_SR cpu_sr = 0u;
204 #endif
205 
206 
207 
208 #if OS_ARG_CHK_EN > 0u
209  if (perr == (INT8U *)0) { /* Validate 'perr' */
210  return (0u);
211  }
212  if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
213  *perr = OS_ERR_MEM_INVALID_PMEM;
214  return (0u);
215  }
216  if (pname == (INT8U **)0) { /* Is 'pname' a NULL pointer? */
217  *perr = OS_ERR_PNAME_NULL;
218  return (0u);
219  }
220 #endif
221  if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
222  *perr = OS_ERR_NAME_GET_ISR;
223  return (0u);
224  }
226  *pname = pmem->OSMemName;
227  len = OS_StrLen(*pname);
229  *perr = OS_ERR_NONE;
230  return (len);
231 }
232 #endif
233 
234 /*$PAGE*/
235 /*
236 *********************************************************************************************************
237 * ASSIGN A NAME TO A MEMORY PARTITION
238 *
239 * Description: This function assigns a name to a memory partition.
240 *
241 * Arguments : pmem is a pointer to the memory partition
242 *
243 * pname is a pointer to an ASCII string that contains the name of the memory partition.
244 *
245 * perr is a pointer to an error code that can contain one of the following values:
246 *
247 * OS_ERR_NONE if the name was copied to 'pname'
248 * OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
249 * OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
250 * OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area
251 * OS_ERR_NAME_SET_ISR if you called this function from an ISR
252 *
253 * Returns : None
254 *********************************************************************************************************
255 */
256 
257 #if OS_MEM_NAME_EN > 0u
258 void OSMemNameSet (OS_MEM *pmem,
259  INT8U *pname,
260  INT8U *perr)
261 {
262 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
263  OS_CPU_SR cpu_sr = 0u;
264 #endif
265 
266 
267 
268 #if OS_ARG_CHK_EN > 0u
269  if (perr == (INT8U *)0) { /* Validate 'perr' */
270  return;
271  }
272  if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
273  *perr = OS_ERR_MEM_INVALID_PMEM;
274  return;
275  }
276  if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
277  *perr = OS_ERR_PNAME_NULL;
278  return;
279  }
280 #endif
281  if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
282  *perr = OS_ERR_NAME_SET_ISR;
283  return;
284  }
286  pmem->OSMemName = pname;
288  *perr = OS_ERR_NONE;
289 }
290 #endif
291 
292 /*$PAGE*/
293 /*
294 *********************************************************************************************************
295 * RELEASE A MEMORY BLOCK
296 *
297 * Description : Returns a memory block to a partition
298 *
299 * Arguments : pmem is a pointer to the memory partition control block
300 *
301 * pblk is a pointer to the memory block being released.
302 *
303 * Returns : OS_ERR_NONE if the memory block was inserted into the partition
304 * OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory
305 * partition (You freed more blocks than you allocated!)
306 * OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
307 * OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release.
308 *********************************************************************************************************
309 */
310 
312  void *pblk)
313 {
314 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
315  OS_CPU_SR cpu_sr = 0u;
316 #endif
317 
318 
319 
320 #if OS_ARG_CHK_EN > 0u
321  if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
322  return (OS_ERR_MEM_INVALID_PMEM);
323  }
324  if (pblk == (void *)0) { /* Must release a valid block */
325  return (OS_ERR_MEM_INVALID_PBLK);
326  }
327 #endif
329  if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */
331  return (OS_ERR_MEM_FULL);
332  }
333  *(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */
334  pmem->OSMemFreeList = pblk;
335  pmem->OSMemNFree++; /* One more memory block in this partition */
337  return (OS_ERR_NONE); /* Notify caller that memory block was released */
338 }
339 /*$PAGE*/
340 /*
341 *********************************************************************************************************
342 * QUERY MEMORY PARTITION
343 *
344 * Description : This function is used to determine the number of free memory blocks and the number of
345 * used memory blocks from a memory partition.
346 *
347 * Arguments : pmem is a pointer to the memory partition control block
348 *
349 * p_mem_data is a pointer to a structure that will contain information about the memory
350 * partition.
351 *
352 * Returns : OS_ERR_NONE if no errors were found.
353 * OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
354 * OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient.
355 *********************************************************************************************************
356 */
357 
358 #if OS_MEM_QUERY_EN > 0u
360  OS_MEM_DATA *p_mem_data)
361 {
362 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
363  OS_CPU_SR cpu_sr = 0u;
364 #endif
365 
366 
367 
368 #if OS_ARG_CHK_EN > 0u
369  if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
370  return (OS_ERR_MEM_INVALID_PMEM);
371  }
372  if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */
373  return (OS_ERR_MEM_INVALID_PDATA);
374  }
375 #endif
377  p_mem_data->OSAddr = pmem->OSMemAddr;
378  p_mem_data->OSFreeList = pmem->OSMemFreeList;
379  p_mem_data->OSBlkSize = pmem->OSMemBlkSize;
380  p_mem_data->OSNBlks = pmem->OSMemNBlks;
381  p_mem_data->OSNFree = pmem->OSMemNFree;
383  p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree;
384  return (OS_ERR_NONE);
385 }
386 #endif /* OS_MEM_QUERY_EN */
387 /*$PAGE*/
388 /*
389 *********************************************************************************************************
390 * INITIALIZE MEMORY PARTITION MANAGER
391 *
392 * Description : This function is called by uC/OS-II to initialize the memory partition manager. Your
393 * application MUST NOT call this function.
394 *
395 * Arguments : none
396 *
397 * Returns : none
398 *
399 * Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
400 *********************************************************************************************************
401 */
402 
403 void OS_MemInit (void)
404 {
405 #if OS_MAX_MEM_PART == 1u
406  OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
407  OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */
408 #if OS_MEM_NAME_EN > 0u
409  OSMemFreeList->OSMemName = (INT8U *)"?"; /* Unknown name */
410 #endif
411 #endif
412 
413 #if OS_MAX_MEM_PART >= 2u
414  OS_MEM *pmem;
415  INT16U i;
416 
417 
418  OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
419  pmem = &OSMemTbl[0]; /* Point to memory control block (MCB) */
420  for (i = 0u; i < (OS_MAX_MEM_PART - 1u); i++) { /* Init. list of free memory partitions */
421  pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions */
422 #if OS_MEM_NAME_EN > 0u
423  pmem->OSMemName = (INT8U *)"?";
424 #endif
425  pmem++;
426  }
427  pmem->OSMemFreeList = (void *)0; /* Initialize last node */
428 #if OS_MEM_NAME_EN > 0u
429  pmem->OSMemName = (INT8U *)"?";
430 #endif
431 
432  OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */
433 #endif
434 }
435 #endif /* OS_MEM_EN */