DSP编译显示 cannotfortran allocatee bss in SARAM 怎么回事

DSP软件常见错误_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
DSP软件常见错误
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢DSP错误总结!_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
DSP错误总结!
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢频道本月排行
随机推荐文章
Copyright (C) 2006 - 2016 www.eorder.net.cn
All Rights Reserved当前位置: >>
DSP常见编译错误
1. DSP 编程技巧到底有什么好资料? 话说专门深入讲解这个的资料并不是太多,因为大部分 DSP 书籍都是讲解算法或 者寄存器是怎么使用的,那尽量罗列一下(如有遗漏请在评论区补充),有: (1)《DSP C2000 程序员高手进阶》 这本书是当年笔者学习 DSP 的时候看了好几遍的,讲的非常深入、透彻,可惜早 就卖光了并且没有再版。需要的网友可以考虑去图书馆看看,图书馆里最不缺少的就是 老版本的书籍了。。。 (2)EEPW 牛人业话 我们 EEPW 首页的牛人业话里,已经有大量这方面的总结了,链接太多就不一一 列举了,请到 http://www.eepw.com.cn/news/articlelist/type/39 中阅读。 (3)官方资料 最权威的当然还是官方资料,特别是《TMS320C28x Optimizing C/C++ Compiler User’s Guide》和《TMS320C28x Assembly Language Tools User’s Guide》。不足之处就在于,它们都像教科书,严谨有余,活泼不足,特别是初入门的 人看起来会比较累。 (4)参加一些培训 好的培训一般都是要付费的,这个要根据自己的实际情况进行取舍了。 2. 答疑解惑哪家强? 经验的积累, 除了自己努力的自学之外, 有时候一些难关还是得有别人的帮助才行, 可能你花 3 天搞不定的问题,他一看就想起来是什么原因了。如果是企业客户,那直接 联系官方技术支持,很容易就搞定了。或者也可以去官方论坛提问,然后等待解答。 对于广大网友来说,直接获得技术支持可能有一定的难度。我们 EEPW 的论坛的 人气充足,对问题的响应速度也是迅雷不及掩耳的,所以有关 DSP 的问题尽可以到 http://forum.eepw.com.cn/forum/29/1 下提问。 前面这两个无关具体技术,但是能起到 D源头‖的作用。接下来就是具体的技术问 题了,有几十个,我们慢慢来看吧。 3. 作为入门者,创建一个最基本的工程需要做哪些事情? 最简单的入门方法是从现有的例子上入手,比如购买开发板的话,一般都会附送十 几到几十个上手用的例子工程, 把它们研究一遍, 基本上入门这关就过了。 对于 C2000 DSP 的学习来说, 先到 TI 网站上搜索 ControlSUITE 软件下载安装, 里面的入门视频、 工程例子和所有的文档资料都是一应俱全的。如果你买书籍来入门的话,和教编程的书 籍一样,大部分都还是以DHello world‖作为第一个程序入手,然后运行程序显示在调 试窗口中的。 4. 一个定点的 C28x 起始工程最少需要哪些文件和选项? 1) 编译器选项:-v28 -ml -mt -g -pdr Cw 2) 包含 main()函数的一个.c 或者.cpp 程序 3) 实时运行支持库文件 rts2800_ml.lib 4) 链接文件(.cmd)和头文件:一个小的入门工程,一般从别的工程里把它们复制 过来就好了,比如可以从 ControlSUITE 软件的目录下找到对应器件的。 5. 一个浮点的 C28x 起始工程最少需要哪些文件和选项(启用浮点支持)? 1) 编译器选项:-v28 --float_support=fpu32 -ml -mt -g -pdr -w 2) 包含 main()函数的一个.c 或者.cpp 程序 3) 实时运行支持库文件 rts2800_fpu32.lib 4) 链接文件(.cmd)和头文件:一个小的入门工程,一般从别的工程里把它们复制 过来就好了,比如可以从 ControlSUITE 软件的目录下找到对应器件的。 6. 包含 CLA 和 VCU 的器件,其入门工程需要哪些额外选项? 新器件层次不穷,短短几年时间,包含控制律加速器(CLA)和 VCU 加速器(用来执 行高效 Viterbi、复杂算术运算,16 位快速傅里叶变换 (FFT) 和 CRC 算法)的器件 已经有几十种了,而且像 CLA、VCU 这些技术还在快速地升级中,如果要在代码中用 到这些特性, 就需要添加--cla_support=cla0 和--vcu_support=vcu0 这样的选项。 7. 编译器选项有那么多中,典型的配置有哪些? C28x 编译器的选项非常多, 我们用了很长的篇幅来讲解它们。 作为典型配置的话, 对于 C28x 的 CPU 来说(通常我们把 DSP 的架构划分为 CPU+外设,更复杂的则还有 FPU、CLA、VCU 等额外单元),常用的选项如表 1 所示。
注:如果一个选项没有别名,则代表在使用它的时候直接使用全名,如表 1 的第二 列那样的形式。 8. 含有 CLA 加速器的 CPU 必备的编译器选项? 除了问答 4、5、7 提到的选项之外,CLA CPU 对编译器也有一定的要求,如表 2 所示。 表 2 CLA CPU 必备的编译器选项9. D大内存模型‖和D小内存模型‖的区别是什么? C28x 一般使用大内存模型,假设数据可以存放在存储单元的任何可用空间中。小 内存模型的提出其实针对的是基于 C27x 模式 CPU 的代码, 它默认数据是存放在低 64k 存储空间范围内的,除非使用 far 关键字进行特别指明。现在的 DSP 器件片上存储空 间普遍比较大,显然使用大内存模型更为合理。 10. 什么是D统一内存模型‖? 统一内存模型D--unified_memory‖指在D统一的内存模式‖下产生代码。顾名思义, 就是把所有的存储空间定义为一个整体,不管它是片上的 SRAM、ROM、OTP 还是使 用 XINTF 接口的外部的存储单元,通常把外设的寄存器也映射到数据存储空间中。这 样编译器在编译时就可以使用 PREAD/PWRITE/MAC 等指令来处理大部分的内存复制 memcpy 调用和结构体的分配。 11. 实时运行库 RTS 的作用是什么? 在计算机程序设计领域,运行时库是一种被编译器用来实现编程语言内置函数,以 提供该语言程序运行时(执行)支持的一种特殊的计算机程序库。这种库一般包括基本的 输入输出或是内存管理等支持。在 DSP 的编程中,它们的作用是用来建立 C/C++代 码运行的环境,主要包括以下几个方面: 1) ANSI/ISO C/C++标准库。 2) C 的输入输出 I/O 库。 3) 为主机的操作系统提供底层的 I/O 支持。 4) DSP 的启动程序_c_int00(可参考 http://www.eepw.com.cn/article/262926.htm)。 12. RTS 中函数的描述从哪里可以找到? 在问答 11 中,RTS 包含了四大类内容。前面两者因为是标准 C/C++的内容,并 没有在 TI 的文档中给出额外的说明;此外,C++ STL 库和它们的 API 的使用也没有 TI 官方文档。此时我们可以参考标准 C/C++的书籍、资料、网页等。如果希望最权威 的参考,可以查阅 TI 提供的参考链接: 1) The Standard C++ Library: A Tutorial and Reference, Nicolai M. Josuttis, Addison-Wesley, ISBN 0-201-37926-0 2) The C++ Programming Language (Third or Special Editions), Bjarne Stroustrup, Addison-Wesley, ISBN 0-201-88954-4 or 0-201-) C++ online reference at http://www.cplusplus.com/ 4) C 代码的静态检查工具 http://www.splint.org/ 当然,作为 DSP 的开发人员,高效保质地完成代码工作才是最重要,上面那些书 籍、链接,请慢慢研究吧。。。 14. 从哪里可以找到 RTS 库文件? 通常情况下,随 CCS 软件安装而提供的 RTS 库文件都位于 CCS 安装目录中,编 译器 Codegen 对应的子目录中。例如,在新版本的 CCS6.x 中,C28x 的编译器位于 CCS 安装目录下面的\tools\compiler\c.5\lib 中(根据编译器版本的不同, 倒数第二个目录名字会有相应的变化)。 在老版本的 CCS 中,RTS 库文件被默认安装到操作系统的程序目录中,例如 C:\Program Files\Texas Instruments\C2000 Code Generation Tools 5.2.4。 对于其它一些特殊的库,例如 FPU 快速运行支持库 FastRTS,则在下载安装了 FastRTS 安装包之后,位于其安装目录之下的 lib 文件夹中,例如 \FPUfastRTS\V100\lib\rts2800_fpu32_fast_supplement.lib。如果安装了 controlSuite 软件,则可以通过它内置的说明或者搜索功能找到对应的库文件。 15. RTS 库那么多,我们应该使用哪一个? 随着器件类型、特性的不断发展,现在在 CCS 安装目录下叫 RTSxxx.lib 的文件 已经非常非常多了,那么到底哪些是适合我们使用的呢?对于 C28x 器件,总结如表 3 所示。 表 3 C28x DSP 使用的实时运行支持库 16. 已经启用了 rts2800_fpu32_eh.lib ,为什么还要用 rts2800_fpu32_fast_supplement.lib? 在含有 FPU 的器件上,如果在不启用--float_support=fpu32 编译器选项的情况 下使用浮点数编程,那么它的运算还是 CPU 来执行的,执行效率就和从定点 CPU 上直 接使用浮点运行进行编程一样低;启用了--float_support=fpu32 编译器选项之后, 浮 点数的加法、减法、乘法等操作则有 FPU 来完成,执行效率自然要高出很多。 使用 rts2800_fpu32_fast_supplement.lib 库的目的,则是为了调用 DSP 的 ROM 中的数学表快速计算一些数学函数,包括 atan、atan2、cos、division、isqrt、 sin、sincos、sqrt 等。如果不使用 rts2800_fpu32_fast_supplement.lib 库来完成 这些数学运算,则编译器默认情况下是使用标准 C/C++数学库里的函数来完成这些运 算的,效率自然不能和查找 ROM 中的数学表一样迅速。 那么 CCS 为什么不附带安装 FastRTS 库呢?这可能和在定点 DSP 的使用中, IQmath 库也不是附带安装是通用的道理吧,其它相类似的,一些信号处理函数库,例 如 FFT、IFFT 等也不是 CCS 安装的时候附带的,需要自己去下载安装支持程序。 17. 如何把 RTS 库添加到工程文件中? 如果使用命令行脚本的方式添加库文件,则使用-l &库文件名&来添加即可。 在图形化界面下,填加 RTS 库文件的选项在不同版本的 CCS 中是不一样的,在此 把它们一一列出。 在 CCS6.x 和 5.x 版本下: 在工程管理器中的工程名上点击右键,选择&properties&,然后切换到如下视图。在 CCS4.x 版本下: 在 CCS3.3 版本以及更低的版本下:针对比 CCS3.3 更古老的版本: 如果不习惯使用 Eclipse 样式的开发环境, 或者某 些仿真器不兼容 CCS4.x 以及以上版本,或者你还在使用最古老的 TMS320VC33 这 样的芯片,否则至少应该升级到 CCS3.3 这样的版本了。 18. 在对库文件进行修改,或者使用不同版本的编译器时,如何重新编译库文件? 在编译器版本不低于 6.0.2 的情况下, 我们可以直接使用编译器提供的工具来重新 编译 RTS 库文件,即 Mklib 程序。如需使用此工具,请参考它的帮助说明文档。 在编译器版本低于 6.0.2 的情况下,我们需要进入编译器 codegen 的库文件目录 中,找到 rtssrc.zip 这个文件并解压,然后根据其中 rtssrc_zip_README.txt 里面描 述的步骤进行库文件的重新编译。 22. 除了使用编译器的优化选项之外,还可以使用什么方法提高程序的性能? 编译器的优化选项, 只能在代码满足众多选项的要求时, 才能得到较好的优化效果。 在我们编程的时候,首先要做到心里有数,尽可能使用一些高效的编程方式,例如使用 右移操作代替除以 2 的倍数的操作,可以大幅度地减少代码运行时间等。这些技巧很多 是与 C/C++的熟练使用所相关的。此外,根据器件的特点,例如是否包含 FPU、CLA 等,把特定的代码放在不同的区域执行,也能起到提高程序性能的效果;根据代码对性 能的要求, 把它们运行在不同的位置, 例如 RAM 快于 Flash, Flash 又快于 XINTF 等; 在器件包含数学表的情况下,使用内建的数序函数库,而不是标准的 C 数学库等。在此 我们可以给出一些提示: 1) 代码运行在 Flash 中 一定要使能预读缓冲区,并配置适当的等待状态。一般在各个器件的头文件与外设 示例包里都有对应的例子。 2) 把时间关键的代码和/常数数组等从 Flash 复制到 RAM 中运行 在 RAM 中运行时,最大的指令周期比 Flash 中运行时要高,其执行速度也要快出 不少,所以可以根据需要把实时性能要求较高的程序复制到 RAM 中运行,具体的方法 和实例可以参考 http://www.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber =spra958l 下面的 《Running an Application from Internal Flash Memory on the TMS320F28xxx DSP》。 3) 评估代码和数据的存储地址的划分,并根据需要修改链接文件 i. 如果某段代码和它所读取的数据位于同一个物理内存区间中, 则因为它们使用相 同的地址总线等资源,无法同时访问,造成了资源的冲突,这会降低程序的性能,所以 最好把代码和数据保存在不同的内存区间中。 ii. 等待状态(wait)会降低系统性能,因为 CPU 会执行过多的无用状态且在此期间 无法处理别的任务:当 CPU 读取或者访问存储单元或者外设的时候,该存储器或者外 设有可能在 CPU 默认分配的时间内无法完成数据的传输, 此时就需要在 CPU 的 ready 信号中插入等待状态,直到数据传输完成才能让 CPU 继续执行别的任务。C28x 器件 上,大部分的 SARAM 都是零等待的,但是在 C2833x 器件中,有一些模块却不是, 例如某些 Flash/OTP 的访问等。 iii. 如果在代码中大量使用两个数据缓冲区,则把两个数据缓冲区存放在不同的 RAM 模块中有可能会提高代码的性能, 因为大量读写同一块 RAM 区间会产生更多的流 水线停滞,造成性能的降低。 4) 使用编译器中的统一内存模式--unified_memory 此模式把所有的存储空间定义为一个整体,这样编译器在编译时就可以使用 RPT 与 PREAD 指令来处理大部分的内存复制调用和结构体的分配。 5) 使用 Flash 和外部存储器 如果代码需要在 Flash 或外部存储器中运行,则在编译时开启-me 选项。它将禁 止编译器使用快速分支指令(SBF/BF),转而使用普通的跳转指令(SB/B)。BF 指令在 默认情况下是被启用的,它能够将跳转分支使用的指令周期从 7 个降低到 4 个,在零 等待状态的 SAM 中执行时,快速分支指令的预读特性使得它较为高效,但是在非零等 待的存储器中执行时,SBF/BF 的预读反而造成了性能的下降,此时需要人为地对预读 和等待进行规划。 6) 使用内联函数 在编译时开启内联函数功能,则编译器会自动把多次调用的函数进行内联,大大减 少函数调用和返回操作所带来的开销。当然,根据D空间换时间‖的原则,开启内联会增 加一定的代码尺寸。 23. 为什么一个 char 类型的数组中,每个元素都占用了 16bit 的地址? 这是因为在 C28x 上,字节(byte)和字(word)是等价的:也就是说它们都是 16 位或者说 16 比特(bit)宽的,即 sizeof(int) == sizeof(char) == 1。 24. sizeof(int) == sizeof(char) == 1 貌似与 ANSI 标准是相违背的? 在 ANSI/ISO 的 C 定义中, sizeof 操作符以字节形式给出了其操作数的存储大小。 ANSI/ISO 还规定,sizeof 操作符取 char 的值时,返回值为 1。因为 TMS320C28x 中的字节是 16 位的,char 也是 16 位的,所以 sizeof 的结果符合 ANSI 标准的。 作为补充,选 16 位,而不是 8 位或者别的什么位数作为 char 的宽度,主要是为 了统一寻址的便利,虽然在某种程度上说这增加了一定的存储器空间占用,或者说浪费 了一些空间,因为它们在存储空间中制造了一些空洞。 25. 如果 char 是 16 位的,那么如何高效地访问 8 位的值? 可以使用__byte()和__mov_byte()这样的编译器内联函数。请参考 http://www.eepw.com.cn/article/265102.htm。 26. 编译结果提示 undefined symbols,名字中包含$符号,怎么破? 名字中带美元符号的函数,例如 FS$$MPY, FS$$TOL 等,都是 RTS 库里的内置 函数,编译器提示我们这些函数未定义,表明我们没有把对应的 RTS 库给加入到工程 中,例如 MPY 是数学函数,需要添加相关的数学库,例如 FPU 数学库等。 27. 链接器提示“_c_int00 is not defined”,怎么破? 在 http://www.eepw.com.cn/article/262926.htm 这篇文章中,已经分析了 _c_int00 的含义。找不到_c_int00 的话,说明我们遗漏了包含它的 RTS 库,例如 rts2800_ml.lib、rts2800_fpu32.lib 等待,这些 RTS 库的具体区别在答疑解惑的第 15 条中已经有对比了(http://www.eepw.com.cn/article/265108.htm)。 28. 新版本的编译器中,printf()/sprintf()函数貌似要使用更多的栈? 这是因为 printf()函数被重新修改了, 以支持多个级别的 printf 格式说明符支持和 修正,以减少代码大小和总内存大小(包括 bss)。printf 由 sprintf()间接调用,它使用 一个 400 个元素的大小的局部数组。为了保存一致性,printf()一直都在使用这么大的 内存空间,而编译器也在尽量避免使用 malloc()进行内存分配。与老版本所不同的的 是,此数组以前是静态的,而现在它被保存在.bss,而不是栈中;这样做的目的是,如 果用户使用 C I/O,则他们往往会在使用合适尺寸的栈的同时尽量减小.bss 的使用。 29. 如果不需要 printf()/sprintf()的全部特性,怎么样才能减小代码体积? 初学者往往使用 printf 打印DHello World‖这样的方式来完成第一个 DSP 编程的 程序,这种方法虽然是非常直观明了的,感觉起来功能也是非常简单的,但是一编译结 果发现提示栈的空间不够,或者有Dprogram 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\c.5\lib\src。在此路径下,有 3 个 printf 函数 对应的 c 程序,它们与链接器选项的对应关系如下表所示。由此我们也可以看出, 支持全部格式的 printf 的源程序的大小, 达到了最小格式支 持下源程序大小的 23 倍还要多。 30. CCS 编译器是否支持任何工业标准? 1) 所有的 TI DSP 支持的 C 语言标准: C89 (ISO/IEC ,或者叫 NSI X3.159-1989) C99 (ISO/IEC ). 不完全支持。 2) 不支持的 C 语言标准: C11 (ISO/IEC ) 3) 支持的 C++标准: C++98 (ISO/IEC ) C++03 (本质是 C++98 的 bug 修复) 4) 不支持的 C++标准: C++ TR1 C++11 (ISO/IEC ) 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&versi on=cqwj 来报告 bug、查看/分享解决方案等,其界面如下图所示:避开老旧的D传统‖bug 的最好办法当然是定期升级编译器和开发环境了。 通过配置, 新版本的 CCS 在启动后会自动检测升级并自动升级,这也简化了我们对开发环境的维 护工作。 33. 链接文件中包含那么多个段,有什么快速识别的方法? 把下面这个例子记牢就好了: // // Global variables x & y ==& .ebss // Initial values 2 & 7 ==& .cinit // int x = 2; int y = 7; void main() { // Local variable =& .stack z = x + // 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 选项,这样在在未定义的输出段被创建时,开发环境的控 制台窗口中会产生相关的警告信息。 35. 虽然可用的存储空间看起来比 section 的长度要大,但是链接器为何提示 “placement fails for object”? 这种情况一般是因为段的空间的分配是并不是我们想象中的连续的一个紧挨一个, 而是被编译器给D分块‖管理了。在内存地址分配时,一个段需要完全适配到页(page) 中,或者从页的边界开始连续分配;为了满足这个要求,段在分配到页中时,可能无法 完全利用某些页,导致内存地址中产生了间隙(hole),使得实际所需要的内存空间超过 了根据变量大小计算出来的理论值。编译器这样做的目的是为了优化数据页(DP)寄存 器的加载,达到减小代码尺寸和优化程序性能的目的。例如,针对一个数组,如果数组 的长度小于 64 字(words),则编译器仅需安全地加载 DP 一次就可以访问数组的全部 元素;如果数组长度大于 64 字,则在访问每 64 字的数组元素时,编译器仅需加载一次 DP,当然如果访问多个 64 字的数组元素则仍需要多次加载 DP。 举例说明: 在 cmd 里定义: RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */ commbuf : & RAMM1 PAGE = 1 在 main.c 里定义以下几个变量 #pragma DATA_SECTION(sendT, &commbuf&) Uint16 sendT[260]; #pragma DATA_SECTION(receT, &commbuf&) Uint16 receT[260]; #pragma DATA_SECTION(CntPPR, &commbuf&) Uint32 CntPPR[250]; 表面上共需 260+260+250*2=1020,commbuf 正好放得下.但 ccs 提示空间 不够: (run placement fails for object &commbuf&, size 0x474 (page 1). Available ranges: RAMM1 size: 0x400 unused: 0x400 max hole: 0x400) 产生错误的原因是根据 DP 加载的原则,page 被划分为 64word 的小单元,而数 组被存储在连续的、整块的单元上,未使用到的空间不会再分配给其它数组或者变量使 用。所以 16 位 260 长度的数组实际占用了 64*5=320 (64*4=256&260),32 位 500 的长度实际占用了 64*8=512, 占用的总长度为: 320*2+512=。 按照 CCS 的提示,commbuf 占用空间是 320*2+500=,但是事 实上 32 位数组占据的最后那个 page 已经无法被别的变量使用了,所以如果还有新的 变量出现的话,会提示 RAMM1 块缺少的地址更多。 根据我们的需要,可以在每次之间内存读取操作之前都加载 DP,这样就可以禁用 上面的D分块‖管理特性了。这样做虽然可以减小内存地址空间中的D间隙‖,但是每一次 访问内存都需要加载 DP,反而大大地增加了代码的尺寸,实在是得不偿失(看起来很少 有人会这么做)。我们可以通过启用编译器的-disable_dp_load_opt,或者叫-md 选 项来实现这一方法。 确认某个段是否被编译器给分块管理的方法就是使用.bss 和.usect 指令,具体内 容请参考 http://www.eepw.com.cn/article/263821.htm。 36. 链接器提示“placement fails for object '.text'”,我们如何为.text 分配更多的内存? .text 段中包含包含所有可执行的代码,以及编译器编译产生的常量。如果我们的 代码比较大,超过了 cmd 文件中默认分配的空间,则.text 无法适配到内存空间中,就 会产生上面的错误。通常有三种方法可以来为其分配更多的空间。 方法一:修改 cmd 这个我们已经提到过, 请参考 http://www.eepw.com.cn/article/256732.htm。 方法二:分割.text,把它平均分配到多个内存区域中 这个方法比较直观,前提是几个内存区域的总长度要满足要求。例如: .text : && FLASHA | FLASHC | FLASHD, PAGE = 0 方法三:完整分割法 这个名字有点古怪,它本质仍然是把.text 分割,目标区域也可以有多个,但是当 第一个区域就满足要求时,则只把它分配到第一个区域中,剩余的目前区域实际上未被 使用到。 在实际编程实现时,这些方法仍然存在一定的限制,包括: 1. 在包含控制律加速器 CLA 的 Piccolo 器件中,只有特定的内存区域可被 CLA 所使用。 2. 在含有 DMA 的器件中,并不是所有的内存都可被 DMA 所访问。 3. 一般情况下,SRAM 都是单个机器周期内只能访问一次,但是 0 等待状态的。 但在一些器件中,程序内存控制是包含等待状态的,例如在某些 2833x 器件中,DMA 可访问的数据空间是 0 等待状态的,但是程序控制是 1 等待状态的。这些 SRAM 空间 更适合纯数据访问类型的使用。 37. 在 cmd 文件中,可以把连续的 Flash 模块组合为一个整体的区间吗? 答案是可以的。 在 Flash 的烧写中, 可以在同一时间被烧写的 Flash 的最小长度被 称为扇区(sector),所以通过把我们的代码进行分区烧写,就可以把它们对齐到扇区。 Flash 模块结合的方法一:直接合并法 以把两个 Flash 扇区组和为一个段为例: 合并前,两个扇区的定义是: MEMORY { // // Individual sectors E and F called out in the MEMORY description // ... FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */ FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */ ... } 合并之后的 Flash 区间为: MEMORY { // // Sectors E and F merged into one in the MEMORY description // ... FLASH : origin = 0x310000, length = 0x010000 /* on-chip FLASH F & FLASH E */ ... } 方法二:反其道行之,把段分配到多个 Flash 模块中,与问答 36 的方法二是一致 的,例如: SECTIONS { .text: { *(.text) } && FLASHE| FLASHH } 38. 在 cmd 文件中,可以把相邻的 SARAM 模块组合为一个整体的区间吗? 答案是可以的,方法与 Flash 组合的方法一样。 虽然这样做是完全没有问题的, 但需要牢记 SARAM 模块都是单个机器周期内只能 访问一次的,所以为了优化程序的性能,最好把代码给分区到不同的物理 SARAM 模块 中,这样可以减少大量读/写操作中的资源冲突。 39. 对于 DSP/BIOS 的工程,如何了解链接的信息? DSP/BIOS 的配置工具生成一个 cmd 文件, 规定如何连接所有 DSP/BIOS 生成 的程序段, 并且默认链接至所有 C/C++ 语言编译程序生成的程序段。 当从 RAM 运 行程序时,可能只需要这一个 cmd 文件就够了。但在当从 Flash 中执行时,很有可能 需要生成且连接一个或多个自定义的程序段。 此外, 任何配置片载 Flash 控制寄存器(例如, Flash 等待状态)的代码不能从 Flash 执行。我们也许需要从 RAM(而非 Flash)中运行特定时间关键函数来大幅提升性能。 必须创建一个自定义 cmd 来处理这些我们定义的程序段。可以参考 Running an Application from Internal Flash Memory on the TMS320F28xx DSP 这个文档, 其示例代码在 http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumbe r=spra958&fileType=zip。 需要注意的是, 这些文档和程序与新版本的 CCS 中所包含 SYS/BIOS 并不是完全 兼容的。 此外, 如果我们想使用第三方的操作系统, 例如 VxWorks、 us/OS、 INTEGRITY 等,则要根据这些 RTOS 的特点进行内存的分配与管理。 43. Error: option --include_path is missing its parameter 'dir',如何 解决?本文引用地址:http://www.eepw.com.cn/article/267640.htm这个错误的发生往往是编译器没有能够正确地解析包含变量或者宏的头文件的路 径。解决方法可以利用上图中的 Variables 选项卡,点击 Add,把自定义的变量添加 进去,此时 CCS 会检查该编译器变量是否符合标准。 44. Error: unresolved symbols remain,如何解决?出现这个错误说明链接器在符号表中找不到相关的符号定义。在这个例子中,源程 序 example 中使用了函数 myfunc,但是在编译生成的所有目标文件(.obj)或者所有 的库文件(.lib)中都找不到这个函数。 解决的方法自然是找到这个函数从哪里来的?然后 把它的源添加到工程中。 在使用 Stellarisware 或者 ControlSuite 套件中的例子来创建我们自己的工程时, 如果忘了使用―library 选项把库文件添加到链接器的路径里,则经常会出现此错误。 这些库文件包括:Stellarisware/Tivaware 中的 driverlib, grlib, usblib, ControlSuite 中的 driverlib, IQMath 等等。 那么接下来的步骤就是添加对应的库文件了。最直接的方法是在工程属性里选择, 如下图所示:此外, 如果在 C++代码中引用 C 代码的头文件, 如果这个头文件是自定义的(而不 是系统提供的), 则最好在头文件中添加 extern &C& {...}以方便在 C++代码中方便使 用#include 来引用该头文件。那么问题又来了:C 编译器不认识 extern &C&怎么办? 此时要使用#ifdef 这样的宏来在 C 中屏蔽它们,即: #ifdef __cplusplus extern &C& { #endif 45. Error: placement fails for section &xxx&,如何解决?这个错误说明我们定义的段超过了指定存储器区间的大小。 可以从以下几个方面来 解决此问题: 1. 检查栈和堆的长度, 看看是不是给它们配置了过大的值, 导致了在 RAM 中保存 不下去?然后尝试减小它们的长度。 2. 尝试使能或者增加编译器的优化级别,未经优化的代码往往需要更多的存储空 间。 3. 如果使用了 I/O 代码,则它们会显著增加代码尺寸,例如在很多小容量的器件 上,一个 printf()函数就能超过存储容量了,此时可以使用 printf()的最小格式,请参 考 http://www.eepw.com.cn/article/266820.htm。 4. 可以考虑修改 cmd 文件,以增加某个段所使用的存储空间的长度;代价是别的 存储空间的长度会相应减小,有可能导致新的 placement fails 这样的错误产生。具 体可参考 http://www.eepw.com.cn/article/256732.htm。 5. 尝试精简/优化代码,在不影响功能的情况下,使用一些编程技巧来减小代码尺 寸。 例如,我们可以使用D空间换时间‖,或者D时间换空间‖的方法,在代码尺寸和执行 速度上做一些折衷。比如对于一个滑动傅立叶变换(sDFT),我们既可以使用很大的数 组来保存滑动值, 从而实现很高的运算速度;也可以减少运算速度,每个周期只使用几 个点来完成计算,这样可以极大地减小存储空间的占用。 6. 不到万不得已,不要去考虑更换芯片。 但是如果在产品开发的评估阶段,存储空间就已经捉襟见肘了,则还是要提早考虑 升级芯片的,不然以后再增加新的功能,或者哪怕是仅仅修正了一个小的 bug,有可能 就彻底放不进去了。 46. Tag_Memory_Model attribute value of &1& that is different than one previously seen (&2&); combining incompatible files,是神马意思? 这个错误表明链接器所链接的目标文件中存在不同的内存模式, 比如说有的目标文 件使用了大内存模式,而有的使用的是小内存模式。修改的方法则是让所有的文件在链 接时都使用相同的内存模式。 事实上这种错误出现的场合并不算太多, 主要出现在工程中引用了别人提供的某些 obj 文件或者库文件的时候。在 C2000 上,新建工程的时候推荐大家统统使用大内存 模式(-ml)选项。 47. Error: file grlib.lib& was built without VFP coprocessor support while a prev combining incompatible files,是神马意思? 这个错误与上面那个错误的原因是类似的, 表明链接器所链接的目标文件中存在不 同的浮点支持模式。修改方法则是让所有的目标文件和库文件使用相同的浮点支持 --float_support 选项。 48. 为什么编译的时候总是提示 Warning: creating output section &xxx& without a SECTIONS specification? 在使用默认的 cmd 文件进行编程, 而工程中有使用了某些 cmd 中未明确定义的段 的时候,就会出现这个警告。因为没有在 cmd 中定义这个段,所以链接器会使用默认 的算法来创建和分配输出段DXXX‖;这样虽然能保证程序的工作,却不被建议这样做, 因为它不利于内存地址空间的有效分配和管理。通常来说,最好不要有任何的链接器警 告,以消除程序运行时潜在的 bug。 49. 莫名其妙的 gmake: Access is denied。 在编译程序的时候,编译器会生成一系列的中间文件,包括 obj、lib、asm 等等, 这个过程被一些带有主动防御系统的杀毒软件和安全软件当作危险行为, 因此就被禁止 掉了,导致编译失败,如下图所示:所以在编译程序的时候,最好禁用安全软件,不然即使是安全软件没有直接阻止编 译,也会跳出各种各样的询问信息,不胜其扰。 50. Type 'xyz' or Symbol 'abc' could not be resolved。 这些错误一般是由 Eclipse CDT (C/C++开发工具)错报出的,而不是由 TI 本身 的编译器所给出的。目前的解决方法是: 从 CCSv4 的工程升级到 CCSv5 或者更高版本的时候,如果选择的是 project--导入工程,一般会有一定的兼容性问题,可能会产生这样的错误。解决方案则是创建一 个新的工作区,然后把所有的源程序、库文件、cmd 文件等导入到新的工程中,重新 配置工程选项,然后再编译。 或者干脆忽略 CDT 的语法错误,方法是在 CCS 中点击 Window-&Preferences-&General-&Editors-&Text Editors-&Annotations, 选 择 C/C++ Indexer Markers,然后清除掉所有的选择。 51. Warning: build attribute vendor section TI missing in & : compatibility cannot be determined。是什么属性丢失了? 出现这个问题,说明使用的库文件是由一个老版本的编译/链接工具所创建的,在 使用新版本的工具进行编译/链接时,这个老的库文件缺失了某些属性,导致了这个警 告的产生。在 C2000 DSP 的开发中,有几个场合特别容易出现此警告: ? 在新的编译环境中,使用了一个老版本的 IQmath 库文件。 ? 在测试时,使用了老版本的编译器生成的 Flash API。 ? 在使用高分辨率的 HRPWM 模块时, 使用了老版本的 SFO 库文件来修正 MEP。 这个警告总的来说并不影响程序的运行, 我们即可以通过把老的库文件换成最新版 本来彻底解决此问题, 也可以在 cmd 文件中使用--diag_suppress=16002 来消除此 警告信息。至于 16002 这样的警告信息是如何归类的,在 CCS 的编译提示里就有: #16002-D build attribute vendor section TI missing in &c:/ti/ccsv6/tools/compiler/C.2/lib/IQmath.lib&: compatibility cannot be determined 52. fatal error: file .....rts2800_fpu32.lib& specifies ISA revision &C28FPU32&, which is not compatible with ISA revision &C2800& specified in a previous file or on the command line。 这个致命错误说明对某些不是 FPU32 的目标文件启用了 --float_support=FPU32 选项进行编译,例如这个目标文件是由不含有 FPU 的器件 上的编译编译而来的时候就会产生,也有可能是这个目标文件没有使用 FPU 选项。解 决的方法是: ? 如果导致错误的目标文件是支持 FPU 的,则使用-v28 --float_support=FPU32 来编译所有的程序。在 CCS 中,可以把这个选项作为全局 选项,或者预编译选项。 ? 如果器件不支持 FPU,则不要使用 FPU32 选项。这是因为在含有 FPU 的器件 中, float 类型的变量会传递到 FPU 寄存器中进行处理;而在不含有 FPU 的器件中, float 类型的变量仍然会保存到栈中。 53. Warning: entry-point symbol other than &_c_int00& specified: &code_start&。 初学者经常会遇到此问题。事实上这个警告并不会对程序的运行产生什么影响,它 只是用来告诉我们,程序的入口点被编译器给自动分配到 code_start,而不是默认的 _c_int00 中;它们的效果是一样的,含义请参考 http://www.eepw.com.cn/article/262926.htm。TI 提供的外设例子在编译时也 经常会产生此警告。 54. Error: unresolved symbols remain.... 符号 FD$$MPY、FD$$TOL 之类的找不到,这样的问题也是初学者经常遇到的。 这样的问题说明相关的库函数被使用了,但是库并没有被添加到工程之中。例如,在程 序中使用了 c = IQdiv(a,b);这样的程序,但是并没有把 IQmath.lib 添加到工程中, 则 IQdiv 就会被提示 unsolved 这样的错误, 解决方法则是把对应的库文件添加到工程 里就好了。 特别说明:带有两个美元符号$$的函数一般都是实时运行库 RTS 里的,一定要记 得添加对应的 RTS 库文件。 55. Error: Tag_ISA attribute value of &2& that is different than one previously seen (&1&); combining incompatible files. 这个错误表明 ISA 版本这个属性不正确。其中,1 代表 C27x,2 代表 C28x。在 使用 C28x 时,应该使用-v28 这样的选项来使用 C28x 模式,而不应该再使用其它的 兼容模式了。 56. Error: placement fails for object &csmpasswds& 在早期版本的 CCS5.x 编译器/链接器中,有这个问题,链接器会不停地提示相同 名字的段被既保存在 page0,又被保存在 page1 之中,直到我们把它们改好;这算是 一个 bug 吧,升级编译工具 codegen 的版本,或者干脆升级整个 ccs 软件,就可以解 决此问题。 57. Warning: function declared implicitly 虽然这只是个警告,但是它表明函数的原型不存在,编译器会对函数的参数和返回 值做一些假设,这就是 bug 的一种源头,所以一定要把这个警告给消除掉。 58. 为什么一个看起来很简单的程序,链接的时候却要花费很长的时间? 导致这种现象的最主要的原因是类型合并(type merging)。 那什么是类型合并呢? 举个简单的例子, 在头文件 types.h 中定义了结构 sss, 且所有的.c 中中都引用了这个 types.h。 因此在编译之后, 描述 sss 的调试类型信息被包含到每个目标文件之中(除非 使用了--symdebug:none 来禁用调试信息),因此在链接的时候,链接器会发现有很 多个 sss 类型的副本;默认情况下, 链接器使用类型合并把这么多 sss 类型合并为一个, 从而使得最终输出的.out 文件中只有一个 sss 类型,而不是很多个重复的副本,达到 减小代码尺寸的目的,并且使得 CCS 在加载.out 文件时也会花费更少的时间。然后, 类型合并这个过程中需要大量的计算,因此导致了链接看起来需要花费很长的时间。 解决的方法有两个: 1. 禁用类型合并:使用链接器的-b 选项(含义请参考 http://www.eepw.com.cn/article/249328.htm)。这样做的结果是链接的时间变 短, 但是.out 文件变大, 需要更长的时间来加载;如果在这个例子中 sss 的副本非常多, 有可能需要很差的时间来加载.out 文件。 2. 使用--symdebug:none 选项来完全禁止把调试信息写入.out 文件。 这样做既 可以减小链接时间, 又可以减小.out 的尺寸和缩短加载时间, 但后果是代码的调试功能 被大大削弱了。 59. 如何使用一个.cmd 文件在含有不同的内部存储空间的芯片上来实现段的优 先级? 假设有下面的状况: 器件 1 有 64kb 快速的内部存储,而器件 2 有 128kb。现在我们有 4 个关键的代 码段: .text:_a : 20kb .text:_b : 30kb .text:_c : 20kb .text:_d : 10kb 其中段 a 的运算重要性最高,段 b 的次之,以此类推。 给片内的快速存储器命名为 IRAM,而片外的慢速存储器命名为 SDRAM。假设在 器件 1 上,我们必须把.text:_a 和.text:_b 保存在 IRAM 中以保证运行速度, 而.text:_c 和.text:_d 则既可以保存在 IRAM,也可以保存在 SDRAM 中。在器件 2 中,因为片上存储显著增大,可以把 abcd 四个段都保存在 SDRAM 中。此时我们可以 使用下面的方式,使用同一个.cmd 文件来完成段的分配:这一段语句的作用有两个: (1) 在分配存储空间时,按照顺序来确保配段的优先级。在.cmd 文件中,如果需 要保证段的优先级,则必须使用 GROUP 这个指令;如果不使用则段之间不会有优先级 的关系,此时链接器会有效把长度最大的那个段优先分配空间,以最大程度地减少存储 空间中的空隙。 (2) 自动在不相邻的存储空间 IRAM 和 SDRAM 中划分输出的段。 两个大于号D&&‖ 也是链接器的内部指令,它用来表明 GROUP 中的段可以被划分到不同的存储空间里。 例如,当链接器在器件 1 上,发现在分配完.text:_a 和.text:_b 到 IRAM 中之后,发 现.text:_c 有 20kb,IRAM 的空间已经不足以存放它时,它会跳过把 text:_c 分配到 IRAM 上,而是把 text:_c 分配到 SDRAM 中;接下来链接器会继续尝试把 text:_d 给 分配到 IRAM 中(如果 text:_d 的长度足够小的话)。而在器件 2 上,编译器会发现空 间足够存放 abcd 四个段的时候,就把它们四个一起保存到 IRAM 中了。 如果我们使用下面的两种方式,结果会是什么样的呢?使用这个方法仍然可以做到段的分割,即上面的第二条,然而它们之间空间分配的 优先级没有办法保证,很有可能使得程序的性能受到影响。使用这个方法仍然可以做到段的优先级,即上面的第一条,然而在器件 1 上这些段 将无法全部保存到 IRAM 中,最终导致链接器的错误。。 60. 为什么需要开启链接器Cw 选项? -w 的含义是:在未定义的输出段被创建时产生警告信息。因此,如果我们在程序 中创建了段,例如:但是在 cmd 文件中没有明确段的类型(例如.text、.bss 等),则链接器将有可能任 意地给我们自定义的段分配一个地址控制,这将导致严重的运行时错误。例如,链接器 有可能任意地把我们自定义的段给分配为 FLASH 这个段类型,但是实际上它们并不在 Flash 中运行,结果导致代码完全不执行。 使用-w 选项将使得链接器必须提示我们有关段未定义的信息,从而避免上述问题 的发生。 61. 链接器地址映射文件中的 trampolines 代表什么含义? 在链接之后,打开生成的.map 文件,可以查看地址映射信息,如下图所示。 其中的 TRAMPOLINES 在英语里是D蹦床‖的有意思,在这里的含义则是代表非直 接跳转的向量。它的含义与蹦床运动是一样的,代码执行到 trampoline 之后会立刻跳 转出,或者回弹。当跳转指令无法到达目的地时,链接器会自动产生 trampoline, 然 后我们就可以看到上图所示的那些信息了,它们的含义是: callee:函数被调用。 addr:callee 的地址。 tramp:链接器自动为 trampoline 所产生的名字。 addr:trampoline 在存储器中的地址。 call addr:从 trampoline 产生的调用所使用的地址列表。 call info:包含最初调用的目标文件和输入段。如果目标文件保存在某个库中, 则会把库文件的名字也显示出来。 62. 在 C 编译器中使用内联的汇编指令的情况下,为何代码的实时运行出错了? 在 C 代码中,我们可以使用 asm()指令来插入汇编代码。如果插入的这段汇编代 码修改了 C 代码所使用的运行环境中的寄存器,则会破坏 C 代码的数据,导致运行时 出错。所有在 C 代码中使用内联的汇编代码时务必小心,不要破坏了程序的完整性。
赞助商链接
DSP一些常见问题(1)_信息与通信_工程科技_专业资料。【转】DSP CCS 初学调试...引申: 补充概念: cmd 文件 用于 DSP 代码的定位。由于 DSP 的编译器的编译...dsp 编译错误与解决方法_军事/政治_人文社科_专业资料。1,ERRORdsp...DSP实验常见错误及解决方... 4页 免费 BCH编译码的DSP实现 3页 1下载券 #...DSP软件常见错误_信息与通信_工程科技_专业资料。1、仿真器驱动的问题。CCS 和...4、编译错误:symbol xxx is defined multiple times. (1)因为库文件的问题,...4)DSP 的 C 的效率较高,非常适合于嵌入系统。 为什么在 CCS 下编译工具工作不正常? 在 CCS 下有部分客户会碰到编译工具工作不正常, 常见错误为: 1)autoexec....1、syntax error 语法错误 2、MEMORY specification ignored RAMM1 不存在的内存...dsp 编译错误与解决方法 暂无评价 4页 免费
DSP程序编写和调试的常见... 12...VisualDSP5.0++下的常见错误和BUG_专业资料。今天有空,把 VDSP 下的常见错误...解决办法:更新到 VisualDSP++4.5_Update_6.vdu(或之后的版本)。 编译出现“...ccs编译错误_计算机软件及应用_IT/计算机_专业资料。CCS3.3常见编译错误 ...3、Include Search Path C:\CCStudio_v3.3\MyProjects\DSP2833x_common\...本文是我学习DSP的时候遇到的各种问题的总结,文中详细的介绍了问题的解决方案,...(7)使用中断处理函数和一些编译选项冲突,注意避免对包含中断处理函数的C 程序...DSP程序编写和调试的常见问题_信息与通信_工程科技_专业资料。DSP 仿真器为什么必须...由于 DSP 的编译器的编 译结果是未定位的,DSP 没有操作系统来定位执行代码,...dsp/bios 的程序,编译链接无错误,而点击 LOAD Program 下载 xxx.out 完成时...但实际开发 DSP/BIOS 应用程序时为了真实的了解目 标板的各种信息,仅有 ...
All rights reserved Powered by
www.tceic.com
copyright &copyright 。文档资料库内容来自网络,如有侵犯请联系客服。}

我要回帖

更多关于 cannot run in wd 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信