LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lib_mem.h
Go to the documentation of this file.
1 /*
2 *********************************************************************************************************
3 * uC/LIB
4 * CUSTOM LIBRARY MODULES
5 *
6 * (c) Copyright 2004-2011; Micrium, Inc.; Weston, FL
7 *
8 * All rights reserved. Protected by international copyright laws.
9 *
10 * uC/LIB is provided in source form to registered licensees ONLY. It is
11 * illegal to distribute this source code to any third party unless you receive
12 * written permission by an authorized Micrium representative. Knowledge of
13 * the source code may NOT be used to develop a similar product.
14 *
15 * Please help us continue to provide the Embedded community with the finest
16 * software available. Your honesty is greatly appreciated.
17 *
18 * You can contact us at www.micrium.com.
19 *********************************************************************************************************
20 */
21 
22 /*
23 *********************************************************************************************************
24 *
25 * STANDARD MEMORY OPERATIONS
26 *
27 * Filename : lib_mem.h
28 * Version : V1.35.00
29 * Programmer(s) : ITJ
30 *********************************************************************************************************
31 * Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
32 *
33 * (a) ALL standard library functions are implemented in the custom library modules :
34 *
35 * (1) <Custom Library Directory>\lib_*.*
36 *
37 * (2) <Custom Library Directory>\Ports<cpu><compiler>\lib*_a.*
38 *
39 * where
40 * <Custom Library Directory> directory path for custom library software
41 * <cpu> directory name for specific processor (CPU)
42 * <compiler> directory name for specific compiler
43 *
44 * (b) Product-specific library functions are implemented in individual products.
45 *
46 * (2) Assumes the following versions (or more recent) of software modules are included in
47 * the project build :
48 *
49 * (a) uC/CPU V1.27
50 *********************************************************************************************************
51 */
52 
53 
54 /*
55 *********************************************************************************************************
56 * MODULE
57 *
58 * Note(s) : (1) This memory library header file is protected from multiple pre-processor inclusion through
59 * use of the memory library module present pre-processor macro definition.
60 *********************************************************************************************************
61 */
62 
63 #ifndef LIB_MEM_MODULE_PRESENT /* See Note #1. */
64 #define LIB_MEM_MODULE_PRESENT
65 
66 
67 /*$PAGE*/
68 /*
69 *********************************************************************************************************
70 * INCLUDE FILES
71 *
72 * Note(s) : (1) The custom library software files are located in the following directories :
73 *
74 * (a) <Your Product Application>\app_cfg.h
75 *
76 * (b) <Custom Library Directory>\lib_*.*
77 *
78 * where
79 * <Your Product Application> directory path for Your Product's Application
80 * <Custom Library Directory> directory path for custom library software
81 *
82 * (2) CPU-configuration software files are located in the following directories :
83 *
84 * (a) <CPU-Compiler Directory>\cpu_*.*
85 * (b) <CPU-Compiler Directory><cpu><compiler>\cpu*.*
86 *
87 * where
88 * <CPU-Compiler Directory> directory path for common CPU-compiler software
89 * <cpu> directory name for specific processor (CPU)
90 * <compiler> directory name for specific compiler
91 *
92 * (3) Compiler MUST be configured to include as additional include path directories :
93 *
94 * (a) '<Your Product Application>\' directory See Note #1a
95 *
96 * (b) '<Custom Library Directory>\' directory See Note #1b
97 *
98 * (c) (1) '<CPU-Compiler Directory>\' directory See Note #2a
99 * (2) '<CPU-Compiler Directory><cpu><compiler>\' directory See Note #2b
100 *
101 * (4) NO compiler-supplied standard library functions SHOULD be used.
102 *********************************************************************************************************
103 */
104 
105 #include <cpu.h>
106 #include <cpu_core.h>
107 
108 #include <lib_def.h>
109 #include <app_cfg.h>
110 
111 
112 /*
113 *********************************************************************************************************
114 * EXTERNS
115 *********************************************************************************************************
116 */
117 
118 #ifdef LIB_MEM_MODULE
119 #define LIB_MEM_EXT
120 #else
121 #define LIB_MEM_EXT extern
122 #endif
123 
124 
125 /*$PAGE*/
126 /*
127 *********************************************************************************************************
128 * DEFAULT CONFIGURATION
129 *********************************************************************************************************
130 */
131 
132 /*
133 *********************************************************************************************************
134 * MEMORY LIBRARY ARGUMENT CHECK CONFIGURATION
135 *
136 * Note(s) : (1) Configure LIB_MEM_CFG_ARG_CHK_EXT_EN to enable/disable the memory library suite external
137 * argument check feature :
138 *
139 * (a) When ENABLED, arguments received from any port interface provided by the developer
140 * or application are checked/validated.
141 *
142 * (b) When DISABLED, NO arguments received from any port interface provided by the developer
143 * or application are checked/validated.
144 *********************************************************************************************************
145 */
146 
147  /* Configure external argument check feature (see Note #1) : */
148 #ifndef LIB_MEM_CFG_ARG_CHK_EXT_EN
149 #define LIB_MEM_CFG_ARG_CHK_EXT_EN DEF_DISABLED
150  /* DEF_DISABLED Argument check DISABLED */
151  /* DEF_ENABLED Argument check ENABLED */
152 #endif
153 
154 
155 /*
156 *********************************************************************************************************
157 * MEMORY LIBRARY ASSEMBLY OPTIMIZATION CONFIGURATION
158 *
159 * Note(s) : (1) Configure LIB_MEM_CFG_OPTIMIZE_ASM_EN to enable/disable assembly-optimized memory functions.
160 *********************************************************************************************************
161 */
162 
163  /* Configure assembly-optimized function(s) [see Note #1] : */
164 #ifndef LIB_MEM_CFG_OPTIMIZE_ASM_EN
165 #define LIB_MEM_CFG_OPTIMIZE_ASM_EN DEF_DISABLED
166  /* DEF_DISABLED Assembly-optimized function(s) DISABLED */
167  /* DEF_ENABLED Assembly-optimized function(s) ENABLED */
168 #endif
169 
170 
171 /*
172 *********************************************************************************************************
173 * MEMORY ALLOCATION CONFIGURATION
174 *
175 * Note(s) : (1) Configure LIB_MEM_CFG_ALLOC_EN to enable/disable memory allocation functions.
176 *********************************************************************************************************
177 */
178 
179  /* Configure memory allocation feature (see Note #1) : */
180 #ifndef LIB_MEM_CFG_ALLOC_EN
181 #define LIB_MEM_CFG_ALLOC_EN DEF_DISABLED
182  /* DEF_DISABLED Memory allocation DISABLED */
183  /* DEF_ENABLED Memory allocation ENABLED */
184 #endif
185 
186 
187 /*$PAGE*/
188 /*
189 *********************************************************************************************************
190 * DEFINES
191 *********************************************************************************************************
192 */
193 
194 /*
195 *********************************************************************************************************
196 * LIBRARY MEMORY ERROR CODES
197 *********************************************************************************************************
198 */
199 
200 #define LIB_MEM_ERR_NONE 10000u
201 #define LIB_MEM_ERR_NULL_PTR 10001u /* Ptr arg(s) passed NULL ptr(s). */
202 
203 #define LIB_MEM_ERR_INVALID_MEM_SIZE 10100u /* Invalid mem size. */
204 #define LIB_MEM_ERR_INVALID_MEM_ALIGN 10101u /* Invalid mem align. */
205 #define LIB_MEM_ERR_INVALID_SEG_SIZE 10110u /* Invalid mem seg size. */
206 #define LIB_MEM_ERR_INVALID_SEG_OVERLAP 10111u /* Invalid mem seg overlaps other mem seg(s). */
207 #define LIB_MEM_ERR_INVALID_POOL 10120u /* Invalid mem pool. */
208 #define LIB_MEM_ERR_INVALID_BLK_NBR 10130u /* Invalid mem pool blk nbr. */
209 #define LIB_MEM_ERR_INVALID_BLK_SIZE 10131u /* Invalid mem pool blk size. */
210 #define LIB_MEM_ERR_INVALID_BLK_ALIGN 10132u /* Invalid mem pool blk align. */
211 #define LIB_MEM_ERR_INVALID_BLK_IX 10133u /* Invalid mem pool ix. */
212 #define LIB_MEM_ERR_INVALID_BLK_ADDR 10135u /* Invalid mem pool blk addr. */
213 #define LIB_MEM_ERR_INVALID_BLK_ADDR_IN_POOL 10136u /* Mem pool blk addr already in mem pool. */
214 
215 #define LIB_MEM_ERR_SEG_EMPTY 10200u /* Mem seg empty; i.e. NO avail mem in seg. */
216 #define LIB_MEM_ERR_SEG_OVF 10201u /* Mem seg ovf; i.e. req'd mem ovfs rem mem in seg. */
217 #define LIB_MEM_ERR_POOL_FULL 10205u /* Mem pool full; i.e. all mem blks avail in mem pool. */
218 #define LIB_MEM_ERR_POOL_EMPTY 10206u /* Mem pool empty; i.e. NO mem blks avail in mem pool. */
219 
220 #define LIB_MEM_ERR_HEAP_NOT_FOUND 10210u /* Heap seg NOT found. */
221 #define LIB_MEM_ERR_HEAP_EMPTY 10211u /* Heap seg empty; i.e. NO avail mem in heap. */
222 #define LIB_MEM_ERR_HEAP_OVF 10212u /* Heap seg ovf; i.e. req'd mem ovfs rem mem in heap. */
223 
224 
225 /*
226 *********************************************************************************************************
227 * MEMORY LIBRARY TYPE DEFINES
228 *
229 * Note(s) : (1) LIB_MEM_TYPE_&&& #define values specifically chosen as ASCII representations of the memory
230 * library types. Memory displays of memory library objects will display the library TYPEs
231 * with their chosen ASCII names.
232 *********************************************************************************************************
233 */
234 
235 #define LIB_MEM_TYPE_NONE CPU_TYPE_CREATE('N', 'O', 'N', 'E')
236 #define LIB_MEM_TYPE_HEAP CPU_TYPE_CREATE('H', 'E', 'A', 'P')
237 #define LIB_MEM_TYPE_POOL CPU_TYPE_CREATE('P', 'O', 'O', 'L')
238 
239 
240 /*$PAGE*/
241 /*
242 *********************************************************************************************************
243 * DATA TYPES
244 *********************************************************************************************************
245 */
246 
247 /*
248 *********************************************************************************************************
249 * LIB MEM TYPE
250 *
251 * Note(s) : (1) 'LIB_MEM_TYPE' declared as 'CPU_INT32U' & all 'LIB_MEM_TYPE's #define'd with large, non-trivial
252 * values to trap & discard invalid/corrupted library memory objects based on 'LIB_MEM_TYPE'.
253 *********************************************************************************************************
254 */
255 
257 
258 
259 /*
260 *********************************************************************************************************
261 * MEMORY POOL TABLE IX TYPE
262 *
263 * Note(s) : (1) MEM_POOL_IX_NONE SHOULD be #define'd based on 'MEM_POOL_IX' data type declared.
264 *********************************************************************************************************
265 */
266 
268 
269 #define MEM_POOL_IX_NONE DEF_INT_16U_MAX_VAL /* Define as max unsigned val (see Note #1). */
270 #define MEM_POOL_IX_MIN 1
271 #define MEM_POOL_IX_MAX (MEM_POOL_IX_NONE - 1)
272 
273 
274 /*$PAGE*/
275 /*
276 *********************************************************************************************************
277 * MEMORY POOL DATA TYPES
278 *
279 * MEMORY SEGMENT
280 * ----------------
281 * MEMORY POOL'S | | <----
282 * POINTERS TO | MEMORY | |
283 * MEM_POOL MEMORY BLOCKS | BLOCKS | |
284 * |----------------| |---------| | -------- | |
285 * | O------------------> | O--------------------> | | | |
286 * |----------------| |---------| | | | | |
287 * | Pool Addr Ptrs | | O------------- | -------- | |
288 * | Pool Size | |---------| | | | |
289 * |----------------| | | | | -------- | |
290 * | Blk Size | | | --------> | | | |
291 * | Blk Nbr | | | | | | | |
292 * | Blk Ix | | . | | -------- | |
293 * |----------------| | . | | | |
294 * |----------------| | . | | . | |
295 * | O----------------- | | | . | |
296 * |----------------| | | | | . | |
297 * | O------------ | | | | | |
298 * |----------------| | | |---------| | -------- | |
299 * | Seg Size Tot | | | | O--------------------> | | | |
300 * | Seg Size Rem | | | |---------| | | | | |
301 * |----------------| | | | | | -------- | |
302 * | Seg List Ptrs | | | |---------| | | |
303 * |----------------| | | | ------------ | |
304 * | | | | <--------
305 * | | | | | |
306 * | | | | | |
307 * | | | | | |
308 * | | | | | |
309 * | | | | | |
310 * | | ---------------- | |
311 * | | | |
312 * | -------------------------------------------------- |
313 * | |
314 * -----------------------------------------------------------
315 *
316 *********************************************************************************************************
317 */
318 
319 typedef struct mem_pool MEM_POOL;
320 
321  /* --------------------- MEM POOL --------------------- */
322 struct mem_pool {
323  LIB_MEM_TYPE Type; /* Pool type : LIB_TYPE_POOL or LIB_TYPE_HEAP. */
324 
325  MEM_POOL *SegPrevPtr; /* Ptr to PREV mem seg. */
326  MEM_POOL *SegNextPtr; /* Ptr to NEXT mem seg. */
327  MEM_POOL *PoolPrevPtr; /* Ptr to PREV mem pool. */
328  MEM_POOL *PoolNextPtr; /* Ptr to NEXT mem pool. */
329 
330  void *PoolAddrStart; /* Ptr to start of mem seg for mem pool blks. */
331  void *PoolAddrEnd; /* Ptr to end of mem seg for mem pool blks. */
332  void **PoolPtrs; /* Ptr to mem pool's array of blk ptrs. */
333  MEM_POOL_IX BlkIx; /* Ix into mem pool's array of blk ptrs. */
334  CPU_SIZE_T PoolSize; /* Size of mem pool (in octets). */
335  CPU_SIZE_T BlkNbr; /* Nbr of mem pool blks. */
336  CPU_SIZE_T BlkSize; /* Size of mem pool blks (in octets). */
337  CPU_SIZE_T BlkAlign; /* Align of mem pool blks (in octets). */
338 
339  /* --------------------- MEM SEG ---------------------- */
340  void *SegAddr; /* Ptr to mem seg's base/start addr. */
341  void *SegAddrNextAvail; /* Ptr to mem seg's next avail addr. */
342  CPU_SIZE_T SegSizeTot; /* Tot size of mem seg (in octets). */
343  CPU_SIZE_T SegSizeRem; /* Rem size of mem seg (in octets). */
344 };
345 
346 
347 /*$PAGE*/
348 /*
349 *********************************************************************************************************
350 * GLOBAL VARIABLES
351 *********************************************************************************************************
352 */
353 
354 
355 /*$PAGE*/
356 /*
357 *********************************************************************************************************
358 * MACRO'S
359 *********************************************************************************************************
360 */
361 
362 /*
363 *********************************************************************************************************
364 * MEMORY DATA VALUE MACRO'S
365 *
366 * Note(s) : (1) (a) Some variables & variable buffers to pass & receive data values MUST start on appropriate
367 * CPU word-aligned addresses. This is required because most word-aligned processors are more
368 * efficient & may even REQUIRE that multi-octet words start on CPU word-aligned addresses.
369 *
370 * (1) For 16-bit word-aligned processors, this means that
371 *
372 * all 16- & 32-bit words MUST start on addresses that are multiples of 2 octets
373 *
374 * (2) For 32-bit word-aligned processors, this means that
375 *
376 * all 16-bit words MUST start on addresses that are multiples of 2 octets
377 * all 32-bit words MUST start on addresses that are multiples of 4 octets
378 *
379 * (b) However, some data values macro's appropriately access data values from any CPU addresses,
380 * word-aligned or not. Thus for processors that require data word alignment, data words can
381 * be accessed to/from any CPU address, word-aligned or not, without generating data-word-
382 * alignment exceptions/faults.
383 *********************************************************************************************************
384 */
385 
386 
387 /*$PAGE*/
388 /*
389 *********************************************************************************************************
390 * MEM_VAL_GET_xxx()
391 *
392 * Description : Decode data values from any CPU memory address.
393 *
394 * Argument(s) : addr Lowest CPU memory address of data value to decode (see Notes #2 & #3a).
395 *
396 * Return(s) : Decoded data value from CPU memory address (see Notes #1 & #3b).
397 *
398 * Caller(s) : Application.
399 *
400 * Note(s) : (1) Decode data values based on the values' data-word order in CPU memory :
401 *
402 * MEM_VAL_GET_xxx_BIG() Decode big- endian data values -- data words' most
403 * significant octet @ lowest memory address
404 * MEM_VAL_GET_xxx_LITTLE() Decode little-endian data values -- data words' least
405 * significant octet @ lowest memory address
406 * MEM_VAL_GET_xxx() Decode data values using CPU's native or configured
407 * data-word order
408 *
409 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
410 *
411 * (2) CPU memory addresses/pointers NOT checked for NULL.
412 *
413 * (3) (a) MEM_VAL_GET_xxx() macro's decode data values without regard to CPU word-aligned addresses.
414 * Thus for processors that require data word alignment, data words can be decoded from any
415 * CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
416 *
417 * (b) However, any variable to receive the returned data value MUST start on an appropriate CPU
418 * word-aligned address.
419 *
420 * See also 'MEMORY DATA VALUE MACRO'S Note #1'.
421 *
422 * (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are
423 * also independent of CPU data-word-alignment & SHOULD be used whenever possible.
424 *
425 * See also 'MEM_VAL_COPY_GET_xxx() Note #4'.
426 *
427 * (5) MEM_VAL_GET_xxx() macro's are NOT atomic operations & MUST NOT be used on any non-static
428 * (i.e. volatile) variables, registers, hardware, etc.; without the caller of the macro's
429 * providing some form of additional protection (e.g. mutual exclusion).
430 *
431 * (6) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
432 * linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
433 * constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
434 * value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
435 * included as an extra precaution in case 'cpu.h' is incorrectly configured.
436 *********************************************************************************************************
437 */
438 /*$PAGE*/
439 
440 #define MEM_VAL_GET_INT08U_BIG(addr) ((CPU_INT08U) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0u * DEF_OCTET_NBR_BITS)))
441 
442 #define MEM_VAL_GET_INT16U_BIG(addr) ((CPU_INT16U)((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (1u * DEF_OCTET_NBR_BITS)) + \
443  (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (0u * DEF_OCTET_NBR_BITS))))
444 
445 #define MEM_VAL_GET_INT32U_BIG(addr) ((CPU_INT32U)((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (3u * DEF_OCTET_NBR_BITS)) + \
446  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (2u * DEF_OCTET_NBR_BITS)) + \
447  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (1u * DEF_OCTET_NBR_BITS)) + \
448  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (0u * DEF_OCTET_NBR_BITS))))
449 
450 
451 
452 #define MEM_VAL_GET_INT08U_LITTLE(addr) ((CPU_INT08U) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0u * DEF_OCTET_NBR_BITS)))
453 
454 #define MEM_VAL_GET_INT16U_LITTLE(addr) ((CPU_INT16U)((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (0u * DEF_OCTET_NBR_BITS)) + \
455  (((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (1u * DEF_OCTET_NBR_BITS))))
456 
457 #define MEM_VAL_GET_INT32U_LITTLE(addr) ((CPU_INT32U)((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (0u * DEF_OCTET_NBR_BITS)) + \
458  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (1u * DEF_OCTET_NBR_BITS)) + \
459  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (2u * DEF_OCTET_NBR_BITS)) + \
460  (((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (3u * DEF_OCTET_NBR_BITS))))
461 
462 
463 
464 #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
465 
466 #define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_BIG(addr)
467 #define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_BIG(addr)
468 #define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_BIG(addr)
469 
470 #elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
471 
472 #define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_LITTLE(addr)
473 #define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_LITTLE(addr)
474 #define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_LITTLE(addr)
475 
476 #else /* See Note #6. */
477 
478 #error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
479 #error " [See 'cpu.h CONFIGURATION ERRORS']"
480 
481 #endif
482 
483 
484 /*$PAGE*/
485 /*
486 *********************************************************************************************************
487 * MEM_VAL_SET_xxx()
488 *
489 * Description : Encode data values to any CPU memory address.
490 *
491 * Argument(s) : addr Lowest CPU memory address to encode data value (see Notes #2 & #3a).
492 *
493 * val Data value to encode (see Notes #1 & #3b).
494 *
495 * Return(s) : none.
496 *
497 * Caller(s) : Application.
498 *
499 * Note(s) : (1) Encode data values into CPU memory based on the values' data-word order :
500 *
501 * MEM_VAL_SET_xxx_BIG() Encode big- endian data values -- data words' most
502 * significant octet @ lowest memory address
503 * MEM_VAL_SET_xxx_LITTLE() Encode little-endian data values -- data words' least
504 * significant octet @ lowest memory address
505 * MEM_VAL_SET_xxx() Encode data values using CPU's native or configured
506 * data-word order
507 *
508 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
509 *
510 * (2) CPU memory addresses/pointers NOT checked for NULL.
511 *
512 * (3) (a) MEM_VAL_SET_xxx() macro's encode data values without regard to CPU word-aligned addresses.
513 * Thus for processors that require data word alignment, data words can be encoded to any
514 * CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
515 *
516 * (b) However, 'val' data value to encode MUST start on an appropriate CPU word-aligned address.
517 *
518 * See also 'MEMORY DATA VALUE MACRO'S Note #1'.
519 *
520 * (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are
521 * also independent of CPU data-word-alignment & SHOULD be used whenever possible.
522 *
523 * See also 'MEM_VAL_COPY_SET_xxx() Note #4'.
524 *
525 * (5) MEM_VAL_SET_xxx() macro's are NOT atomic operations & MUST NOT be used on any non-static
526 * (i.e. volatile) variables, registers, hardware, etc.; without the caller of the macro's
527 * providing some form of additional protection (e.g. mutual exclusion).
528 *
529 * (6) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
530 * linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
531 * constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
532 * value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
533 * included as an extra precaution in case 'cpu.h' is incorrectly configured.
534 *********************************************************************************************************
535 */
536 /*$PAGE*/
537 
538 #define MEM_VAL_SET_INT08U_BIG(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFFuL) >> (0u * DEF_OCTET_NBR_BITS))); } while (0)
539 
540 #define MEM_VAL_SET_INT16U_BIG(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00uL) >> (1u * DEF_OCTET_NBR_BITS))); \
541  (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FFuL) >> (0u * DEF_OCTET_NBR_BITS))); } while (0)
542 
543 #define MEM_VAL_SET_INT32U_BIG(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000uL) >> (3u * DEF_OCTET_NBR_BITS))); \
544  (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000uL) >> (2u * DEF_OCTET_NBR_BITS))); \
545  (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00uL) >> (1u * DEF_OCTET_NBR_BITS))); \
546  (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FFuL) >> (0u * DEF_OCTET_NBR_BITS))); } while (0)
547 
548 
549 
550 #define MEM_VAL_SET_INT08U_LITTLE(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFFuL) >> (0u * DEF_OCTET_NBR_BITS))); } while (0)
551 
552 #define MEM_VAL_SET_INT16U_LITTLE(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FFuL) >> (0u * DEF_OCTET_NBR_BITS))); \
553  (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00uL) >> (1u * DEF_OCTET_NBR_BITS))); } while (0)
554 
555 #define MEM_VAL_SET_INT32U_LITTLE(addr, val) do { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FFuL) >> (0u * DEF_OCTET_NBR_BITS))); \
556  (*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00uL) >> (1u * DEF_OCTET_NBR_BITS))); \
557  (*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000uL) >> (2u * DEF_OCTET_NBR_BITS))); \
558  (*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000uL) >> (3u * DEF_OCTET_NBR_BITS))); } while (0)
559 
560 
561 
562 #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
563 
564 #define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_BIG(addr, val)
565 #define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_BIG(addr, val)
566 #define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_BIG(addr, val)
567 
568 #elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
569 
570 #define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_LITTLE(addr, val)
571 #define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_LITTLE(addr, val)
572 #define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_LITTLE(addr, val)
573 
574 #else /* See Note #6. */
575 
576 #error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
577 #error " [See 'cpu.h CONFIGURATION ERRORS']"
578 
579 #endif
580 
581 
582 /*$PAGE*/
583 /*
584 *********************************************************************************************************
585 * MEM_VAL_COPY_GET_xxx()
586 *
587 * Description : Copy & decode data values from any CPU memory address to any CPU memory address.
588 *
589 * Argument(s) : addr_dest Lowest CPU memory address to copy/decode source address's data value
590 * (see Notes #2 & #3).
591 *
592 * addr_src Lowest CPU memory address of data value to copy/decode
593 * (see Notes #2 & #3).
594 *
595 * Return(s) : none.
596 *
597 * Caller(s) : Application.
598 *
599 * Note(s) : (1) Copy/decode data values based on the values' data-word order :
600 *
601 * MEM_VAL_COPY_GET_xxx_BIG() Decode big- endian data values -- data words' most
602 * significant octet @ lowest memory address
603 * MEM_VAL_COPY_GET_xxx_LITTLE() Decode little-endian data values -- data words' least
604 * significant octet @ lowest memory address
605 * MEM_VAL_COPY_GET_xxx() Decode data values using CPU's native or configured
606 * data-word order
607 *
608 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
609 *
610 * (2) CPU memory addresses/pointers NOT checked for NULL.
611 *
612 * (3) MEM_VAL_COPY_GET_xxx() macro's copy/decode data values without regard to CPU word-aligned
613 * addresses. Thus for processors that require data word alignment, data words can be copied/
614 * decoded to/from any CPU address, word-aligned or not, without generating data-word-alignment
615 * exceptions/faults.
616 *
617 * (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are
618 * also independent of CPU data-word-alignment & SHOULD be used whenever possible.
619 *
620 * See also 'MEM_VAL_GET_xxx() Note #4'.
621 *
622 * (5) Since octet-order copy/conversion are inverse operations, MEM_VAL_COPY_GET_xxx() &
623 * MEM_VAL_COPY_SET_xxx() macros are inverse, but identical, operations & are provided
624 * in both forms for semantics & consistency.
625 *
626 * See also 'MEM_VAL_COPY_SET_xxx() Note #5'.
627 *
628 * (6) MEM_VAL_COPY_GET_xxx() macro's are NOT atomic operations & MUST NOT be used on any non-
629 * static (i.e. volatile) variables, registers, hardware, etc.; without the caller of the
630 * macro's providing some form of additional protection (e.g. mutual exclusion).
631 *
632 * (7) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
633 * linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
634 * constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
635 * value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
636 * included as an extra precaution in case 'cpu.h' is incorrectly configured.
637 *********************************************************************************************************
638 */
639 /*$PAGE*/
640 
641 #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
642 
643 
644 #define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
645 
646 #define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
647  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } while (0)
648 
649 #define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
650  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
651  (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
652  (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } while (0)
653 
654 
655 
656 #define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
657 
658 #define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
659  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
660 
661 #define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \
662  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
663  (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
664  (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
665 
666 
667 
668 #define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src)
669 #define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src)
670 #define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src)
671 
672 
673 
674 
675 #elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
676 
677 
678 #define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
679 
680 #define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
681  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
682 
683 #define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \
684  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
685  (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
686  (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
687 
688 
689 
690 #define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
691 
692 #define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
693  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } while (0)
694 
695 #define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
696  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
697  (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
698  (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } while (0)
699 
700 
701 
702 #define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src)
703 #define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src)
704 #define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src)
705 
706 
707 
708 
709 #else /* See Note #7. */
710 
711 #error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
712 #error " [See 'cpu.h CONFIGURATION ERRORS']"
713 
714 #endif
715 
716 
717 /*$PAGE*/
718 /*
719 *********************************************************************************************************
720 * MEM_VAL_COPY_GET_INTU_xxx()
721 *
722 * Description : Copy & decode data values from any CPU memory address to any CPU memory address for
723 * any sized data values.
724 *
725 * Argument(s) : addr_dest Lowest CPU memory address to copy/decode source address's data value
726 * (see Notes #2 & #3).
727 *
728 * addr_src Lowest CPU memory address of data value to copy/decode
729 * (see Notes #2 & #3).
730 *
731 * val_size Number of data value octets to copy/decode.
732 *
733 * Return(s) : none.
734 *
735 * Caller(s) : Application.
736 *
737 * Note(s) : (1) Copy/decode data values based on the values' data-word order :
738 *
739 * MEM_VAL_COPY_GET_INTU_BIG() Decode big- endian data values -- data words' most
740 * significant octet @ lowest memory address
741 * MEM_VAL_COPY_GET_INTU_LITTLE() Decode little-endian data values -- data words' least
742 * significant octet @ lowest memory address
743 * MEM_VAL_COPY_GET_INTU() Decode data values using CPU's native or configured
744 * data-word order
745 *
746 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
747 *
748 * (2) CPU memory addresses/pointers NOT checked for NULL.
749 *
750 * (3) MEM_VAL_COPY_GET_INTU_xxx() macro's copy/decode data values without regard to CPU word-
751 * aligned addresses. Thus for processors that require data word alignment, data words
752 * can be copied/decoded to/from any CPU address, word-aligned or not, without generating
753 * data-word-alignment exceptions/faults.
754 *
755 * (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_COPY_GET_INTU_xxx()
756 * macro's & SHOULD be used whenever possible.
757 *
758 * See also 'MEM_VAL_COPY_GET_xxx() Note #4'.
759 *
760 * (5) Since octet-order copy/conversion are inverse operations, MEM_VAL_COPY_GET_INTU_xxx() &
761 * MEM_VAL_COPY_SET_INTU_xxx() macros are inverse, but identical, operations & are provided
762 * in both forms for semantics & consistency.
763 *
764 * See also 'MEM_VAL_COPY_SET_INTU_xxx() Note #5'.
765 *
766 * (6) MEM_VAL_COPY_GET_INTU_xxx() macro's are NOT atomic operations & MUST NOT be used on any
767 * non-static (i.e. volatile) variables, registers, hardware, etc.; without the caller of
768 * the macro's providing some form of additional protection (e.g. mutual exclusion).
769 *
770 * (7) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
771 * linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
772 * constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
773 * value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
774 * included as an extra precaution in case 'cpu.h' is incorrectly configured.
775 *********************************************************************************************************
776 */
777 /*$PAGE*/
778 
779 #if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
780 
781 
782 #define MEM_VAL_COPY_GET_INTU_BIG(addr_dest, addr_src, val_size) do { \
783  CPU_SIZE_T i; \
784  \
785  for (i = 0; i < (val_size); i++) { \
786  (*(((CPU_INT08U *)(addr_dest)) + i)) = (*(((CPU_INT08U *)(addr_src)) + i)); \
787  } \
788  } while (0)
789 
790 
791 #define MEM_VAL_COPY_GET_INTU_LITTLE(addr_dest, addr_src, val_size) do { \
792  CPU_SIZE_T i; \
793  CPU_SIZE_T j; \
794  \
795  for (i = 0, j = (val_size) - 1; i < (val_size); i++, j--) { \
796  (*(((CPU_INT08U *)(addr_dest)) + i)) = (*(((CPU_INT08U *)(addr_src)) + j)); \
797  } \
798  } while (0)
799 
800 
801 #define MEM_VAL_COPY_GET_INTU(addr_dest, addr_src, val_size) MEM_VAL_COPY_GET_INTU_BIG(addr_dest, addr_src, val_size)
802 
803 
804 
805 
806 #elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
807 
808 
809 #define MEM_VAL_COPY_GET_INTU_BIG(addr_dest, addr_src, val_size) do { \
810  CPU_SIZE_T i; \
811  CPU_SIZE_T j; \
812  \
813  for (i = 0, j = (val_size) - 1; i < (val_size); i++, j--) { \
814  (*(((CPU_INT08U *)(addr_dest)) + i)) = (*(((CPU_INT08U *)(addr_src)) + j)); \
815  } \
816  } while (0)
817 
818 
819 #define MEM_VAL_COPY_GET_INTU_LITTLE(addr_dest, addr_src, val_size) do { \
820  CPU_SIZE_T i; \
821  \
822  for (i = 0; i < (val_size); i++) { \
823  (*(((CPU_INT08U *)(addr_dest)) + i)) = (*(((CPU_INT08U *)(addr_src)) + i)); \
824  } \
825  } while (0)
826 
827 
828 #define MEM_VAL_COPY_GET_INTU(addr_dest, addr_src, val_size) MEM_VAL_COPY_GET_INTU_LITTLE(addr_dest, addr_src, val_size)
829 
830 
831 
832 
833 #else /* See Note #7. */
834 
835 #error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
836 #error " [See 'cpu.h CONFIGURATION ERRORS']"
837 
838 #endif
839 
840 
841 /*$PAGE*/
842 /*
843 *********************************************************************************************************
844 * MEM_VAL_COPY_SET_xxx()
845 *
846 * Description : Copy & encode data values from any CPU memory address to any CPU memory address.
847 *
848 * Argument(s) : addr_dest Lowest CPU memory address to copy/encode source address's data value
849 * (see Notes #2 & #3).
850 *
851 * addr_src Lowest CPU memory address of data value to copy/encode
852 * (see Notes #2 & #3).
853 *
854 * Return(s) : none.
855 *
856 * Caller(s) : Application.
857 *
858 * Note(s) : (1) Copy/encode data values based on the values' data-word order :
859 *
860 * MEM_VAL_COPY_SET_xxx_BIG() Encode big- endian data values -- data words' most
861 * significant octet @ lowest memory address
862 * MEM_VAL_COPY_SET_xxx_LITTLE() Encode little-endian data values -- data words' least
863 * significant octet @ lowest memory address
864 * MEM_VAL_COPY_SET_xxx() Encode data values using CPU's native or configured
865 * data-word order
866 *
867 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
868 *
869 * (2) CPU memory addresses/pointers NOT checked for NULL.
870 *
871 * (3) MEM_VAL_COPY_SET_xxx() macro's copy/encode data values without regard to CPU word-aligned
872 * addresses. Thus for processors that require data word alignment, data words can be copied/
873 * encoded to/from any CPU address, word-aligned or not, without generating data-word-alignment
874 * exceptions/faults.
875 *
876 * (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are
877 * also independent of CPU data-word-alignment & SHOULD be used whenever possible.
878 *
879 * See also 'MEM_VAL_SET_xxx() Note #4'.
880 *
881 * (5) Since octet-order copy/conversion are inverse operations, MEM_VAL_COPY_GET_xxx() &
882 * MEM_VAL_COPY_SET_xxx() macros are inverse, but identical, operations & are provided
883 * in both forms for semantics & consistency.
884 *
885 * See also 'MEM_VAL_COPY_GET_xxx() Note #5'.
886 *
887 * (6) MEM_VAL_COPY_SET_xxx() macro's are NOT atomic operations & MUST NOT be used on any
888 * non-static (i.e. volatile) variables, registers, hardware, etc.; without the caller
889 * of the macro's providing some form of additional protection (e.g. mutual exclusion).
890 *********************************************************************************************************
891 */
892 
893  /* See Note #5. */
894 #define MEM_VAL_COPY_SET_INT08U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src)
895 #define MEM_VAL_COPY_SET_INT16U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src)
896 #define MEM_VAL_COPY_SET_INT32U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src)
897 
898 #define MEM_VAL_COPY_SET_INT08U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src)
899 #define MEM_VAL_COPY_SET_INT16U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src)
900 #define MEM_VAL_COPY_SET_INT32U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src)
901 
902 
903 #define MEM_VAL_COPY_SET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src)
904 #define MEM_VAL_COPY_SET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src)
905 #define MEM_VAL_COPY_SET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src)
906 
907 
908 /*$PAGE*/
909 /*
910 *********************************************************************************************************
911 * MEM_VAL_COPY_SET_INTU_xxx()
912 *
913 * Description : Copy & encode data values from any CPU memory address to any CPU memory address for
914 * any sized data values.
915 *
916 * Argument(s) : addr_dest Lowest CPU memory address to copy/encode source address's data value
917 * (see Notes #2 & #3).
918 *
919 * addr_src Lowest CPU memory address of data value to copy/encode
920 * (see Notes #2 & #3).
921 *
922 * val_size Number of data value octets to copy/encode.
923 *
924 * Return(s) : none.
925 *
926 * Caller(s) : Application.
927 *
928 * Note(s) : (1) Copy/encode data values based on the values' data-word order :
929 *
930 * MEM_VAL_COPY_SET_INTU_BIG() Encode big- endian data values -- data words' most
931 * significant octet @ lowest memory address
932 * MEM_VAL_COPY_SET_INTU_LITTLE() Encode little-endian data values -- data words' least
933 * significant octet @ lowest memory address
934 * MEM_VAL_COPY_SET_INTU() Encode data values using CPU's native or configured
935 * data-word order
936 *
937 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
938 *
939 * (2) CPU memory addresses/pointers NOT checked for NULL.
940 *
941 * (3) MEM_VAL_COPY_SET_INTU_xxx() macro's copy/encode data values without regard to CPU word-
942 * aligned addresses. Thus for processors that require data word alignment, data words
943 * can be copied/encoded to/from any CPU address, word-aligned or not, without generating
944 * data-word-alignment exceptions/faults.
945 *
946 * (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_COPY_SET_INTU_xxx()
947 * macro's & SHOULD be used whenever possible.
948 *
949 * See also 'MEM_VAL_COPY_SET_xxx() Note #4'.
950 *
951 * (5) Since octet-order copy/conversion are inverse operations, MEM_VAL_COPY_GET_INTU_xxx() &
952 * MEM_VAL_COPY_SET_INTU_xxx() macros are inverse, but identical, operations & are provided
953 * in both forms for semantics & consistency.
954 *
955 * See also 'MEM_VAL_COPY_GET_INTU_xxx() Note #5'.
956 *
957 * (6) MEM_VAL_COPY_SET_INTU_xxx() macro's are NOT atomic operations & MUST NOT be used on any
958 * non-static (i.e. volatile) variables, registers, hardware, etc.; without the caller of
959 * the macro's providing some form of additional protection (e.g. mutual exclusion).
960 *********************************************************************************************************
961 */
962 
963  /* See Note #5. */
964 #define MEM_VAL_COPY_SET_INTU_BIG(addr_dest, addr_src, val_size) MEM_VAL_COPY_GET_INTU_BIG(addr_dest, addr_src, val_size)
965 #define MEM_VAL_COPY_SET_INTU_LITTLE(addr_dest, addr_src, val_size) MEM_VAL_COPY_GET_INTU_LITTLE(addr_dest, addr_src, val_size)
966 #define MEM_VAL_COPY_SET_INTU(addr_dest, addr_src, val_size) MEM_VAL_COPY_GET_INTU(addr_dest, addr_src, val_size)
967 
968 
969 /*$PAGE*/
970 /*
971 *********************************************************************************************************
972 * MEM_VAL_COPY_xxx()
973 *
974 * Description : Copy data values from any CPU memory address to any CPU memory address.
975 *
976 * Argument(s) : addr_dest Lowest CPU memory address to copy source address's data value
977 * (see Notes #2 & #3).
978 *
979 * addr_src Lowest CPU memory address of data value to copy
980 * (see Notes #2 & #3).
981 *
982 * Return(s) : none.
983 *
984 * Caller(s) : Application.
985 *
986 * Note(s) : (1) MEM_VAL_COPY_xxx() macro's copy data values based on CPU's native data-word order.
987 *
988 * See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
989 *
990 * (2) CPU memory addresses/pointers NOT checked for NULL.
991 *
992 * (3) MEM_VAL_COPY_xxx() macro's copy data values without regard to CPU word-aligned addresses.
993 * Thus for processors that require data word alignment, data words can be copied to/from any
994 * CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
995 *
996 * (4) MEM_VAL_COPY_xxx() macro's are NOT atomic operations & MUST NOT be used on any non-static
997 * (i.e. volatile) variables, registers, hardware, etc.; without the caller of the macro's
998 * providing some form of additional protection (e.g. mutual exclusion).
999 *********************************************************************************************************
1000 */
1001 
1002 #define MEM_VAL_COPY_08(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); } while (0)
1003 
1004 #define MEM_VAL_COPY_16(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
1005  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); } while (0)
1006 
1007 #define MEM_VAL_COPY_32(addr_dest, addr_src) do { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
1008  (*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
1009  (*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
1010  (*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); } while (0)
1011 
1012 
1013 /*$PAGE*/
1014 /*
1015 *********************************************************************************************************
1016 * FUNCTION PROTOTYPES
1017 *********************************************************************************************************
1018 */
1019 
1020 void Mem_Init ( void);
1021 
1022  /* ---------------- MEM API FNCTS ---------------- */
1023 void Mem_Clr ( void *pmem,
1024  CPU_SIZE_T size);
1025 
1026 void Mem_Set ( void *pmem,
1027  CPU_INT08U data_val,
1028  CPU_SIZE_T size);
1029 
1030 void Mem_Copy ( void *pdest,
1031  const void *psrc,
1032  CPU_SIZE_T size);
1033 
1034 CPU_BOOLEAN Mem_Cmp (const void *p1_mem,
1035  const void *p2_mem,
1036  CPU_SIZE_T size);
1037 
1038 
1039 
1040 #if (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED) /* ---------------- MEM POOL FNCTS ---------------- */
1041 
1042 void *Mem_HeapAlloc ( CPU_SIZE_T size,
1043  CPU_SIZE_T align,
1044  CPU_SIZE_T *poctets_reqd,
1045  LIB_ERR *perr);
1046 
1047 
1048 void Mem_PoolClr ( MEM_POOL *pmem_pool,
1049  LIB_ERR *perr);
1050 
1051 void Mem_PoolCreate ( MEM_POOL *pmem_pool,
1052  void *pmem_base_addr,
1053  CPU_SIZE_T mem_size,
1054  CPU_SIZE_T blk_nbr,
1055  CPU_SIZE_T blk_size,
1056  CPU_SIZE_T blk_align,
1057  CPU_SIZE_T *poctets_reqd,
1058  LIB_ERR *perr);
1059 
1060 void *Mem_PoolBlkGet ( MEM_POOL *pmem_pool,
1061  CPU_SIZE_T size,
1062  LIB_ERR *perr);
1063 
1064 void Mem_PoolBlkFree( MEM_POOL *pmem_pool,
1065  void *pmem_blk,
1066  LIB_ERR *perr);
1067 
1068 #endif
1069 
1070 
1071 /*$PAGE*/
1072 /*
1073 *********************************************************************************************************
1074 * CONFIGURATION ERRORS
1075 *********************************************************************************************************
1076 */
1077 
1078 #ifndef LIB_MEM_CFG_ARG_CHK_EXT_EN
1079 #error "LIB_MEM_CFG_ARG_CHK_EXT_EN not #define'd in 'app_cfg.h'"
1080 #error " [MUST be DEF_DISABLED] "
1081 #error " [ || DEF_ENABLED ] "
1082 
1083 #elif ((LIB_MEM_CFG_ARG_CHK_EXT_EN != DEF_DISABLED) && \
1084  (LIB_MEM_CFG_ARG_CHK_EXT_EN != DEF_ENABLED ))
1085 #error "LIB_MEM_CFG_ARG_CHK_EXT_EN illegally #define'd in 'app_cfg.h'"
1086 #error " [MUST be DEF_DISABLED] "
1087 #error " [ || DEF_ENABLED ] "
1088 #endif
1089 
1090 
1091 
1092 #ifndef LIB_MEM_CFG_OPTIMIZE_ASM_EN
1093 #error "LIB_MEM_CFG_OPTIMIZE_ASM_EN not #define'd in 'app_cfg.h'"
1094 #error " [MUST be DEF_DISABLED] "
1095 #error " [ || DEF_ENABLED ] "
1096 
1097 #elif ((LIB_MEM_CFG_OPTIMIZE_ASM_EN != DEF_DISABLED) && \
1098  (LIB_MEM_CFG_OPTIMIZE_ASM_EN != DEF_ENABLED ))
1099 #error "LIB_MEM_CFG_OPTIMIZE_ASM_EN illegally #define'd in 'app_cfg.h'"
1100 #error " [MUST be DEF_DISABLED] "
1101 #error " [ || DEF_ENABLED ] "
1102 #endif
1103 
1104 
1105 
1106 
1107 #ifndef LIB_MEM_CFG_ALLOC_EN
1108 #error "LIB_MEM_CFG_ALLOC_EN not #define'd in 'app_cfg.h'"
1109 #error " [MUST be DEF_DISABLED] "
1110 #error " [ || DEF_ENABLED ] "
1111 
1112 #elif ((LIB_MEM_CFG_ALLOC_EN != DEF_DISABLED) && \
1113  (LIB_MEM_CFG_ALLOC_EN != DEF_ENABLED ))
1114 #error "LIB_MEM_CFG_ALLOC_EN illegally #define'd in 'app_cfg.h'"
1115 #error " [MUST be DEF_DISABLED] "
1116 #error " [ || DEF_ENABLED ] "
1117 
1118 
1119 #elif (LIB_MEM_CFG_ALLOC_EN == DEF_ENABLED)
1120 
1121 
1122 #ifndef LIB_MEM_CFG_HEAP_SIZE
1123 #error "LIB_MEM_CFG_HEAP_SIZE not #define'd in 'app_cfg.h'"
1124 #error " [MUST be > 0] "
1125 
1126 #elif (DEF_CHK_VAL_MIN(LIB_MEM_CFG_HEAP_SIZE, 1) != DEF_OK)
1127 #error "LIB_MEM_CFG_HEAP_SIZE illegally #define'd in 'app_cfg.h'"
1128 #error " [MUST be > 0] "
1129 #endif
1130 
1131 
1132 #ifdef LIB_MEM_CFG_HEAP_BASE_ADDR
1133 #if (LIB_MEM_CFG_HEAP_BASE_ADDR == 0x0)
1134 #error "LIB_MEM_CFG_HEAP_BASE_ADDR illegally #define'd in 'app_cfg.h'"
1135 #error " [MUST be > 0x0] "
1136 #endif
1137 #endif
1138 
1139 
1140 #endif
1141 
1142 
1143 /*
1144 *********************************************************************************************************
1145 * LIBRARY CONFIGURATION ERRORS
1146 *********************************************************************************************************
1147 */
1148 
1149  /* See 'lib_mem.h Note #2a'. */
1150 #if (CPU_CORE_VERSION < 127u)
1151 #error "CPU_CORE_VERSION [SHOULD be >= V1.27]"
1152 #endif
1153 
1154 
1155 /*$PAGE*/
1156 /*
1157 *********************************************************************************************************
1158 * MODULE END
1159 *********************************************************************************************************
1160 */
1161 
1162 #endif /* End of lib mem module include. */
1163