x86 下64 位整数的声明方法:(嵌入式常用long long)
1. __int64 var1;
2. unsigned __int64 var2
x86 下inline 的使用方法(要改为__inline)
直接改project->[setting]->[c/c++]->Preprocessor definitions:编辑框里输入inline=__inline即可
读代码:
宏:本质上只是一种替换,是一种预处理。宏可以被展开成一段代码,或者一个表达式。
带参宏使得宏的展开依据传入参数来展开。这样带参宏形式上像一个函数,使得宏依据参数被展开为不同的代码和表达式,
增加了宏的灵活性。
宏可以嵌套,就是说如果宏展开后,里边还有宏,则宏还要进一步展开。
使用宏,可以实现多平台,多项目共用一套代码,修改config.h
众多的头文件包含的是哪一个呢 ? 看你编译时包含的是谁!
下面看一个例子:
GPFDAT = 0x10; // 意思为把0x10 送给gpio f 端口的数据口。
由此可以判断,用c 语言应该是 *(gpid_addr + portf_off + portf_data_off) = 0x10
那么怎样定义这个宏呢 ?
第一层。定义GPIO 宏,加入端口偏移与寄存器偏移。
#define GPFDAT bGPIO(oGPIO_F, oGPIO_DAT)
#define oGPIO_F 0x50 //端口可以依次定义,实现了灵活性
#define oGPIO_DAT 0x4 /* R/W, Data register for port */ // 实现了简单性
第二层。定义寄存器宏,加入GPIO 基地址
#define bGPIO(p,o) __REGl(GPIO_CTL_BASE + (p) + (o))
#define GPIO_CTL_BASE 0x56000000
第三层。定义寄存器宏。实现对内存单元的左值访问。
#define __REGl(x) (*(volatile unsigned long *)(x))
由此可见,这个宏是三个数值替换,并把它写成内存访问的形式。
也许把一系列的寄存器地址排列起来,组成一张大的地址表。 然后对每一个地址用__REG宏包装。形成对寄存器的访问
这样二层宏就够了。 而上面基址加偏移则构成了三层宏。 这主要应该看spec 是怎样给定寄存器地址的。
; ---------------------------------------------------------------------------
再看一个宏:
第一层
#define TCFG0_PRE1(x) FInsrt((x), fTCFG0_PRE1)
第二层。参数和名称又是宏
#define fTCFG0_PRE1 Fld(8,8) /* prescaler value for time 2,3,4 */
#define FInsrt(Value, Field) (UData (Value) << FShft (Field))
第三层。
#define Fld(Size, Shft) (((Size) << 16) + (Shft)) // 始见天日。是对形式参数的运算
#define UData(Data) (Data)
#define FShft(Field) ((Field) & 0x0000FFFF)
注1: 如果一个带参数宏,其宏定义只是对形式参数的操作,则宏已经分解到底。
如果一个带参宏,其展开式的名称或参数仍然是一个宏,则需要进一步展开,这称为宏的嵌套。
宏的嵌套的过程,用以引入新的变量。
注2: 该宏的解释。
1. fTCFG0_PRE1 是一个常数8<<16+8
2. FInsrt(Value, Field) 之FShft(fTCFG0_PRE1), 也是一常数
3. 再把x (左移一个常数)
所以,该宏的意义为把参数x 固定左移一定位置。就这么简单。 这是这个固定的常数,需要有一个构造过程。
; ---------------------------------------------------------------------------
当你移植linux 代码到windows, 会用到windows 的libc 函数。
使用了linux 的putc, 便不能用windows 的putc 了吗 ? 怎样使二者结合呢? 结合点?!
不要包含windows下头文件,那样你会被windows 头文件所纠缠,可以适当声明要使用的windows 函数的函数原型。
一般,引入一个printf或putc 就可以了吧。
补补课: stdout 是在stdio.h中定义的宏。
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
而这个_iob 是外部定义的FILE 结构
_CRTIMP extern FILE _iob[]; 是在libcmtd.lib 的 _file.obj 中定义的。
printf 则在libcmtd.lib 的printf.obj 中定义