++++++++++++++++++++++
1)硬码实义化
用宏来将一个硬码数值,进行实义化。、
#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
#define MCU_MEM_MAP_VERSION 0x0300U#define ADC_HC_ADCH_MASK (0x1FU)#define FSL_IOMUXC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
在编写代码的过程中,尽量不要出现硬码,如果需要使用硬码,也要使用实义宏。
这样便于将函数模板化。
在需要修改时,只修改实义宏即可,无需修改函数。
另一种硬码实义化的方式,是enum。
enum分为枚举常量和枚举变量。
在定义enum时,花括号里列出的,就是枚举常量。
而在代码中用内存分配的,就是枚举变量。
枚举常量,就是实义化的硬码。
它和实义宏是有区别的,
实义宏是一个纯数值,不具类型。
枚举常量是具类型的。
对一个枚举变量赋值时,会检查类型是否匹配,所以需要强转。
+++++++++++++++++++++++++++++++++++++
2)参数块实义化
在调用函数时,需要传参,参数列表的一部分,我们称为参数块。
如果参数块,是硬码形式的,即这个参数块中,全是数值,
那么可以将参数块实义化,定义为宏,
这个宏,就是宏拟参数块。
#define IOMUXC_GPIO1_IO02_GPIO1_IO02 0x020E0064U, 0x5U, 0x00000000U, 0x0U, 0x020E02F0U
注意,参数块中间的多个硬码,要用逗号分隔,但是参数块的前面和后面,都不要有逗号。
这样,使得参数块,看起来就像一个参数一样。
在编写代码的过程中,尽量不要出现硬码,如果需要使用硬码,也要使用实义宏。
++++++++++++++++++++++++++++++++
3)宏拟变量
用宏来将MMIO或者MMREG进行实义化。
对MMREG的读写,就像对一个变量读写一样。
#define CCM_CCGR5 *((volatile unsigned long*)0x020C4080)
绝对地址,是一个指针,将其强转,并加以volatile修饰。
对指针取数,即为变量。
这就是宏拟变量。
+++++++++++++++++++++++++
4)宏拟句柄
用宏来将MMIORegion或者MMRegRegion进行实义化。
typedef struct
{volatile unsigned int CCR;volatile unsigned int CCDR;volatile unsigned int CSR;volatile unsigned int CCSR;
}CCM_Type;#define CCM_BASE (0X020C4000) #define CCM ((CCM_Type *) CCM_BASE)
首先通过定义结构体对象,将MMRegRegion定义到一个Block中。每个成员都有volatile修饰符,表示这是一个MMREG。
命名通常用后缀_Type标识。
然后用宏来定义一个BaseAddress。
基址宏,通常用后缀_BASE标识。
然后将基址宏强转,成为一个结构体对象的指针类型,并实义化为一个宏。
我们称一个结构体对象的指针,为句柄。
这个宏就是宏拟句柄。
+++++++++++++++++++++++++++++++++++++++
5)宏拟函数
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK))
注意,宏拟函数的宏体,必须用一个总括号包含起来。最后不能有分号。
宏拟函数的作用,是将一个操作语句块,或者操作表达式,实义化,模板化。
函数在编译时,会被编译成可调用代码段。这就会涉及到调用开销,
但是宏拟函数,编译时,会就地展开,成为内联代码段。
另一种内联代码段的方法,是static inline 函数。
static inline void IOMUXC_SetPinMux(uint32_t muxRegister,uint32_t muxMode,uint32_t inputRegister,uint32_t inputDaisy,uint32_t configRegister,uint32_t inputOnfield)
{*((volatile uint32_t *)muxRegister) =IOMUXC_SW_MUX_CTL_PAD_MUX_MODE(muxMode) | IOMUXC_SW_MUX_CTL_PAD_SION(inputOnfield);if (inputRegister){*((volatile uint32_t *)inputRegister) = IOMUXC_SELECT_INPUT_DAISY(inputDaisy);}
}static inline void IOMUXC_SetPinConfig(uint32_t muxRegister,uint32_t muxMode,uint32_t inputRegister,uint32_t inputDaisy,uint32_t configRegister,uint32_t configValue)
{if (configRegister){*((volatile uint32_t *)configRegister) = configValue;}
}
内联函数的写法,能够描述更复杂的代码块。
宏拟函数,通常用来描述较简洁的代码,例如表达式。
++++++++++++++++++++++++++++++++++
6)头文件保护,宏标志,宏开关
#ifndef __MAIN_H
#define __MAIN_H...
#endif
检查是否存在宏标志,
有则跳过,没有则打上宏标志。
++++++++++++++++++++++++++++++++