【原创】TI C2833x介绍---外设寄存器的头文件(3)
0赞前面两次讲了两种不同的寄存器定义以及调用的方法。直观上看,书写、记忆方面的不同是它们的区别,那它们的代码大小、代码的效率会不会有什么不同呢?
我们可以看一下同一段代码,分别采用两种方法书写,编译生成的汇编文件的区别。
以一个CPUtimer操作的程序为例。首先是结构化的定义法(开启相同的编译器选项,都不使用优化选项):
源程序为:
// Stop CPU Timer0
CpuTimer0Regs.TCR.bit.TSS = 1;
// Load new 32-bit period value
CpuTimer0Regs.PRD.all = 0x00010000;
// Start CPU Timer0CpuTimer0
Regs.TCR.bit.TSS = 0;
生成的汇编程序为(可以在单步调试的时候直接在ccs里面看到,或者开启CCS编译时生成.asm文件的选项):
MOVW DP, #0030
OR @4, #0x0010
MOVL XAR4, #0x010000
MOVL @2, XAR4
AND @4, #0xFFEF
编译生成的代码只占用了5个字,执行时间为5个时钟周期(也说明我们CCS的C编译器是十分高效的!)。
那传统的方法会不会效率和结构化定义法一样呢?是变好还是变差?我们看一下;
源程序为:
// Stop CPU Timer0
*TIMER0TCR |= 0x0010;
// Load new 32-bit period value
*TIMER0TPRD32 = 0x00010000;
// Start CPU Timer0
*TIMER0TCR &= 0xFFEF;
编程生成的汇编程序为:
MOV @AL,*(0:0x0C04)
ORB AL, #0x10
MOV *(0:0x0C04), @AL
MOVL XAR5, #0x010000
MOVL XAR4, #0x000C0A
MOVL *+XAR4[0], XAR5
MOV @AL, *(0:0x0C04)
AND @AL, #0xFFEF
MOV *(0:0x0C04), @AL
从代码的长度我们就可以明显看出,传统方法生成的代码,其占用的存储空间和执行时间都明显变长了。
读到这里你可能会问,二者的目的是一样的(停止CPU定时器,重载它的周期值,然后重新启动定时器),为何后者的效率要差?分析为:
- 结构化的定义方法可以更好地利用DP寻址模式以及我们很久之前提到的28x的CPU所支持的一种叫“原子指令”的读写简化机制(Atomics Read/Modify/Write)。
- 而#define这样的定义方式依靠指针来进行随机存取,无法有效利用C28x的Atomic操作。