| 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
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
256 typedef CPU_INT32U LIB_MEM_TYPE;
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
267 typedef CPU_INT16U MEM_POOL_IX;
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