搜索
bottom↓
回复: 11

stm32移植日志之五

[复制链接]

出0入0汤圆

发表于 2009-9-3 21:07:30 | 显示全部楼层 |阅读模式
看本文请参考《都江堰操作系统与嵌入式系统设计》第15章,该书可在www.djyos.com下载。
    djyos使用gcc作为编译器,已经5年多了,要抛弃它,实在是一个艰难的抉择,需要下很大的决心。在移植日志中,专门为gcc写一篇,以示纪念。
当初选择gcc做编译环境,是因为gcc支持的cpu种类繁多,可以简化djyos移植到其他cpu平台的工作,现在证明,这种想法大错特错!这次将djyos从ARM7移植到stm32的过程中,花了大量的时间折腾gcc后,仍未成功,而从0开始学习MDK到成功编译djyos,花费的时间竟然比花在gcc上的时间少得多。
    所以说,企图通过gcc简化cpu间移植工作是不现实的,新的cpu应该去学习它的专业开发环境,才是王道。也许,在linux环境下编译linux应用程序,gcc是最合适的,但用来编译非linux程序,gcc真的不适合。5年多来,gcc把我折腾得够呛,让gcc再去折腾djyos的用户,让我于心何忍!
    空口无凭,让事实说话,过去的就不说了,也没有留下什么记录,下面谈谈这次把djyos移植到stm32的过程中gcc给我的苦头。

牛头马嘴的出错信息
    我们知道,要使用gcc编译,就必须编写makefile和ld文件,这两个文件的书写规矩还真多,有些地方要用[tab]键,有些地方要用空格,有些地方又不允许空格,有些地方可以空行,有些地方不允许空行。违反了这些规矩,如果能给出正确的错误信息也行,可惜的是,给出的信息和真正的错误根本牛头不对马嘴!略举几例:
1、makefile中可以使用shell的printf命令,如果被打印的字符串有分行的话,空行是绝对不允许的,如果任意地方出现空行,可能的出错信息是:
   makefile:244: *** commands commence before first target.  Stop.    注:244行是文件末行
   也可能是:
   /usr/bin/sh: -c: line 0: unexpected EOF while looking for matching `"'
   你看着这些出错信息,是不是云里雾里?
2、在ld文件中,一个输出段描述如下:
   sec1 :
   {
      sec_base = . ;
      . =  addr;
      * (.text)
    } > region1
    上述代码中,但“sec_base=.”中的“.”代表的是绝对地址,“ .=addr ”中的“.”却是region1内的偏移地址。万幸的是,这个问题能够直接导致代码定位出错,调试的时候可以发现。
3、同样是ld文件中,地址必须升序排列,若有代码:
   sec2 :
   {
      . =  addr1;
      . =  addr2;
      * (.text)
    } > region2
    如果addr2<addr1,出错信息是:
debug.ld: xx1 cannot move location counter backwards (from xx2 to xx3)
其中:
xx1:文件最后一行的行号,不是出错行的行号
xx2:addr1+region2段起始地址。
xx3:addr2+region2段起始地址

生成了错误的代码

    如果说上述问题只是对你的考验的话——这么好的东西,不经九九八十一难,怎能轻易让你用!接下来的问题,就更严重了。
    一直使用的是gnuarm,经过一番煎熬后,终于编译成功了,加载调试吧!却发现根本无法调试,0地址并不是ld文件中指定的向量表,于是把可执行文件objdump出来,一看其中的内容,简直让人哭笑不得,gcc居然在向量表前面,0地址处放了这些东西:
00000000 <____divdf3_from_thumb>:
       0:        4778              bx        pc
       2:        46c0              nop                        (mov r8, r8)
       4:        ea00274a         b        9d34 <__aeabi_ddiv>
00000008 <____asm_reset_switch_from_thumb>:
       8:        4778              bx        pc
       a:        46c0              nop                        (mov r8, r8)
       c:        ea0003ed         b        fc8 <__asm_reset_switch>
这段代码有两个错误:
1、        这段代码是用来从thumb切换到arm状态的interwork代码段,在cm3中,企图切入arm状态,岂不是找死吗?fault伺候。
2、        它把这段代码放在0地址,谁都知道cm3中0地址应该是什么!
虽然这两个是不可饶恕的错误,但我还是企图通过调整编译参数来解决问题,花了大量时间阅读gcc文档,并且经过无数次失败的试验后,我最终还是投降了。
gnuarm不行,那换一个发行版本如何呢?于是安装了sourcery g++ lite,编译后,反汇编一看,OK,0地址正确地出现了向量表:
00000000 <_start>:
       0:        2000c000         .word        0x2000c000
       4:        00000012         .word        0x00000012
       8:        00000010         .word        0x00000010
       c:        00000010         .word        0x00000010
00000010 <rst_fault_handler>:
      10:        e7fe              b.n        10 <rst_fault_handler>
    大喜过望之余,马上加载调试,可一上来就陷入fault,通过跟踪调试,发现sourcery产生的代码,虽然没有在0地址添加interwork代码,但在所有的用C调用汇编函数的地方,用了比interwork稍微“聪明”点的blx:
    13f8:        f7ff ef64         blx        12c4 <__asm_reset_thread>
    看官,指令中目的地址的最低位是0,摆明要切入arm状态,在只支持thumb-2的cm3中,是不折不扣的非法指令,怪不得陷入fault了。
    我仍不死心,于是又安装了yagarto,结果一样令人失望。
    连正确地使用指令集都保证不了,这样的编译器,还有什么留恋的呢?还是从MDK或IAR中选一个吧。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2009-9-4 09:11:11 | 显示全部楼层
希望也出个IAR移植版。

出0入0汤圆

发表于 2009-9-9 15:28:48 | 显示全部楼层
看来众多工程师的选择是对的啊,IAR和mdk就是好用。

我觉得gcc主要是没人去管,不能与时俱进。

IAR不错哦,楼主用IAR吧。我也用IAR

出0入0汤圆

发表于 2009-10-23 15:49:18 | 显示全部楼层
说实话,最开始看到这篇文章很不爽,在没有弄明白事实真相前指责GCC的不对,做为一个开源的C编译器,它哪里惹你了。

先分清一个基本问题:GNU GCC,binutils, newlib
前者是编译器
后者是汇编器,链接器
最后是C库

这三者都是开源的,lz最开始提到的是gcc生成的代码有问题。实质上,把一个.o反汇编出来看,gcc生成的代码绝对是完好的!

如上所述,GNU tool-chains 实际上是分三拨人来完成的,你上面提到的blx的问题,我在做RT-Thread的GCC移植时也遇到过。GCC编译没错,链接过后,就出来了blx。基本可以确认关键在binutils上,即链接的问题上。开始时,我也没办法解决,甚至是打算重新编译一遍binutils(在mingw下编译GNU tool-chains最困难的是GCC,新版本还未编译过,以前的3.x版本是要自行修改下。而binutils的编译是最容易的),看看binutils哪个地方处理不对。

不过仔细搜索了下gcc几个相关的邮件列表,实际上早就有人反映了相关问题,有反映没道理不解决,这不是OpenSource社区解决问题之道。

所以继续折回来查看编译参数,然后发觉了,只需要传给gcc编译的参数与传给ld的参数相同:-mcpu=cortex-m3 -mthumb,那么就不会有blx的问题了(如果这依然有问题,那么就找找自己代码原因吧!)。

然后再说说几个Windows下的GCC版本,我这次移植时采用的是CodeSourcery的版本:
WinARM 版本:没试过,讨厌其100多M的打包体积,而且更新也比较慢。
Yagarto 版本:试过了,在最后链接阶段产生了一堆Thumb call to ARM的问题。这个本来是我最看好的版本,因为其开源的血统最正。
CodeSourcery 版本:这个是专业公司的版本,包含相当多的优化,一些优化甚至还没得到GCC官方版本的采纳。

而采用cygwin的版本,与个人习惯不相符合,无视。。。

Yagarto 版本还需要继续尝试下,或许是因为第一次发布支持Cortex-M3版本的缘故。

出0入0汤圆

 楼主| 发表于 2009-10-23 20:38:02 | 显示全部楼层
楼上高人。
不过我英语太菜,对社区望而生畏,一般只用google搜一下中文资料,缺一条腿啊。

出0入0汤圆

发表于 2010-8-27 12:22:11 | 显示全部楼层
看了3楼的解释,我觉得楼主应该得到很大的收获了。

ADS/RVDS/IAR/MDK这些商业版本的集成开发环境是很不错,自己玩玩也没有问题,人家东西做得也确实好用,譬如毒药会让人上瘾不说,有错误只能等待商业公司打补丁;对于做嵌入式开发的正规公司来讲,一个正规的License至少好几千美金,也算是知识产权的尊重。

西方开源的先驱们也是出于对商业公司贪得无厌的反感,自立更生从无到有的开发了自由软件,保证每个人有获取和修改代码的自由,到今天已经可以说任何商业软件能完成的功能在自由软件里都有替代品,实在没有就会有新的项目启动来开发。

GCC/Binutil/Libc等是自由软件的基石,重要性甚至超过Linux内核,因为内核也是用它们编译产生的。希望楼主千万不要放弃对GCC工具链的支持,开源社区一定会找到答案。至于楼主您提到的英文障碍,我觉得用好翻译工具,用好Wikipedia,能看懂最起码的关键词汇就不会影响大致的判断了,毕竟需要咬文嚼字的不是技术人员的主流风格吗;再者说了就冲着对自由软件前辈们的致敬也应该把英文搞上去;另外毕竟大部分芯片的Datasheet也是英文的;只要楼主拿出开发DJYOS的勇气,积少成多,持之以恒一定会突破整个瓶颈的。

楼主的文档如果需要翻译成英文,可以在国内找一些自愿者来帮助。

出0入0汤圆

发表于 2010-9-3 14:17:09 | 显示全部楼层
高人地盘,错入。

出0入0汤圆

发表于 2010-11-8 18:08:46 | 显示全部楼层
表示一直用gnu gcc 編stm32,沒什麼問題。表示對djyos有壓力。。。

出0入0汤圆

发表于 2010-12-9 17:37:12 | 显示全部楼层
没有钻研精神,心浮气燥是搞不了技术的。
用winarm-2008版的arm-eabi-gcc ,arm-eabi-as ,arm-eabi-ld ,
arm-eabi-objcopy, arm-eabi-objdump ,arm-eabi-size
开发Cortex-M3内核MCU没有发现有任何问题的GNU终实粉丝在此飘过。。。。。

出0入0汤圆

 楼主| 发表于 2010-12-9 18:15:15 | 显示全部楼层
回复【8楼】zhousd 银河一号
-----------------------------------------------------------------------

回复【7楼】dukedz
-----------------------------------------------------------------------

回复【3楼】ffxz
-----------------------------------------------------------------------

不要议论gcc的是非了。
我抛弃gcc,主要是因为gcc太难用,只有像3楼、7楼、8楼这样的高手才能用好,而djyos特征之一,是易学易用,gcc有这个特征吗?
我承认水平有限,驾驭不了gcc,也不愿意花太多时间在驾驭gcc上,但djyos不能要求用户也花同样多的精力在驾驭gcc上吧?
那么多傻瓜式的开发工具,完全符合djyos易学易用的特点,何必吊死在gcc这一棵树上呢?
这些,就是我抛弃gcc的最根本的原因。
如果真的用gcc,估计我以后的用户服务工作,大多数精力将花在gcc有关。

出0入0汤圆

发表于 2011-11-6 21:08:58 | 显示全部楼层
关注

出0入0汤圆

发表于 2011-11-9 09:58:42 | 显示全部楼层
学习了。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 00:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表