【分享】由MDK平台(UTF8原因)更换为IAR平台后的一些个人经验

2019-12-12 18:22发布

本帖最后由 huchunlei 于 2015-4-6 18:23 编辑

       最近使用STM32开发一个带触摸屏(480*640)的控制器,使用uCOS-III 3.04 和 emWin 5.26,一开始使用的是MDK平台开发的, MDK 版本是 5.14,使用的STM32F103ZG,库版本是 3.5。

       首先说说我用MDK遇到的问题:东西都快开发完了, 最后想给控制器加开机界面,就是显示产品名称,公司名称之类的, 界面上产品名要用一个大些的字体, 结果发现 以前使用的 一个第三方的 emWIM字体生成器(应该是以前ucgui时期的一个生成器,在emWIM下也能使用) 生成 其他大的字体存在问题, 因此就想到了使用emWIN官方的字体生成器(网上有完整版下载的 5.16版本),结果发现 emWIN 的字体生成器使用的是 Unicode编码,而MDK编译器默认情况使用的是 电脑系统的编码(中文操作系统使用的是 GB2312编码),结果字体对不上。   后来发现 网上有一种方法就是 把 C文件  用记事本打开,另存成 UTF-8的编码就可以了,试验之后果然可以, 但是也带来了一个问题,更改编码后的文件,在使用MDK编辑器修改之后,在保存,就成了乱码了, 后来又借助网络发现, MDK有一个选项里面可以把编辑器的编码改成UTF-8(菜单Edit->Configuration->Editor),果断改成了 UTF-8,以为这样就万事大吉了, 结果又出现一个新的问题,问题如下(太长了,另起一段吧):

       已经是 UTF-8编码格式的 C语言文件,使用MDK的编辑器修改后保存,乱码现象到没出现, 但是编译的时候,编译器却对C文件里面的中文字符串识别出现了问题,总是说字符串后面缺少引号, 显然是没正确识别。  但是,把这个C文件使用 Window的记事本打开后, 在另存为同样的文件覆盖之前那个,在编译的时候就不出错了。这令我很纳闷,都是UTF8格式的文件,为何一个文件没问题,一个文件有问题。

       使用 UltraEdit 打开 2个一样的C文件,一个是 记事本保存的,一个是 MDK 编辑器保存的, 对比了一下发现,    Windows 记事本保存的 UTF-8的文件,在文件开头处 比 MDK 保存的文件 多了3个字节(EF BB BF),而MDK自己的编辑器没这3个字节,直接就是文件内容了。  经过网上搜索,发现 这多出来的3个字节是 微软为了标记UTF-8文件而自己加进来了, 标准的文本文件 不应该 加这个标志,针对这个问题花了将近1天的时间都没有解决(尝试过 修正 MDK 的 编辑器 或者是 编译器,但是由于不是计算机专业的,看着一堆十六进制代码,最后还是放弃了)。  到这我就很奇怪了, 虽说MDK 的 平台 和 ARMCC 编译器不是一起开发的,但是你集成在一起给用户使用, 这个最低级的错误都会出现, 真不知道说什么好了。  后来网上看到 有人跟我遇到 一样的问题了,并且证明是 MDK的BUG, 低版本的 MDK 4.5 没这个问题。

       解决MDK问题方法:由于MDK使用不便,因此决定更换为 IAR平台,IAR平台使用的是最新版本 IAR ARM 7.40,装好IAR后,首先试一下编码的问题,果然IAR 也有更改编码的选项(菜单Toos->Options->Editor),里面除了 UTF-8,还有很多编码可选,比MDK强多了。另外,在编辑器的编辑区点右键还有”Character Encoding“选项, 选项里面还有“Convert to UTF-8” ,这个方便多了。 使用 Convert to UTF-8 这个选项把 C文件转换为 UTF-8编码后,编译也正常了,没出现MDK那个问题。     后来,由于好奇,用UE打开看了 IAR 保存的C文件,是没有“EF BB BF”这个文件头了, 跟MDK一样,  然后我在在想如果多了 文件头,IAR的编译器还认吗, 于是就用记事本保存了一个 UTF8的文件(会添加文件头),在编译,果然编译出错了, 看来对于 IAR 而言, 不要使用 记事本编辑 代码最好。  用IAR 自己的编辑器不存在任何问题。

       但是更换为IAR平台后,也遇到了一些问题,下面我列举出来,供大家参考,免得跟我一样走了很多弯路:

       1、编译通不过,有错误。  由于平台不同, 针对 CPU进行优化的那些汇编代码,比如ucosIII的汇编代码,启动文件,我都更换过了, 怎么还有错误呢? 后来发现是由于新版IAR的原因,跟 ST 的库 3.5 版本 的 CMSIS 文件存在不兼容,因为把以前库里面的 CMSIS 2个文件(C和h文件)删除, 在IAR的工程右键菜单 Option->General Options->Library Configuration,里面勾选上“Use CMSIS”,这样就可以了。

       2、编译通过,大量警告。经过查看警告,发现基本上是2种,一种是 浮点数 隐性 转换 为整数,另外一种是 volatile 修饰的全局变量 直接参与了计算。 这个2个问题,确实是我写代码没有注意到的问题, 但是MDK 却没给出任何警告, IAR 还是尽职一些。修改之后,编译0警告,0错误。

        3、uCOS-III 不能启动,执行 OSStart(&err); 后却没有进入第一个任务。 这个确实花了我大量时间,最后又跟 uCOS 官方的代码进行比较后,发现我在启动OS之前 没有禁用 中断。  果然 加上禁用中断的代码,可以启动了。 奇怪的是,以前在MDK平台下,没加这个代码也是没有问题的,IAR却不行了。 估计是MDK编译的代码里面针对CPU已经做了一些初始化工作,而IAR 却没有, 而需要我们自己去处理。

       4、使用 sprintf 转换 浮点数 出现问题。这个问题,我开始以为好解决,因为IAR里面有设置(在IAR的工程右键菜单 Option->General Options->Library Options里面),把printf 使用的库,选择 Full, 结果一测试,还是不行。 后来经过大概半天时间的查找(期间一度认为IAR有BUG),后来发现 是我的 uCOS-III的任务堆栈没有 8字节对齐, 因为之前在 MDK里面使用了关键字 __align(8) 对齐, 到了IAR 平台下,由于不认这个关键字,就给删了。 当时看任务能够运行,还以为不对齐也没问题,看来我又想错了。 后来在IAR下加了 对齐的修饰, 浮点数的打印也好了,IAR下使用的方法为:#pragma data_alignment=8。


       至此,经过2天的调试,又发现了IAR的一些优点,比如:

       1、编译速度比MDK快, 这个就不多说了, 用过人都有感觉。
       2、代码优化的比MDK好,比如我用的 emWIN系统,用MDK编译出来的程序,运行中切换界面,个别地方总会卡一下,当时试了多种不同的写法,都不能解决,还以为emWIN存在BUG, 用了 IAR 才发现, 原来没这个问题,是编译器的问题。
       3、代码存在的不规范的地方,IAR 能发现并警告,而MDK却不能,上面我提到了, 对于提高代码质量而言,我觉得IAR 做的比 MDK好。
       4、错误的代码,IAR运行必定会出错,而MDK不一定(当然我这个说法也不是绝对的)。  比如我程序里面有一个函数中有个变量,应该用 static 修饰的,却忘了加 static ,结果用MDK编译运行 没发现问题(也可能是暂时没发现问题),而用IAR 编译运行后,到这个地方必定出问题, 这我才发现了这处错误。
       5、由于使用 uCOS-III, 为了保证每个任务分配的堆栈够用而且不浪费,我在程序里面 做了个 信息打印输出, 每1秒输出1次,以此来观察每个任务 的CPU占用率,堆栈占用率等信息。 而使用了IAR 之后发现,IAR的调试 可以勾选 uCOS-III 插件, 在线仿真过程中可以,看到每个任务的运行状态,比我打印的那些信息多得多。 看来IAR 又为我节省了CPU资源的开销了。



        以上这些是我这3天以来的调试经历,写出来给大家参考下,尤其是新手, 免得跟我一样,本来半天可以搞定的事情,弄了3,4天。同时也给自己建个备忘录吧。

        最后,还有一个问题没有解决,就是IAR 左侧的工程列表,里面的文件夹和文件,如何排序,MDK是可以排序的, 而IAR 默认是按照文件名自动排的,也没找到在哪里设置。用鼠标脱的话,只能是把一个文件 放到另外的文件夹里面,顺序改不了。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。