tag 标签: 编译器

相关帖子
相关博文
  • 热度 3
    2023-9-15 13:17
    630 次阅读|
    0 个评论
    Keil MDK 作为嵌入式行业常用的开发工具,嵌入式工程师们都很熟悉。但是最近听说 Arm 公司要把 Keil MDK 合并到 Arm Development Studio 里,所以 Keil MDK 的版本更新已经基本停止了,大家都还在使用很老版本的 Keil MDK ,功能上并不是很方便,希望找到更好的替代工具。此外,从近期举办的包括 RISC-V 中国峰会在内的多个行业活动来看, RISC-V 在中国的发展如火如荼并且势头很猛,因此还要考虑开发工具是否会长期支持 RISC-V 并可以通过移植重用相关设计。 但是替代 Keil MDK 需要考虑项目工程如何迁移到其他工具,由于工程文件格式不同、以及底层编译技术的差异, Keil MDK 的工程文件与其他工具平台并不完全兼容,需要一定量的迁移工作。本文就根据笔者的经验,分享一下如何快速把 Keil MDK 的代码迁移到其他平台,并且解决不同平台之间项目文件不兼容的问题。 目前迁移 Keil MDK 代码常见的目标平台有两个,分别是 GCC 和 IAR 。下面就给大家分别介绍并比较一下两者的区别: 概览: · GCC 也很常见但是它只是一种编译器,需要配合 IDE 使用,常见的选择有 VSCODE ,或者 Eclipse 这些 IDE ,由于都是免费的组件,需要自己动手搭建,要有一定的 IDE 搭建知识才能使用起来,当然最大的好处是免费。有些朋友因为一些众所周知的特殊原因,不得不放弃使用 Keil MDK ,如果又苦于没有预算购买其他工具的话,就基本上只有 GCC 可选了; · 如果有预算买商用工具,另一个选择是 IAR , IAR 是 Keil 同级别的商用工具,性能与用户体验都不错,且自带 IDE ,不需要配置,直接安装即用。同时,除了支持基于 Arm 的项目, IAR 的 Embedded Workbench 工具还有支持 RISC-V 的版本,这对项目和应用比较多或者希望进一步扩展 RISC-V 架构项目的工程师具有很重要的意义。这是因为从 IAR Embedded Workbench for Arm 移植到 IAR Embedded Workbench for RISC-V 的过程非方便,因为很多文件夹内容已经统一了。 项目迁移流程对比: 首先要声明,迁移项目分为两大部分工作,第一是项目文件格式的适配,第二是项目代码的适配。 1. 项目文件的适配是一定要做的,而且方法和途经比较确定。 2. 正常情况下,如果项目里使用的都是标准 C/C++ ,那么应该编译是没问题的。但是项目代码的适配可能涉及到一些不是标准 C/C++ 的迁移,例如某些特殊要求下,标准的 C/C++ 代码难以实现某些功能,而使用编译器的内联函数( Intrinsic )可以更高效的实现这些功能。如果涉及非标准 C/C++ ,那么就需要用户针对性的对这些非标准 C/C++ 进行跨编译平台的迁移。 关于非标指令的迁移,这里不做介绍,因为涉及的指令太多,不可能在一篇里介绍完,大家碰到了可以单独处理。 下面为大家介绍下通用的项目工程迁移指导: 从 Keil 迁移到 GCC 一般需要修改以下内容: 1. 工程目录配置:从 .uvproj 文件里查看 Keil MDK 的文件目录,把相同的文件配置到 GCC 的 Makefile 文件目录里; 2. 连接( Linker )文件: Keil MDK 的连接器文件是 .sct, 根据对应的描述,可以手写一个 GCC 对应支持格式的连接文件; 3. 启动代码:一般服务好的芯片厂商会制作不同编译器平台的启动代码,在例程文档里可以找找看,如果有看到支持 GCC 的格式,就可以直接拿来用。如果没有的话,就需要手写了。不同的芯片都要单独写启动文件,纯自己手写的难度比较大,需要对芯片非常了解,一般需要芯片厂商的人支持才行,这里不多做赘述。 4. 制作 Makefile 工程文件,包括 a. 源文件的工程目录配置, b. GCC 格式的连接文件替换, c. 把 Keil MDK 的编译参数和连接参数复制到 Makefile 的对应参数中; d. 添加设备信息和调试配置( GDB ) 迁移之后还要进行验证,包含编译结果的验证,编译后可执行文件代码尺寸、运行速度的验证和调整。如果代码尺寸或者运行速度不达标,还需要调整编译器优化选项。调整优化选项后,记得也要重新测试代码执行结果是否符合预期,因为不同的优化选项可能造成代码运行结果的变化。 从 Keil 迁移到 IAR 如果是迁移到 IAR ,推荐使用 IAR 官方的项目转换工具 IAR Project Converter ,迁移过程就会非常方便。在 IAR 的 Embedded Workbench for Arm 工具的菜单栏里,点击 Tools à IAR Project Converter, 就可以自动把 Keil 的工程文件和代码转换成 IAR 格式,最后再把 .s 启动文件换成 IAR 格式的就可以,一般在芯片公司提供的代码示例里都有不同格式的 .s 文件,直接找到 IAR 版本的替换原有的就可以。当然迁移之后还是要校验一下编译是否正常,测试下代码是否运行正常。如果用 IAR ,基本不用担心代码体积变大,或者运行速度拖慢, IAR 拥有非常好的编译优化,一般情况下编译结果会更优,只需要找到合适的编译选项就 OK 了。 总结: Keil 项目迁移到其他平台技术上可行,尤其是代码中不涉及非标的 C/C++ 代码时,具备项目迁移经验的情况下是完全可实施的,需要担心的只是工作量的问题。 至于选择迁移到 IAR 还是 GCC ,主要考虑以下几点: · 是否有充足的预算。 相信大家最常见的迁移原因就是众所周知的合规问题,如果必须迁移,又没有预算,只有硬着头皮转 GCC 了。如果能有预算,可以考虑购买 IAR 正版,选 IAR 的话迁移也都是比较方便的,并没什么风险,付钱的工具还是比免费的要靠谱得多,而且还能得到相应的支持。当然,如果同一家厂商能够同时支持 Arm 和 RISC-V 的工程开发,则可能有更高的投资回报( ROI )。 · 对不同工具的熟悉程度。 跨平台迁移需要对工具有一定的熟悉度,尤其是迁移到 GCC ,由于 GCC 版本众多,又没有成熟的 IDE ,又没有技术支持的情况下,如果工程师对开发工具并不精通,还是很难顺利迁移成功。如果没有相关经验,还是建议选择 IAR ,毕竟 IAR 官方自带的自动化转换工具还是很方便的,如果有正版 IAR License ,还可以有 IAR 官方人员回复你迁移过程中碰到的问题, IAR 官方的技术支持申请链接是 https://www.iar.com/cn/knowledge/support/request-technical-support/ 。 · 迁移风险是否能够接受。 即使是项目的代码本身迁移成功,也不代表项目整体的迁移成功了,有可能迁移到 GCC 之后由于编译性能的降低,生成的可执行代码在现有的硬件平台上性能不满足!最常见的就是代码体积变大, FLASH 不够用了,或者 RAM 不够了,前期努力白费 T_T 。为了避免这种风险,稳妥的路径还是采用商用级别的编译器, IAR 还是比较稳的。 IAR 支持 14 天免费试用,可以直接去申请个试用版试试能否迁移成功,试用链接 https://www.iar.com/cn/product/architectures/arm/iar-embedded-workbench-for-arm/iar-embedded-workbench-for-arm---free-trial-version/ 以上内容基于自己的经验和知识总结,希望对各位考虑项目迁移的朋友们有帮助,如果有错误,欢迎指正! 作者:火星
  • 热度 4
    2023-7-13 23:23
    1445 次阅读|
    0 个评论
    1、编译器和解释器 1.1、编译器 编译器(compiler)对于我们并不陌生,它主要为程序设计语言提供服务,它将各种各样的程序设计语言(比如:C、C++、RUST、JAVA等)进行处理,翻译成我们底层的计算机能够理解并执行相应动作。 程序设计语言准确的定义是:向人和计算机描述其计算过程的记号。 简单来说,一个编译器就是一个程序,其主要用来阅读某一种高级编程语言写的程序,并将其翻译成机器所能理解的目标语言,进而机器用于执行相应的动作。 image-20230707144018800 1.2、解释器 解释器(interpreter)是另一种语言处理器,它与编译器的处理方式不同,它是通过对高级编程语言进行逐行解析来使机器理解并执行相应动作。 简单理解就是:边解析,边执行。 image-20230707144252398 1.3 编译器和解释器差别 编译器 将整个源代码转换为目标代码,然后在执行之前进行链接,生成可执行文件 (先翻译,再执行)。这种方式的好处是程序执行速度快,但是编译过程需要一次性完成,如果出现错误则需要重新编译整个程序。 解释器则是 逐行解释执行源代码 ,每执行一行代码都需要进行解析(边翻译,边执行)。这种方式的好处是可以在程序执行中逐步发现错误,程序员可以更快地进行测试和调试。但是,解释器运行速度相对慢一些。 总的来说,编译器适合编译大型程序,而解释器适合于小型程序或需要频繁更新的场景。
  • 热度 27
    2014-9-28 13:17
    1249 次阅读|
    0 个评论
      在上次的文章里,我们提到了DSP编程中程序优化最常使用到的选项问题,主要提到的几个选项包括-O1、-O2、-O3、-O4等等。虽然我们是以DSP为例进行说明的,但是对于其它的处理器,例如ARM、CPU、一些高级的单片机如MSP430、PIC等等和一些编译环境,例如Keil、XilinxSDK等,它们使用的一般的优化选项和基本内容也是大同小异的,即同样的优化级别,优化的目的都是基本一致的。   这些都是基本的操作,如果我们的目的仅仅是优化代码性能或者尺寸的话。如果我们想了解优化过程中产生和使用的更多信息的话,对于DSP本身而言,它的一些其它特性对于程序的运行性能也是非常关键的,此时在基本的优化选项基础上,我们又要注意一下高级的优化选项的影响。例如,某些汇编指令在做诸如FFT变化的时候能够成倍的提高效率,所以开启高级优化选项使得编译器有针对性地生成相关的指令就非常重要。下面我们看一下编译器的高级优化选项有哪些。因为要考虑到指令集等因素,这里以C28x系列为例进行分析。   表1编译器的高级优化选项         大家可以关注一下我们集芯城的微信公众号,微信号是:icjxc520 微信二维码:                                 来源:EEChina
  • 热度 18
    2014-9-28 11:58
    964 次阅读|
    0 个评论
      在二三十年前人们刚开始使用C语言代替汇编进行开发的时候,因为当初的处理器/控制器性能很弱,而编译器的能力也有限,所以形成了一些C语言编程效率不高的印象。但是今天的硬件性能已经非常强大,而编译器的能力也是日新月异,如果我们不熟练掌握汇编编程中的一些关键技术,编写的汇编代码的效率已经很难超过编译器从C语言转换出来的汇编代码了。   如果我们使用C语言进行编程的话,编译器除了可以把我们的加减乘除这样的操作转换为ADD、MPY以及相关的寻址、寄存器操作外,还可以在编译产生汇编代码的过程中进行不同程度的优化。优化的过程要根据器件的特点与指令集等进行有针对性的配置,所以在不同的器件上同一段C代码优化产生的结果可能不一样,但是其基本思想都是一致的;甚至是不同公司的编译器,在优化选项和优化效果上面也是基本一致的。在CCS软件的编译器中,我们可以使用的基本的优化级别有5级,如表1所示。需要注意的是,别名就是我们在编译器选项中实际使用的名字,因为字体的原因,看起来可能会有混淆,以-O0为例,其中的第一个是字母O是大写的字母0,表示优化Optimization,而不是阿拉伯数字的0;第二个才是是阿拉伯数字中的零,用数字表示优化的序号或者说优化的程度。         根据需要,我们可以选择需要的优化级别,例如可以选择优化代码的尺寸,从而减小代码占用的存储器空间;一般情况下使用-O2或者-O3可以实现在代码运行速度、代码占用的存储器空间和编译速度几个因素之间的最优化。但是优化也是有一定的代价的,首先编译的时间会随着优化级别的提高而增加;其次如果我们的代码不够严谨,可能会产生意外的结果,例如某些看起来没用的变量直接被编译器给“忽视”了,但是我们本来保留它可能是有目的的,例如用来做为调试用的变量,结果它被优化掉了而失去了意义,这时我们就需要使用一些特殊的C语言关键字告诉编译器,这个变量用在这里是有其它目的的,不能把它给优化掉,等等;这些以后可以详解。   关于优化的更多细节,大家可以参考一些有关高效编程的书,因为编译器虽然可以对代码进行优化,如果我们的代码写的太烂,编译器估计也要吐血了。。。 (EEChina)       大家可以关注一下我们集芯城的微信公众号,微信号是:icjxc520 微信二维码:
  • 热度 18
    2014-9-28 11:22
    895 次阅读|
    0 个评论
      也许你已经熟练使用了CCS好多年,可是当某一天出现一个与cl2000有关的错误的时候,突然间也摸不着头脑了;例如使用老版本的还不支持C2000 FPU的CCS来编译28335的程序,cl2000就会提示你各种不支持然后报错不运行了。Cl2000.exe是神马?     Cl2000.exe就是和我们的程序编译密切相关的编译器了,使用的方法是:     cl2000 目标文件]]     使用方法看起来很复杂,还好CCS已经帮我们调用它了(或者说CCS就是一个框架,它完成的编译、调试、链接等功能几乎都需要调用一些别的exe来执行,所以你可能体会过升级了一些库文件、编辑器版本等,界面文件等却不需要进行任何的更改),这些句子会显示在工程的属性里面。当然如果你想亲自体验一把,也可以在ccs安装目录下面的tools\compiler\c2000_6.1.5\bin下面找到它,即cl2000.exe,然后用命令行的方式运行起来)。举个简单例子:     cl2000-v28symtab.cfile.cseek.asm--run_linker--library=lnk.cmd     --output_file=myprogram.out     在上面的例子中,如果需要编译的文件,例如几个.c或者.asm找不到,CCS就会提示xxx.c或者xxx.asm找不到或者未定义了;或者你改了目标文件的名字,例如改成了a.out,但是加载程序到DSP中的时候却仍然使用更改前的b.out,自然有可能出现预料之外的结果了:在以前帮助网友解决问题的时候,确实出现过这样的状况。     明白了编译器的调用方法之后,我们就更进一步,揭开编译器中形形色色选项的神秘面纱,从此看到编译器提示的形形色色的警告和错误不再用发怵。     具体说来,编译器的选项有多大20个大类,超过一百个具体的选项。当然这些选项是有轻重之分的,有的是必须用到的,例如支持一下FPU等功能;有的则是不常接触的,例如MISRA这样的汽车工业软件可靠性检查,只有在对软件进行标准化时才会用到。所以我们首先看一下最常用的选项,例如处理器的选项,它们的意义在于定义了在编译程序时CPU的模式。补充一点是,cl2000的帮助里看到的选项都是很长的名字,在CCS里面为了书写方便(因为选项框就那么点面积啊),一般用别名来代替;没有别名的则直接使用选项名字。     处理器选项 别名 含义 --silicon_version=28 0 为C28x架构的DSP产生目标文件;不选择的话模式为C27x模式,也可以选择为C2xLP兼容模式(例如让C28的CPU支持C24的汇编语句,存在较多的兼容性问题,因为寻找模式、CPU架构等都发生了一定的变化,有的指令不再适用于新器件)。后两种模式大部分网友都几乎不会用到,所以我们的编译器选项里面一般都会选择-v28。更详细的信息可以参考DSP的CPU介绍和汇编编程指南。 --large_memory_model -ml 产生“大内存模式”下的代码。开启这个选项的话,会强迫编译器把整个地址空间当作一块完整的22位宽的空间(实际是分为16位宽的低地址和超过16位宽度之后的高地址空间的),从而使得寻址时使用的指针也是22位的(这个指针是针对CPU寻址来说的,不是我们C程序里用的指针),这样寻找空间就不必局限于2的16次方,即64K了。这种模式适合在C++编程的时候使用,使得编译生成的代码可以访问超过16位宽度的地址空间的存储单元,这样就没有64K字的空间限制了。 那么为什么在在C++编程时使用呢?是因为目前编译器不支持C++的关键字far;如果你了解C++关键字的话,那用同样的思路来理解这个模式就容易了。 此外,在开启FPU的情况下,大内存模式是必须开启的,否则编译器会报错。 在新建C2000的工程,需要添加相关的库文件的时候,如果你再看到有的库是rts2800.lib,有的是rts2800_ml.lib,这次应该明白改用哪个了吧。小建议是为了省事和保持兼容性,没有别的顾虑的话就把这个选项打开吧。 --unified_memory -mt 在“统一的内存模式”下产生代码。顾名思义,就是把所有的存储空间定义为一个整体,这样编译器在编译时就可以使用RPT与PREAD指令来处理大部分的内存复制memcpy调用和结构体的分配(它也不用“担心”存储空间突然出个断层,没法连续寻找了)。例如像下面的汇编指令就可以得到更加高效的执行: MOVL XAR7, #Array1    ;XAR7指向数组1 MOVL XAR2, #Array2    ;XAR2指向数组2 RPT #(N-1) ;重复执行下一条指令N次 ||PREAD *XAR2++,*XAR7 ;Array2 =Array1 ,i++ 这样的一段汇编代码我们可以直接手工编写;如果你有个for循环的C代码的话,看一下编译生成的汇编代码,是不是几乎一模一样的? --cla_support 无 --cla_support是C2833x系列之后的Piccolo系列才有的特性,叫控制规律加速器,意思是把一些与控制系统性能息息相关的代码放到CLA中独立运行,不占用CPU时间,这样整个控制软件的运行速度都得到极大提高,从而保证实时性。 --float_support={fpu32|softlib|fpu64} 无 在启用了-v28和-ml的前提下才能使用;含义是启用软件处理(比如调用一些优化好的库函数)、32位或者64位的FPU协处理器进行浮点运算,从而支持相关的汇编指令。 这这个子选项是不能同时使用的,即使用方法为: --float_support=fpu32 或者--float_support=fpu64等。 需要补充的是,这里的64位浮点运算指的数据类型是long  double,而实际上28335这样的DSP中FPU目前只硬件支持32位的FPU运算,64位的浮点运行要经过CPU折算再送给FPU处理的,所以不是必须的话尽量不要使用FPU64这样的运算。 --vcu_support 无   VCU是F2837xD这样的高端芯片上具备的功能,指的是Viterbi  and complex unit (VCU II) accelerators,即通过采用viterbi 复杂单元  (VCU II)  加速器执行振动分析来更好地预测电机故障,振动信号的来源是加速度 传感器 或者振动传感器等,可以使用流行的 ME MS ,可以贴在电机的外壳、 编 码器 等部位。如果需要   使用这个功能的话,就需要在编译器选项里面打开它。       大家可以关注一下我们集芯城的微信公众号,微信号是:icjxc520                                   来源:EEChina
相关资源