paradoxfx

【原创】TI C2833x介绍---外设寄存器的头文件(3)

0
阅读(3191)

前面两次讲了两种不同的寄存器定义以及调用的方法。直观上看,书写、记忆方面的不同是它们的区别,那它们的代码大小、代码的效率会不会有什么不同呢?

我们可以看一下同一段代码,分别采用两种方法书写,编译生成的汇编文件的区别。

以一个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定时器,重载它的周期值,然后重新启动定时器),为何后者的效率要差?分析为:

  1. 结构化的定义方法可以更好地利用DP寻址模式以及我们很久之前提到的28x的CPU所支持的一种叫“原子指令”的读写简化机制(Atomics Read/Modify/Write)。
  2. 而#define这样的定义方式依靠指针来进行随机存取,无法有效利用C28x的Atomic操作。