7208|11

86

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

S3C6410移植日记之五---告别gcc [复制链接]

    看本文请参考《都江堰操作系统与嵌入式系统设计》第15章,该书可在www.djyos.com下载。
    djyos使用gcc作为编译器,已经5年多了,要抛弃它,实在是一个艰难的抉择,需要下很大的决心。在移植日志中,专门为gcc写一篇,以示纪念。
    当初选择gcc做编译环境,是因为gcc支持的cpu种类繁多,可以简化djyos移植到其他cpu平台的工作,现在证明,这种想法大错特错!这次将djyosARM7移植到stm32的过程中,花了大量的时间折腾gcc后,仍未成功,而从0开始学习MDK到成功编译djyos,花费的时间竟然比花在gcc上的时间少得多。
    所以说,企图通过gcc简化cpu间移植工作是不现实的,新的cpu应该去学习它的专业开发环境,才是王道。也许,在linux环境下编译linux应用程序,gcc是最合适的,但用来编译非linux程序,gcc真的不适合。5年多来,gcc把我折腾得够呛,让gcc再去折腾djyos的用户,让我于心何忍!
    空口无凭,让事实说话,过去的就不说了,也没有留下什么记录,下面谈谈这次把djyos移植到stm32的过程中gcc给我的苦头。
牛头马嘴的出错信息
    我们知道,要使用gcc编译,就必须编写makefileld文件,这两个文件的书写规矩还真多,有些地方要用[tab]键,有些地方要用空格,有些地方又不允许空格,有些地方可以空行,有些地方不允许空行。违反了这些规矩,如果能给出正确的错误信息也行,可惜的是,给出的信息和真正的错误根本牛头不对马嘴!略举几例:
1makefile中可以使用shellprintf命令,如果被打印的字符串有分行的话,空行是绝对不允许的,如果任意地方出现空行,可能的出错信息是:
   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:文件最后一行的行号,不是出错行的行号
xx2addr1+region2段起始地址。
xx3addr2+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地址,谁都知道cm30地址应该是什么!
    虽然这两个是不可饶恕的错误,但我还是企图通过调整编译参数来解决问题,花了大量时间阅读gcc文档,并且经过无数次失败的试验后,我最终还是投降了。
      gnuarm不行,那换一个发行版本如何呢?于是安装了sourcery g++ lite,编译后,反汇编一看,OK0地址正确地出现了向量表:
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-2cm3中,是不折不扣的非法指令,怪不得陷入fault了。
    我仍不死心,于是又安装了yagarto,结果一样令人失望。
    连正确地使用指令集都保证不了,这样的编译器,还有什么留恋的呢?还是从MDKIAR中选一个吧。
此帖出自stm32/stm8论坛

最新回复

                                 LD需要手动修改,makefile可以自动生成,何必要全部手工呢?生成的不合适的话,可以再手动修改。  详情 回复 发表于 2009-9-13 21:00
点赞 关注
 

回复
举报

75

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
Linux与GCC的最大优点也是它最大的缺点,全世界各地都有人为它做贡献,集中了众多开发人员的智慧,这是其优点;正因为开发人员众多,造成软件的书写和使用没有统一个规范,随意性较高,造成理解和维护的巨大困难,这是其缺点。

下决心摆脱GCC是一个好的决定,但工作量肯定也是非常大的。
此帖出自stm32/stm8论坛
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
                                 路过~
此帖出自stm32/stm8论坛
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

4
 
我从开始ARM的时候就是一直用的GCC
没换过别的

但开始玩CM3的单片机后就没再用过GCC了..
GCC虽好,但也要合理选择呀
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

5
 
对普通电工来说,便宜没好货,免费更是没好货

对真正的高手来说,便宜免费都有好货……只是这种人太少了,我们大部分都是普通电工
此帖出自stm32/stm8论坛
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

6
 
RIDE还是很好用
至少在我的3.23破解版出了问题的情况下
很容易就换到了RIDE中
此帖出自stm32/stm8论坛
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

7
 


让菜鸟也能用会用用好OS,是djyos的目标之一,这包括OS本身和编译调试工具都要易学易用才行,从我自己多年使用gcc的经验看,gcc担当不起“易学易用”这个角色。为了降低用户学习使用的难度,我做了很多努力,写了许多关于建立和使用gcc编译环境的文档,但现在看来,还是必须抛弃之。
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

8
 
ST的每个范例都有针对RIDE的版本
我自己也只是按照范例设置了几个选项,GCC就可以很好的编译了
当然,这种方法不算正统
Makefile+LD如果完全用手工写,确实不容易
但是,易学易用也要考虑价格,你的OS+App还能用免费版的Keil或IAR?
对于CM3,16KB很容易就超出了
此帖出自stm32/stm8论坛
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

9
 
Makefile和LD文件也可以通过模板文件修改一下就能使用
并非必须每次都要重新写
此帖出自stm32/stm8论坛
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

10
 


楼上,你试过在gcc for cm3中用C语言调用汇编函数吗?不管我怎么折腾,gcc都生成“blx 偶数地址”这样的非法指令,一执行就陷入fault。

makefile和ld文件确实是改一下就能用,但我在改的过程中无意间多敲了一个空行,结果出来牛头不对马嘴的提示,搞了我大半天,你能预见djyos的用户会有多少这样的“无意间”吗?
此帖出自stm32/stm8论坛
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

11
 
gcc本身挺不错的,问题是没有好的集成开发环境;
C调汇编我没试过,我一般直接在C子程序里嵌汇编;
试试codeblocks+gcc吧
我用这个组合做qt程序 还是很不错的
gcc+keil做过arm7的项目,没有在cortex上用过
现在改iar了
研究gcc主要是担心将来公司会遇到版权问题
此帖出自stm32/stm8论坛
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

12
 
                                 LD需要手动修改,makefile可以自动生成,何必要全部手工呢?生成的不合适的话,可以再手动修改。
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表