微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > DSP编程技巧之:不得不看的编译指示

DSP编程技巧之:不得不看的编译指示

时间:12-21 来源:互联网 点击:

  编译指示(Pragma Directives)可能是所有的预处理指令中最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对编译器给出了如何处理特定的函数、对象和代码段的方法,在保持与C/C++语言完全兼容的情况下,给出主机(比如C28x)或操作系统(比如DSP/BIOS)专有的特征。这些编译指示的使用较为复杂,但是我们还必须要了解它们,因为它们是程序中必不可少的东西,例如#pragma DATA_SECTION ( symbol , " section name ");这样的。但是往往讲解它们的资料又不多(因为大部分资料集中在入门指南上面),所以在此我们就总结一下针对C28x编译器的pragma指令,再遇到它们的时候就不会一头雾水了。

  1. CHECK_MISRA

  它的作用与在编译器选项中使用--check_misra是相同的,都是对特定源文件使能MISRA-C:2004规则检查(汽车工业软件可靠性联会),使用方法是:

  #pragma CHECK_MISRA (" {all|required|advisory|none|rulespec} ");

  其中的rulespec是具体MISRA中的规则,使用方法请参考DSP编程技巧之12-揭开编译器神秘面纱之代码规范MISRA-C。

  2. CLINK

  CLINK指令可用于某段代码或者某个数据符号,使用之后会在包含被作用符号的段中产生一个.clink指示,表明在条件链接的情况下,如果这个段没有被其它任何段引用的话,这个段可以被移除,从而减小链接输出文件的尺寸。使用方法是:

  #pragma CLINK (symbol )

  3. CODE_ALIGN

  CODE_ALIGN用来沿着特定的对齐参数constant来对齐函数(从而可以让CPU更快寻址,更快执行指令)。当我们希望函数从特定的边界开始的时候,这个指令非常有用。参数constant必须是2的幂(偶数对齐),使用方法是:

  C代码: #pragma CODE_ALIGN ( func, constant );

  C++代码: #pragma CODE_ALIGN ( constant );

  注:在本文中,在C和C++代码中,指令使用方法一样时,不分别写出,如不一样则分C代码和C++代码分别写出。C代码中的#pragma指令一般需指定函数名,也即其作用域;C++代码中的#pragma指令一般不带有函数名,其作用域为紧邻该指令后面的函数;下同。

  4. CODE_SECTION

  CODE_SECTION是较为常见的指令,默认情况下,代码被存放在.text段中,使用此指令则用来指定并改变某段代码所分配的段,其使用方法是:

  C代码: #pragma CODE_SECTION (symbol , "section name ")

  C++代码: #pragma CODE_SECTION (" section name ")

  例如:

  char bufferA[80];

  char bufferB[80];

  #pragma CODE_SECTION(funcA, "codeA")

  char funcA(int i);

  char funcB(int i);

  void main()

  {

  char c;

  c = funcA(1);

  c = funcB(2);

  }

  char funcA (int i)

  {

  return bufferA[i];

  }

  char funcB (int j)

  {

  return bufferB[j];

  }  5. DATA_SECTION

  DATA_SECTION可能是使用最多的pragma指令了,它用来定义存储某个符号所使用的段,使用方法是:

  C代码: #pragma DATA_SECTION ( symbol , " section name ");

  C++代码: #pragma DATA_SECTION (" section name ");

  例如:

  #pragma DATA_SECTION(bufferB, "my_sect")

  char bufferA[512];

  char bufferB[512];

  6. 与诊断信息有关的Pragma

  诊断信息一般包括:提醒,警告,错误和不提示等几个级别,使用与诊断信息有关的Pragma和使用相关的编译器选项的结果是一样的,其使用方法以及们的对应关系如下:

  Pragma对应的编译器选项

  有关诊断信息的含义,请参考DSP编程技巧之7---揭开编译器神秘面纱之预处理与诊断。

  7. FAST_FUNC_CALL

  使用这个指令,会在编译时调用快速汇编指令FFC,而不是传统的CALL指令来完成函数的跳转,其使用方法是:

  #pragma FAST_FUNC_CALL ( func );

  它的使用范围是受限的:仅限于调用返回LB *XAR7指令的汇编程序。例如:

  ;汇编程序

  _add_long:

  ADD ACC, *-SP[2]

  LB *XAR7

  //调用汇编的C程序

  #pragma FAST_FUNC_CALL (add_long);

  long add_long(long, long);

  void foo()

  {

  long x, y;

  x = 0xffff;

  y = 0xff;

  y = add_long(x, y);

  }

  除此之外,如果使用该指令,编译器会输出警告信息,并忽略其指示。

  8. FUNC_EXT_CALLED

  在我们启用程序级别的优化选项时(-O3),所有未直接或者简介被main函数调用的函数都将被优化掉,但是这些函数也有可能被我们定义的某些汇编代码使用到,所以使用FUNC_EXT_CALLED可以在编译时保留这些代码,其使用方法是:

  C代码: #pragma FUNC_EXT_CALLED ( func );

  C++代码: #pragma FUNC_EXT_CALLED;  9. FUNCTION_OPTIONS

  使用这个选项可以在编译C/C++代码中的某些函数时,使用额外的编译器的命令行选项,实现与在命令行中输入相关的命令同样的效果。其使用方法是:

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top