原创 arm嵌入式系统开发高效程序的技巧

2008-10-9 15:05 1574 4 4 分类: MCU/ 嵌入式

开发高效率的程序涉及很多方面包括编程风格算法实现针对目标的特 殊优化等等这部分主要从 ARM 的体系结构特点出发介绍几个程序开发中的注意点如何根据目标硬件的存储器配置对运行程序的映像文件进行优化布局 的方法,在前面的专题中已经有过介绍。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


Tag嵌入式系统 嵌入式程序开发 arm


1 变量定义 变量定义虽然很简单,但是也有很多值得注意的地方。


 


 


第二个问题是局部变量的类型定义。一般情况下人们总是设法使用 short char 来定义变量以节省存储器空间但是当一个函数的局部变量数目有限的情 况下编译器会把局部变量分配给内部寄存器每个变量占用一个寄存器这样, 使用 short char 型变量不但起不到节省空间的作用,还会带来其他的副作用,请看图 2。假定 a1 是任意可能的寄存器,存储函数的局部变量。同样完成加一 的操作,32 位的 int 型变量最快,只用一条加法指令。而 8 位和 16 位变量,完 成加法操作后,还需要在 32 位的寄存器中进行符号扩展,其中带符号的变量, 要用逻辑左LSL接算术右ASR条指令才能完成符号扩展无符号 的变量要使用一条逻辑AND指令对符号位进行清零所以使用 32 位 的 int unsigned int 局部变量最有效率某些情况下函数从外部存储器读入局 部变量进行计算这时候往往值得先把不是 32 位的变量转换成 32 (至于把8 位或 16 位变量扩展成 32 位后隐藏了原来可能的溢出异常这个问题需要进


一步的仔细考虑


 


 


变量定义中还有一个与习惯思维相悖的地方是冗于局部变量的使用一般情况下程序员总是竭力避免使用冗余变量,以精简程序。通常情况下这是正确的, 但是也有例外,请看下面一个例子:



int


f(void);


 


int


g(void);


// f()g()不访问全局变量errs


int


errs;


// 全局变量


void test1(void)


{   errs += f();


errs += g();


}


void test2(void)


{   int localerrs = errs;           // 定义冗余的局部变量


localerrs += f();


localerrs += g();


errs = localerrs;


}


 


 


在第一种情况 test1每次访问全局变量 errs 时都要先从相应的存储器 load 到寄存器里 f g函数调用后再 store 回原来的存储器里面在 这个例子里一共要进行两次这样的 load/store 操作而在第二种情况 test2里, 局部变量 localerrs 被分配以寄存器这样一来整个函数就只需要一次 load/store 全局变量存储器了能够节省存储器访问的次数对于系统性能的提高是非常有好处的。


 


 


这个例子说明了增加局部变量可以减少存储器的访问。


 


2 参数传递


 


 


ARM 的工具链里定义了统一的函数过程调用标准 ATPCSARM-Thumb Procedure Call StandardATPCS 定义了寄存器组中的{R0 – R3}作为参数传递和 结果返回寄存器如果参数数目超过四个则使用堆栈进行传递我们知道内部 寄存器的访问速度是远远大于存储器的所以要尽量使参数传递在寄存器里面进行,即应尽量控制函数的参数在四个以下。这是理解 ATPCS 后应该实现的一种 编程风格但是利用 ATPCS 我们还可以得到更多我们可以用它来实现 C 与 汇编之间直接的函数调用。见图 3 中的例子:


C 中直调用汇编函数


extern void strcopy(char *d, const char *s);


 


 


int main(void)


{


const   char *src = Source”;


char       dest[10];


...


strcopy(dest, src);


...


}


AREA StrCopy, CODE, READONLY EXPORT strcopy


 


 


strcopy


LDRB            R2, [R1], #1


STRB             R2, [R0], #1


CMP              R2, #0


BNE               strcopy


MOV             PC, LR


 


 


END


 


 


这个例子中的函数 strcopydest, src)用汇编来实现,根据 ATPCS 的定义, 函数参数从左到右由寄存器进行传递,所以在汇编中可以直接由 R0 R1 进行 引用。有了这条途径,在 C 和汇编之间进行相互调用就容易实现了。


 


3 循环条件


 


 


记数循环是程序中十分常用的流程控制结构。在 C 中,类似下面的 for 循环 比比皆是:


 


 


for (loop = 1; loop <= limit; loop++)


 


 


这种累加计数的方法符合一般的自然思维习惯所以比下面的递减计数方法使用 更多:


 


 


for (loop = limit; loop != 0; loop--)


 


这两者在逻辑上并没有效率差异但是映射到具体的体系结构中就产生了


 


因此,在 ARM 的体系结构下编程,最好采用递减至零的方法来设置循环条 件。


 


4 条件执行


 


 


上面已经提及了 ARM 指令的条件执行,充分利用这个特性,可以有助于缩短代码长度,优化流程控制。


 


5 混合编程


 


 


汇编和 C/C++语言的混合编程在一个追求效率的程序中是比较常见的前 面已经讲到过在汇编和 C/C++之间进行函数调用时,要遵循 ATPCS 的定义。这 里介绍在 C/C++里加入汇编程序的两种方法:内联汇编(Inline Assemble)和嵌 入式汇编(Embedded Assemble


 


内联汇编是指在 C/C++函数定义中插入汇编语句的方法,如下面的例子:


void enable_IRQ(void)


 


{


int tmp;


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />asm                                                          //  内联汇编定义


{


MRS tmp, CPSR                                     //  可以引用外部的 C 变量定义


BIC tmp, tmp, #0x80


MSR CPSR_c, tmp


}


}


 


 


内联汇编的用法跟真实汇编之间有很大的区别并且不支持 Thumb在内联


汇编之中不能直接访问物理寄存CPSR 除外即使使用寄存器名进行编程, 也会被编译器进行重新分配。


 


 


与内联汇编不同,嵌入式汇编具有真实汇编的所有特性,同时支持 ARM Thumb是不能直接引用 C/C++的变量定义数据交换必须通过 ATPCS 进行。 嵌入式汇编在形式上表现为独立定义的函数体,如下所示:


 


 


asm int add(int i, int j)                                  // 定义嵌入式汇编


{


ADD R0, R0, R1                                     // Value of i in R0 and j in R1, result in R0


MOV PC, LR


}


void main()


{


printf("12345 + 67890 = %d\n", add(12345, 67890));


}


 


 


灵活使用内联汇编和嵌入式汇编,可以帮助提高程序效率。


6 性能分析 很多时候需要对程序的执行效率和性能进行分析直接测试当然是最真实的


途径,但是这种方法除了在运行时间上进行定量外,很难得到确切的数据信息。 而指令集仿真这种方法ARMulator  ISS,恰恰为程序执行过程中处理器的 行为提供了一个参数统计方法。


 


通过在感兴趣的代码段两端设置参考点把执行过程中处理器的各种状态周 期精确地统计出来作为性能分析最直接的分析数据 6 中所示是一段例程在 ARM7TDMI 上面运行的状态统计,可以计算出平均每条指令花费的处理器时钟 为 1.9 左右进行代码优化时目标就是减少非顺序访问周期和内部等待周期数。


7 小结 代码优化是个很大的题目这里只是抛砖引玉索引几个要点进行讨论


多这方面的知识,可以参阅这方面的众多论述和著作。


 


 


至此,关于在 ARM 体系结构下进行嵌入式系统编程的 6 个专题已经全部结 束。对此感兴趣的读者可以访问 http://www.armodm.com 进一步了解更多有关 ARM 的技术资料。


 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条