分类: LINUX
2009-04-26 22:44:40
终于调通了printf,不过只是初步,有种泪目的感觉,整个周末周日耗进去了,orz
之前一直在移植2440test的代码,从ADS编译环境移植到GCC编译环境,虽然核心代码是不用怎么写,但是移植的工作还不小,ADS和GCC的语法相差还是有点大,特别是第一阶段的汇编代码,差不多要整个重写格式,然后做需要的修改,总之修改的真不少。第二阶段相对就好点,因为是C代码为主,基本不需要怎么修改就OK,不过话虽然那么说,第二阶段的串口PRINTF函数倒是搞了我一整天了,就是这个东西,引发了不少东西。
原来用yagarto的版本,是arm-elf,配套的是 newlib ,开始也没啥注意和 arm-linux的区别,反正在window上面干活而已,我不是那些极端主义者,啥一定要扔掉window用linux之类……或者你可以说我的觉悟不够高吧。我用window而已,但是并没有用ADS ,KEIL MDK IAR等IDE,当然了,抵制盗版也是原因之一,哈哈~~~观望一下 win7 的性能如何,好的话考虑入个正版,免得有些人JJYY的。呃,貌似扯远了 ……
开始打算 include
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函数,工作的很好。
对比一下,用newlib的printf函数的话,代码在 32K,用iprintf代替的话,代码是 20k,用自己的vsprintf 的话,代码是 3K,汗,这相差太大了!!况且我的主要目的只是串口输出,调试而已,没有必要用那么完成的printf函数!!!所以还是用自己实现的比较好啊。
剩下的问题还是那个printf怎么输出浮点数的问题了,有点思路,但是还是得继续google看资料,希望能解决,不过这个暂时对我来说并不重要,毕竟系统计算浮点数已经OK了,printf函数也用自己的代替了,printf输出浮点的问题就显得不怎么重要了,考虑一下自己写一个,哈哈,参考 linux 的vsprintf ,看是否看的懂,哈哈~~
注重基础,永远是没有错的。在今次移植过程中遇到的问题,基本都有了一个明确的思路,知道怎么找资料解决,知道到什么地方找资料,知道大概问题是由啥问题造成的,所以感觉过去的一年的学习并没有白费,基础的重要性体现出来了。
Etual
2009-4-26
chinaunix网友2009-05-06 18:15:49
ORZ,膜拜一下 --------------------------------------------------------------------- 拍鞋网阿迪达斯品牌专卖店,专业销售adidas三叶草、阿迪达斯鞋、阿迪达斯三叶草、阿迪达斯板鞋、阿迪达斯篮球鞋! 阿迪达斯专卖店地址: http://www.paixie.net/adidas/