训练营PLSR题目
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

387 рядки
16 KiB

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