#define _F_START(f) (0 ? f)
#define _F_END(f) (1 ? f)
#define _F_SIZE(f) (1 + _F_END(f) - _F_START(f))
#define _F_MASK(f) (((1 << _F_SIZE(f)) - 1) << _F_START(f))
#define _F_NORMALIZE(v, f) (((v) & _F_MASK(f)) >> _F_START(f))
#define _F_DENORMALIZE(v, f) (((v) << _F_START(f)) & _F_MASK(f))
// //
// Global macros //
// //
#define FIELD_GET(x, reg, field) /
( /
_F_NORMALIZE((x), reg ## _ ## field) /
)
上面是501驱动程序里面的一部分宏定义
#define _F_START(f) (0 ? f)
这句定义令人费解。
学过c语言的都知道有个选择表达式 <逻辑表达式>?表达式1:表达式2
而这里的定义只有(0?f),那么f是什么呢?
通过跟踪程序,我们发现在sm5.h中对寄存器的定义是这样的:
#define CRT_HWC_ADDRESS 0x080230
#define CRT_HWC_ADDRESS_ENABLE 31:31
而调用的时候就是将CRT_HWC_ADDRESS_ENABLE置换其中的f,这样宏定义的式子就是
(0?31:31)。
还有下面的FIELD_GET宏定义,里面有一句reg##_##field,其中##是用来连接前后字符的
例如我们如下调用:
FIELD_GET(x,reg,field);
就等价于_F_NORMALIZE((x),reg_field);
而此驱动程序的编写人员在前面已经有了reg_field这样的宏定义。
它程序中是这样的:
FIELD_GET(regRead32(DEVICE_ID), DEVICE_ID, DEVICE_ID);
其中regRead32(DEVICE_ID)是获得指定寄存器中内容的,DEVICE_ID是设备ID号的寄存器,
然后它在头文件中有如下定义:
#define DEVICE_ID 0x000060
#define DEVICE_ID_DEVICE_ID 31:16
狂晕!不知道编程者为什么要这样去定义,可读性太差了,浪费了不少时间才弄明白!