Follow and star our public account for exciting content
Source: Mastering Embedded Systems
1. Prevent a header file from being included multiple times
1#ifndef COMDEF_H
2#define COMDEF_H
3// Header file content
4#endif
1#ifndef COMDEF_H
2#define COMDEF_H
3// Header file content
4#endif
2. Redefine some types to prevent differences in type byte sizes due to various platforms and compilers, facilitating portability.
1typedef unsigned char boolean; /* Boolean value type. */
2typedef unsigned long int uint32; /* Unsigned 32 bit value */
3typedef unsigned short uint16; /* Unsigned 16 bit value */
4typedef unsigned char uint8; /* Unsigned 8 bit value */
5typedef signed long int int32; /* Signed 32 bit value */
6typedef signed short int16; /* Signed 16 bit value */
7typedef signed char int8; /* Signed 8 bit value */
1typedef unsigned char boolean; /* Boolean value type. */
2typedef unsigned long int uint32; /* Unsigned 32 bit value */
3typedef unsigned short uint16; /* Unsigned 16 bit value */
4typedef unsigned char uint8; /* Unsigned 8 bit value */
5typedef signed long int int32; /* Signed 32 bit value */
6typedef signed short int16; /* Signed 16 bit value */
7typedef signed char int8; /* Signed 8 bit value */
Not recommended:
1typedef unsigned char byte; /* Unsigned 8 bit value type. */
2typedef unsigned short word; /* Unsigned 16 bit value type. */
3typedef unsigned long dword; /* Unsigned 32 bit value type. */
4typedef unsigned char uint1; /* Unsigned 8 bit value type. */
5typedef unsigned short uint2; /* Unsigned 16 bit value type. */
6typedef unsigned long uint4; /* Unsigned 32 bit value type. */
7typedef signed char int1; /* Signed 8 bit value type. */
8typedef signed short int2; /* Signed 16 bit value type. */
9typedef long int int4; /* Signed 32 bit value type. */
10typedef signed long sint31; /* Signed 32 bit value */
11typedef signed short sint15; /* Signed 16 bit value */
12typedef signed char sint7; /* Signed 8 bit value */
3. Get a byte or word at a specified address
1#define MEM_B( x ) ( *( (byte *) (x) ) )
2#define MEM_W( x ) ( *( (word *) (x) ) )
1#define MEM_B( x ) ( *( (byte *) (x) ) )
2#define MEM_W( x ) ( *( (word *) (x) ) )
4. Calculate maximum and minimum values
1#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
2#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
1#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
2#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
5. Get the offset of a field in a structure
1#define FPOS( type, field ) \
2/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */
1#define FPOS( type, field ) \
2/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */
6. Get the size in bytes of a field in a structure
1#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
1#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
7. Convert two bytes to a word in LSB format
1#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
1#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
8. Convert a word to two bytes in LSB format
1#define FLOPW( ray, val ) \
2(ray)[0] = ((val) / 256); \
3(ray)[1] = ((val) & 0xFF)
1#define FLOPW( ray, val ) \
2(ray)[0] = ((val) / 256); \
3(ray)[1] = ((val) & 0xFF)
9. Get the address of a variable (word width)
1#define B_PTR( var ) ( (byte *) (void *) & (var) )
2#define W_PTR( var ) ( (word *) (void *) & (var) )
1#define B_PTR( var ) ( (byte *) (void *) & (var) )
2#define W_PTR( var ) ( (word *) (void *) & (var) )
10. Get the high and low byte of a word
1#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
2#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
1#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
2#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
11. Return the nearest multiple of 8 greater than X
1#define RND8( x ) ((((x) + 7) / 8 ) * 8 )
1#define RND8( x ) ((((x) + 7) / 8 ) * 8 )
12. Convert a letter to uppercase
1#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
1#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
13. Check if a character is a decimal digit
1#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
1#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
14. Check if a character is a hexadecimal digit
1#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
2((c) >= 'A' && (c) <= 'F') ||\
3((c) >= 'a' && (c) <= 'f') )
1#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
2((c) >= 'A' && (c) <= 'F') ||\
3((c) >= 'a' && (c) <= 'f') )
15. A method to prevent overflow
1#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
1#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
16. Return the number of elements in an array
1#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
1#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
17. Return the value of an unsigned number n mod by power of two (X,n)=X%(2^n)
1#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
2( (dword)(val) & (dword)((mod_by)-1) )
1#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
2( (dword)(val) & (dword)((mod_by)-1) )
18. For IO space mapped in storage space, input and output processing:
1#define inp(port) (*((volatile byte *) (port)))
2#define inpw(port) (*((volatile word *) (port)))
3#define inpdw(port) (*((volatile dword *)(port)))
4#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
5#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
6#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
1#define inp(port) (*((volatile byte *) (port)))
2#define inpw(port) (*((volatile word *) (port)))
3#define inpdw(port) (*((volatile dword *)(port)))
4#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
5#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
6#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
19. Use some macros for debugging
The ANSI standard specifies five predefined macro names, which are:
1_ L I N E _
2_ F I L E _
3_ D A T E _
4_ T I M E _
5_ S T D C _
If the compilation is not standard, it may only support a few of the above macro names, or not support them at all. Remember that the compiler may also provide other predefined macro names.<span>_ L I N E _</span> and <span>_ F I L E _</span> macros have been discussed in the section regarding <span># l i n e</span>, here we discuss the remaining macro names.<span>_ D A T E _</span> macro contains a string in the form of month/day/year, indicating the date when the source file was translated into code.The time when the source code is translated into target code is included as a string in <span>_ T I M E _</span>. The string is in the form of hour:minute:second.If the implementation is standard, the macro <span>_ S T D C _</span> contains the decimal constant 1. If it contains any other number, the implementation is non-standard.Macros can be defined, for example: when <span>_DEBUG</span> is defined, output data information and the line number in the file.
1#ifdef _DEBUG
2#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
3#else
4#define DEBUGMSG(msg,date)
5#endif
20. Macro definitions to prevent errors when used should be enclosed in parentheses.
For example:
1#define ADD(a,b) (a+b)
Use <span>do{}while(0)</span> statement to enclose multiple statements to prevent errors, for example:
1#difne DO(a,b) a+b;\
2a++;
When applied:
1if(….)
2DO(a,b); // produces an error
3else
Solution:
1#define DO(a,b) do{a+b;\
2a++;}while(0)
❞
Copyright statement: Content sourced from the internet, copyright belongs to the original author. Unless unable to confirm, the author and source will be indicated. If there is any infringement, please inform us, and we will delete it immediately and apologize!
‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
Follow my public WeChat account and reply "C language" to receive 300G of programming materials for free.
Click "Read the original text" for more shares, welcome to share, collect, like, and view