Chinaunix首页 | 论坛 | 博客
  • 博客访问: 603665
  • 博文数量: 99
  • 博客积分: 5128
  • 博客等级: 大校
  • 技术积分: 1538
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-27 19:40
文章分类

全部博文(99)

文章存档

2012年(3)

2011年(5)

2010年(4)

2009年(31)

2008年(56)

分类: LINUX

2009-04-26 22:44:40

终于调通了printf,不过只是初步,有种泪目的感觉,整个周末周日耗进去了,orz

之前一直在移植2440test的代码,从ADS编译环境移植到GCC编译环境,虽然核心代码是不用怎么写,但是移植的工作还不小,ADSGCC的语法相差还是有点大,特别是第一阶段的汇编代码,差不多要整个重写格式,然后做需要的修改,总之修改的真不少。第二阶段相对就好点,因为是C代码为主,基本不需要怎么修改就OK,不过话虽然那么说,第二阶段的串口PRINTF函数倒是搞了我一整天了,就是这个东西,引发了不少东西。

 

原来用yagarto的版本,是arm-elf,配套的是 newlib ,开始也没啥注意和 arm-linux的区别,反正在window上面干活而已,我不是那些极端主义者,啥一定要扔掉windowlinux之类……或者你可以说我的觉悟不够高吧。我用window而已,但是并没有用ADS ,KEIL MDK IARIDE,当然了,抵制盗版也是原因之一,哈哈~~~观望一下 win7 的性能如何,好的话考虑入个正版,免得有些人JJYY的。呃,貌似扯远了 ……

 

开始打算 include 然后调用系统自带的 vsprintf 函数来处理可变参数传递问题,没想到出了大堆的问题里面找不到库,看函数的名字,貌似是一些浮点处理用的函数,那就怪了,明明已经加载了 –lm 数学函数库了啊,为啥还有问题?当时完全猜不到问题,严重郁闷中,后来百度google了一天,那是星期六。终于知道了,原来ARM是没有硬件的浮点协处理器,所以GCC生成硬件浮点指令的话就会出错。于是查了GCCmanual,知道了有个选项可以设置生成软浮点指令 –msoft-float 代替默认的 –mhard-float,但是后来看了一下下面的注视,傻眼了,要那样做的话整个牵连的库需要重新编译,libgcc.a …… 这样的话我用现成的编译链的意义就没有,看了一下yagartoGCC默认选项(这个是编译生成GCC编译链的时候的选项,貌似是后期无法改变的),又傻眼了

Using built-in specs.

Target: arm-elf

Configured with: ../gcc-4.2.2/configure --target=arm-elf --prefix=/home/yagarto/install --disable-nls --disable-shared --disable-threads --with-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --enable-languages=c,c++ --enable-interwork --enable-multilib --with-newlib --with-headers=../newlib-1.16.0/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v

Thread model: single

gcc version 4.2.2

 

没有启用软件浮点,还是用默认的硬件浮点,难道是这个问题??不知道,继续google,看了很多英文网页,一边后悔之前没有学好英文……虽然看的懂,但是不是十分确定,而且开着词典看,慢,哎,在学校真的要学好英文啊。

最有悠悠逛逛又到了 gnuarm.org 发现这里有 arm-elf 的编译好的版本,看了一下说明,貌似默认已经开了 soft-float 了,大喜,干脆换个编译器?下载回来安装,看了一下默认选项:

Using built-in specs.

Target: arm-elf

Configured with: ../gcc-4.2.2/configure --target=arm-elf --prefix=/c/gnuarm-4.2.2 --enable-interwork --enable-multilib --with-float=soft --disable-newlib-supplied-syscalls --with-newlib --with-headers=../newlib-1.15.0/newlib/libc/include --enable-languages=c,c++

Thread model: single

gcc version 4.2.2

 

发现很好,确实是开了--with-float=soft ,本来可以自己重新编译这个编译链的,不过着实不知道怎么在windows上面应用,在linux下编译运行的。干脆就用这个编译链了。修改了一下,重新编译项目文件。

 

话说,makefile是需要好好注意的,开始也是被这个东西搞死了。于是参考了 WinARM的例子程序at91sam7s64_Hello,这个例子刚好就是说明怎么重定位printf函数的!WinARM也是用newlib的,可以说是一样。于是从这个例子里面学习。大概看了2个小时,搞清楚了一些关系。

知道了其实需要做的工作是很少的,我们只需要提供一个 syscalls.c 函数,重新实现以下几个底层的系统调用函数代替 newlib 里面的函数就OK了,at91sam7s64_Hello 里面的基本可以用了,只是修改一下

Read write 里面的系统调用调用自己的 UART函数,extern char end[]; 这里需要注意,这里用的是 连接脚本的符号,所以在连接脚本里面加上就OK了,其他不用改。另外,newlib 有个 iprintf 版本的函数,是专门处理整数类型的,我这个调试成功,但是完整实现版本的 printf 还没有搞定,浮点printf也没有搞定,不知道啥问题,哎…..

 

最后就是调试自己的 vsprintf 函数了,这个之前写了一整天的了,在ADS上面调试成功,但是在用GCC也是死活搞不懂,今天通过查资料,了解了不少各种的问题,于是决定再挑战一下,在确定其他完全没有问题的情况下,屏蔽掉系统的 iprintf函数,将 uart_printf 函数指向自己的那个 vsprintf ,让人惊喜的是,竟然一次通过,当时有种泪目的感觉,看到UART打印出的一些信息:

printf test ok!

mini_vsprintf test ok!

rUBRDIV0:26

rUBRDIV0:0x1A

之前的想法是用来打印 字符串,十进制数,十六进制数,这样用来调试是非常方便的,从串口的输出看出,这都非常正确的实现了!!之前的努力没有白费啊,用了1天时间写的VSPRINTF函数,工作的很好。

对比一下,用newlibprintf函数的话,代码在 32K,用iprintf代替的话,代码是 20k,用自己的vsprintf 的话,代码是 3K,汗,这相差太大了!!况且我的主要目的只是串口输出,调试而已,没有必要用那么完成的printf函数!!!所以还是用自己实现的比较好啊。

 

剩下的问题还是那个printf怎么输出浮点数的问题了,有点思路,但是还是得继续google看资料,希望能解决,不过这个暂时对我来说并不重要,毕竟系统计算浮点数已经OK了,printf函数也用自己的代替了,printf输出浮点的问题就显得不怎么重要了,考虑一下自己写一个,哈哈,参考 linux vsprintf ,看是否看的懂,哈哈~~

 

注重基础,永远是没有错的。在今次移植过程中遇到的问题,基本都有了一个明确的思路,知道怎么找资料解决,知道到什么地方找资料,知道大概问题是由啥问题造成的,所以感觉过去的一年的学习并没有白费,基础的重要性体现出来了。

Etual

2009-4-26

阅读(3270) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-05-06 18:15:49

ORZ,膜拜一下 --------------------------------------------------------------------- 拍鞋网阿迪达斯品牌专卖店,专业销售adidas三叶草、阿迪达斯鞋、阿迪达斯三叶草、阿迪达斯板鞋、阿迪达斯篮球鞋! 阿迪达斯专卖店地址: http://www.paixie.net/adidas/

chinaunix网友2009-05-04 09:35:18

牛逼。。我看得头都大了。。

chinaunix网友2009-05-01 08:33:41

高深,佩服