免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11663 | 回复: 7
打印 上一主题 下一主题

请教u-boot中的printf()打印64位整型变量 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-23 14:02 |只看该作者 |倒序浏览
本帖最后由 OLAY玉兰油 于 2010-04-23 14:15 编辑

最近蛋疼,移植了一个u-boot,发现printf()函数的一些问题
  比如我要打印一个unsigned long long变量,也就是64位的变量,如果值是0x40000,按照0x%llx打印,实际打印出来的是0x4 0000 0000 0000,按照0x%x打印得到0x0

我的结论是:
  数据在内存中存储方式导致printf输出错误

依据:
  1.本来应该是0x40000的,实际在后面加了四个字节的0;
  2.按照32为打印得到0,只是把低4字节省略,说明数据类型转换正确

请教:
1.printf()函数是编译器提供的还是u-boot自带的,或者它是编译器提供的,最后重定向到开发板的串口?
2.如何才能通过printf正确打印64位整型变量
    PS:请不要告诉我把数据左移,右移之类的,再按照32位数据打印(咱们都不是小孩子了,chinalinux论坛丢不起这个人)。我想找到原因,和彻底的解决办法

论坛徽章:
0
2 [报告]
发表于 2010-04-23 15:20 |只看该作者
uboot的代码,之前用过printf去打印64位的,记得是可以用的。
等过段时间拿到>4GB的flash,再具体验证一下。

uboot中的printf,去看代码,实现应该是在common/console.c中,重定向到串口中的。

目前个人以为,90%的可能,还是代码是正常的。只是使用上,不知哪里出错了。

论坛徽章:
0
3 [报告]
发表于 2010-04-24 13:01 |只看该作者
多谢楼上
我的版本是u-boot-2010.03的,应该是最新的了
这个问题出现在nand_erase_opts()函数中(实现nand flash的擦除)
printf("\rErasing at 0x%llx -- %3d%% complete.",erase.addr, percent);这句话输出了擦除的块首地址和已擦除百分比,代码执行过程中,擦除正常,打印错误
补充一下1.3.1中erase.addr是32位的,现在新版本的是64位的,在sourceinsght里看到printf()函数和u-boot-1.3.1的代码不一样
功底有限,还不能很好理解这个函数,继续求教

论坛徽章:
0
4 [报告]
发表于 2010-04-25 23:55 |只看该作者
那应该是这部分了:
printf("\rErasing at 0x%x -- %3d%% complete.", erase.addr, percent);
那首先你自己确认一下,erase.addr是不是的确是定义为u_int64_t的了。
如果定义都对,那应该没啥问题的。

注:巧的是,偶对nand flash这部分相对还是比较熟悉的,呵呵。

论坛徽章:
0
5 [报告]
发表于 2010-04-26 16:53 |只看该作者
前辈啊,新版本中erase.addr中定义成了unsigned long long,确实是64位的,我使用的是u-boot-2010.3这个版本,发现打印结果出错,而看到网上有位达人移植u-boot-2009.08版本,顺便也贴了个图出来,发现此处打印也是出错。因为擦除操作能够正确执行,所以我认为是printf执行出错
  此外,我还发现
    1.如果执行printf("\rErasing at 0x%llx -- %3d%% complete.",erase.addr, percent);,erase.addr和percent都是错的;而分别打印erase.addr和percent,结果是erase.addr打印错误,percent打印正确
    2.在阅读printf代码时发现一句va_arg(args,unsigned long long)代码,由于va_arg()是gcc编译器提供的,怀疑我使用的gcc版本va_arg()进行64位操作时会出错(我的arm-linux-gcc版本是4.3.2)

  请教va_arg()系列的函数在什么地方定义

论坛徽章:
0
6 [报告]
发表于 2010-05-04 22:46 |只看该作者
va_arg是gcc的stdarg.h里面定义的

论坛徽章:
0
7 [报告]
发表于 2010-05-07 12:45 |只看该作者
本帖最后由 crifan 于 2010-05-07 12:48 编辑

1。看了下代码,你说的那个
va_arg(args,unsigned long long)
是不是这个:
在lib_generic/vsprintf.c中的:
int vsprintf(char *buf, const char *fmt, va_list args)
{
..
#ifdef CONFIG_SYS_64BIT_VSPRINTF
                if (qualifier == 'q')  /* "quad" for 64 bit variables */
                        num = va_arg(args, unsigned long long);
                else
#endif
...
}
是的话,那你应已经加了对应的宏,去启动64位的支持了吧?

我的是在头文件中加了:
#define CONFIG_SYS_64BIT_VSPRINTF        1
#define CONFIG_SYS_64BIT_STRTOUL        1
其中CONFIG_SYS_64BIT_STRTOUL对应着cmd_nand.c中,很多输入的字符串变量,转换成64位的数值要用到lib_generic/vsprintf.c中的simple_strtoull

2。关于编译器的版本,我的是用
buildroot v2009.08
编译的gcc 4.2.4版本的arm-linux-gcc
配置里面,加了大文件支持:
    [ * ]  Enable large file (files > 2 GB) support?
不知道这个参数是否对编译出来的,是否支持64位的打印的那些函数有影响。
如果有,那你的编译时候,也要加上。

3。另外,我用的OABI,如果你用的是EABI,不知道是否有可能是EABI的兼容性不够好?(个人感觉,这个可能性极小。。。)

论坛徽章:
0
8 [报告]
发表于 2010-10-12 14:26 |只看该作者
不知楼上的两位大侠问题解决了吗?小弟也遇到了同样的问题。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP