答疑解惑哪家强?当属咱们EEPW最强。。。接下来持续咱们的答疑解惑。
29. 假如不需求printf()/sprintf()的悉数特性,怎么样才干减小代码体积?
初学者往往运用printf打印“Hello World”这样的办法来完结第一个DSP编程的程序,这种办法虽然是非常直观明晰的,感觉起来功用也是非常简略的,可是一编译成果发现提示栈的空间不可,或许有“program will not fit into available memory”之类的过错。这是由于规范的printf()/sprintf()供给了非常多的特性支撑,造成了在DSP上完成时,发生的代码尺度非常大。
此刻咱们能够根据需求调整不同等级的格局格局限定符,例如经过链接器的选项,咱们能够指定–printf_support=full, minimal或许nofloat, full为默许参数,表示支撑一切的格局;nofloat不支撑对浮点类型的数据的输入/打印,包含%a,%A, %f, %F,%g,%G,%e和%E,支撑其它的字符、定点格局等;minimal:对数据格局的最小支撑,只包含了不指定数据宽度和精度标志的整形、字符型或许字符串,即只支撑%%,%d,%o,%c,%s和%x格局。其详细意义可参阅http://www.eepw.com.cn/article/236048.htm。需求留意的是,假如–printf_support运用了不支撑的格局,链接器并不能给出特定的实时运转库的过错提示,在运用时要仔细检查。
此外,假如不去指定链接器选项,咱们也能够修正printf函数默许对应的源程序_printfi.c来完成相似的作用,它的途径一般在编译器的库函数目录下,例如\ti\ccsv6\tools\compiler\c2000_6.2.5\lib\src。在此途径下,有3个printf函数对应的c程序,它们与链接器选项的对应联系如下表所示。
由此咱们也能够看出,支撑悉数格局的printf的源程序的巨细,达到了最小格局支撑下源程序巨细的23倍还要多。
30. CCS编译器是否支撑任何工业规范?
1) 一切的TI DSP支撑的C言语规范:
C89 (ISO/IEC 9899:1990,或许叫NSI X3.159-1989)
C99 (ISO/IEC 9899:1999). 不完全支撑。
2) 不支撑的C言语规范:
C11 (ISO/IEC 9899:2011)
3) 支撑的C++规范:
C++98 (ISO/IEC 14882:1998)
C++03 (实质是C++98的bug修正)
4) 不支撑的C++规范:
C++ TR1
C++11 (ISO/IEC 14882:2011)
5) IEEE-754 (ISO/IEC/IEEE 60559)规范:
TI的ARM和DSP的C/C++编译器支撑32位和64位的二进制浮点数运算,能够支撑IEEE754规范中大部分特性。
6) MISRA-C
MISRA C是由汽车产业软件可靠性协会(MISRA,motor industry software reliability association)提出的C言语开发规范,在操控有关的代码中是非常有用的规范,详细运用办法可参阅http://www.eepw.com.cn/article/247057.htm。
7) 其它规范
在工业领域中,safety安全特性在一些运用场合中已经是要求有必要具有的功用了,相关的规范包含IEC61508、TÜV认证等。现在已经有一部分包含硬件safety特性的DSP器材了;假如运用软件来完成这些特性,则现在还需求咱们自己来编写代码以支撑这样的特征。
31. CCS编译器对GCC扩展的支撑怎么?
GNU编译器结合GCC支撑许多规范ANSI/ISO C/C++所不支撑的特性。在开源运用和Linux等开发中,GCC的编译器gcc和g++等都被广泛运用。所以为了确保对GCC东西所开发的代码的兼容性,TI的编译器也支撑某些GCC的扩展特性。现在支撑的一些特性根本都包含在GCC4.3中,可检查:http://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/C-Extensions.html。
32. 怎么了解有关编译/代码发生东西的已知问题,并取得最新进展?
老外喜爱用IBM的ClearQuest体系来陈述bug并共享解决方案,咱们能够运用TI供给的敞开链接https://cqweb.ext.ti.com/cqweb/#/SDo-Web/SDOWP&format=HTML&version=cqwj来陈述bug、检查/共享解决方案等,其界面如下图所示:
避开老旧的“传统”bug的最好办法当然是定时晋级编译器和开发环境了。经过装备,新版本的CCS在发动后会主动检测晋级并主动晋级,这也简化了咱们对开发环境的维护作业。
33. 链接文件中包含那么多个段,有什么快速辨认的办法?
把下面这个比如记牢就好了:
//
// Global variables x & y ==> .ebss
// Initial values 2 & 7 ==> .cinit
//
int x = 2;
int y = 7;
void main()
{
long z; // Local variable => .stack
z = x + y; // Code => .text
}
34. 为什么咱们需求链接文件.cmd?为何编译器不能主动分配存储空间并进行内存办理?
在操作体系存在的状况下,这些作业的确不需求咱们花费太多的心思。可是在嵌入式的DSP处理中,这样做的首要原因是处理才能和存储空间是非常有限的,有必要要咱们进行必定的介入,例如咱们需求考虑的要素包含:
1) 运转速度:在RAM中比在Flash中快,在Flash中又比在外部存储器(运用XINTF)中快。
2) 代码是否需求存储在非易失的存储器中(例如Flash)?
3) 使命是否是时刻要害的?例如需求把某个时刻要害的ISR被保存在Flash中,然后运转时复制到RAM里。
4) 一些RAM可被DMA模块所拜访,而另一些则不可。
5) 运用独自的物理RAM模块来防止资源的抵触。例如,在C2000 DSP中,RAM模块都是在单个机器周期内只能拜访一次的SARAM(Single-access RAM)。
6) 资源是否坐落外部存储器中?
7) 代码是否需求保存在包含缓存或许预读的存储器中以进步功能?在C2000DSP中,咱们简直见不到缓存或许预读的概念,它们一般出现在包含ARM处理器的器材中。
8) 存储器在程序空间、数据空间中是否具有等候状况?
9) 是否有需求被代码安全模块CSM所维护的代码?CSM并不能维护一切的代码空间。
以上这些要素,在咱们编程时也是需求特别重视,乃至是较为头疼的工作,明显让编辑器去主动完成它们,在现在阶段是不可能的(除非编译器的算法有一天能完成必定程度的人工智能)。所以在现阶段,咱们需求运用链接器指令文件cmd去描绘每个段所需求运用的内存状况。
假如咱们没有把某一个特别的或许自定义的段给指定到特定的存储空间中,则此刻链接器会主动把它给分配到一个可用的存储空间里,这有可能会影响到程序的履行作用。所以咱们要敞开编译器的-w选项,这样在在未定义的输出段被创立时,开发环境的操控台窗口中会发生相关的正告信息。