AlienHit 发表于 2011-11-9 16:28:56

苦逼的人你伤不起啊伤不起,为啥用printf输出浮点数就死机~~

用的alientek的程序,重新定义printf,如下格式:

#pragma import(__use_no_semihosting)            
//标准库需要的支持函数               
struct __FILE
{
        int handle;
        /* Whatever you require here. If the only file you are using is */
        /* standard output using printf() for debugging, no file handling */
        /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
int fputc(int ch, FILE *f)
{
USART1->DR = (u8) ch;      
while((USART1->SR&0X40)==0);//循环查询,直到发送完毕   
}



系统增加了1个串口接收中断、1个定时器中断,
于是莫名其妙的事发生了,每次调用printf时,输出整数,不管多么长的表达式都不会死机,但是用%f输出浮点数时,即使很短的表达式,偶尔会莫名其妙的死机掉!!出现概率还不一定~~

例如下面这么长的整数输出都 不会死机
printf("gy;%i;%i;%i; aa;%i;%i;%i; agl;%i;%i;gy;%i;%i;%i; M;%i;%i;\r",aaa,bbb,ccc,ddd,eee)...

但是下面这句话将死在冒号位置....
printf("Get ntlvalue:%f,\r",ntlvalue);


在MemManageException中断中,关掉while(1)循环,依然死机,但是在MemManageException增加一个发送语句,又不死机了。。。
void MemManageException(void)
{
/* Go to infinite loop when Memory Manage exception occurs */
        USART1->DR = 'a';        USART3->DR ='a';
}


但是上位机观察 死机位置并没有多个'a'字符
传说中的苦逼毛病啊,不知有没有大虾遇到过啊?。。。~~

luzhengmao 发表于 2011-11-9 16:43:21

printf 在很多单片机的编译器就是不支持浮点数的。

rockli 发表于 2011-11-9 16:43:33

有没有勾选 microlib?

AlienHit 发表于 2011-11-9 16:47:02

回复【1楼】luzhengmao
-----------------------------------------------------------------------

我是STM32 C8t6
问题是之前一直可以用的,这两天才出问题的

AlienHit 发表于 2011-11-9 16:51:36

找了2天了,找不到问题在哪里

1.试了0.1ms输出浮点信息,有时候不死机,但是浮点数的小数点变成空格

2.在void HardFaultException(void)、void MemManageException(void)、void BusFaultException(void)、void UsageFaultException(void)这几个函数中,把while(1)死循环全部删除,仍然死机

但是!不改变任何其他地方,在上面几个函数中增加USART1->DR = 'a'; USART3->DR ='a';居然又不死机了!!但是上位机又看不到‘a’的输出信息


知道我有多么的苦逼了吧~~~完全没头绪啊~~

guo69 发表于 2011-11-9 16:58:17

应该是链接的库不对吧,
http://cache.amobbs.com/bbs_upload782111/files_47/ourdev_693527P1RQ7I.JPG
(原文件名:2.JPG)

s-t-m-3-2 发表于 2011-11-10 13:13:14

苦命的孩子啊

AlienHit 发表于 2011-11-10 17:01:29

回复【5楼】guo69
应该是链接的库不对吧,


(原文件名:2.jpg)
引用图片

-----------------------------------------------------------------------

不是这个原因,之前一直是正常使用的,现在换了个串口输出的办法,不用printf了,没太多问题了

hadio 发表于 2011-11-10 23:04:51

可怜的娃呀~我来救你吧,你的发送函数有问题,应该先判断发送完毕,再发送下一个

AlienHit 发表于 2013-9-14 23:47:46

最后原因找到了,因为模拟flash rom覆盖掉了某内存段(应该是存放字符常量的段),

导致printf不能使用(想不到啊原来是这个原因{:dizzy:})看此贴

http://www.amobbs.com/thread-5219250-1-1.html

qllaoda1 发表于 2013-9-15 00:20:23

恭喜楼主的问题在两年以后终于得到了解决{:lol:}

wzd5230 发表于 2013-9-15 06:43:02

貌似这个时间跨度有点大啊!

笑笑我笑了 发表于 2013-9-15 07:06:32

我也是,不管是sprintf还是printf,一输出浮点数就死机。

qllaoda1 发表于 2013-9-15 07:30:03

笑笑我笑了 发表于 2013-9-15 07:06 static/image/common/back.gif
我也是,不管是sprintf还是printf,一输出浮点数就死机。

把heap设置大点试试

1633994509 发表于 2013-9-15 07:42:13

应该是编译器没设置好连接库函数的路径。。。。。

东海傲虾 发表于 2013-9-15 18:22:24

没遇到过,

bruce_helen 发表于 2013-9-15 19:54:44

遇到过,最后都没解决。楼主的上面说的应该不是问题所在。
我之前将网上说的方法都试过了,将栈改大,将堆改大,改变优化等级。。。最后发现情况会好点,但是长时间测试还是会出现问题。现在不管怎么样都不输出浮点数
{:huffy:}{:huffy:}{:huffy:}

ljbskx 发表于 2013-9-15 20:03:30

时间跨度真大

chencc8 发表于 2013-9-15 20:04:54

哈哈,LZ还能记得当初发过帖子啊~

tomzbj 发表于 2013-9-15 21:23:58

bruce_helen 发表于 2013-9-15 19:54 static/image/common/back.gif
遇到过,最后都没解决。楼主的上面说的应该不是问题所在。
我之前将网上说的方法都试过了,将栈改大,将堆 ...

用第三方的printf代替,不用标准库的printf,试试?

chencc8 发表于 2013-9-16 20:59:50

bruce_helen 发表于 2013-9-15 19:54 static/image/common/back.gif
遇到过,最后都没解决。楼主的上面说的应该不是问题所在。
我之前将网上说的方法都试过了,将栈改大,将堆 ...

是不是因为可重入的问题~~你在几个函数或者ISR中调用了printf?

fengyunyu 发表于 2013-9-16 21:04:37

关注一下,以前一用就死,后来就不用了。

lologame 发表于 2013-9-16 21:37:55

以前我也用到过,更改链接库路径后就ok了

bruce_helen 发表于 2013-9-17 12:28:07

chencc8 发表于 2013-9-16 20:59 static/image/common/back.gif
是不是因为可重入的问题~~你在几个函数或者ISR中调用了printf?

不是,只在一个函数中循环调用

street 发表于 2021-8-12 21:12:17

本帖最后由 street 于 2021-8-12 21:16 编辑

我一年前也遇到了.一般printf 只是调试用. 就绕过去了 一直没解决.   这几天调试 不用printf非常别扭.就研究了一下.   
我的现象 就是输出小数没有小数点能正常输出.或者是输出小数的时候没有小数点. 比如printf("test %f \r\n",3.1415)数据结果test 3141500.
重建了工程 还是一样. 最后 注释掉主循环 所有内容, 只加了一个延时和 printf 函数. 显示正常. 然后 就是一段一段测试程序 看看哪里影响了.

最后 发现 是在 main 函数中 定义了一个 比较长的数组 u16 changestate;   将其 变成全局变量 就正常了.

楼主还能不能 记起这个故障了?{:biggrin:}

PS: 忘了说 ,只定义了数组是不影响 printf 的,只要在主循环中访问这个数组 就会影响printf .

n0831 发表于 2021-8-12 21:51:39

楼上这个看起来是栈不够。

dog 发表于 2021-8-13 09:48:29

我悄悄地告诉大家,snprintf(浮点,需要3百多个Bytes的Stack

liang16888 发表于 2021-8-13 12:17:49

大大 我也有碰到这个问题是真的是Stack 被盖到问题吗?

unifax001 发表于 2021-8-15 21:50:44

我的问题是 读取 MAX44009的时候
不使用printf("%f",a);的时候 很正常 一旦使用就一直打印上电时的状态 不更新了

hpdell 发表于 2021-8-23 15:11:23

unifax001 发表于 2021-8-15 21:50
我的问题是 读取 MAX44009的时候
不使用printf("%f",a);的时候 很正常 一旦使用就一直打印上电时的状态 不 ...

有没有使用 什么系统 ??? 及 使用系统后,有没有启动相关的 fpu的设置及相关的宏配置等 ??




unifax001 发表于 2021-8-23 16:13:39

hpdell 发表于 2021-8-23 15:11
有没有使用 什么系统 ??? 及 使用系统后,有没有启动相关的 fpu的设置及相关的宏配置等 ??




freertos
没设置你说的那些东西

solojimes 发表于 2021-8-24 12:30:27

unifax001 发表于 2021-8-15 21:50
我的问题是 读取 MAX44009的时候
不使用printf("%f",a);的时候 很正常 一旦使用就一直打印上电时的状态 不 ...

试试这个函数dtostrf

unifax001 发表于 2021-8-24 13:52:10

solojimes 发表于 2021-8-24 12:30
试试这个函数dtostrf

谢谢指导 抽空我跑下之前的代码试试 谢谢

turelon 发表于 2022-3-10 20:12:24

我遇到过整数打印格式化为浮点数就会死机,希望没人踩这个坑。比如 int val = 10; printf("%f", val);

redroof 发表于 2022-3-10 20:25:35

turelon 发表于 2022-3-10 20:12
我遇到过整数打印格式化为浮点数就会死机,希望没人踩这个坑。比如 int val = 10; printf("%f", val); ...
(引用自34楼)

不死也会乱。
你应该在参数里明确的强转为float,或者转为double也一样,否则结果是未定义的。
%f参数要求从堆栈里取一个double数据,结果里面是个int,连长度都不对了。

turelon 发表于 2022-3-11 23:21:10

redroof 发表于 2022-3-10 20:25
不死也会乱。
你应该在参数里明确的强转为float,或者转为double也一样,否则结果是未定义的。
%f参数要 ...
(引用自35楼)

是的,帮同事背锅了,他把打印类型搞错了,关键还是一条错误打印代码,没有错误的时候不执行,现场出问题了还排查了好一会。不过打印浮点数确实有坑,好像有个8字节对齐,用ucos堆栈不对齐的话好像会有问题…

redroof 发表于 2022-3-12 08:26:47

turelon 发表于 2022-3-11 23:21
是的,帮同事背锅了,他把打印类型搞错了,关键还是一条错误打印代码,没有错误的时候不执行,现场出问题 ...
(引用自36楼)

高级一点的编译器会检查print里面的格式符和实际参数类型是否一致的,不一致会报警告。或许是你的单片机编译器太老了不会检查这一点。
可变参数不一致是很严重的错误

yiyinzhudan 发表于 2022-3-12 10:17:31

学习学习

RFman 发表于 2023-4-14 14:17:46

我遇到的情况是把栈改大一些就可以了

qwe2231695 发表于 2023-4-14 22:44:31

我遇到的情况是把栈改大一些就可以了
+1 , 打印浮点数,库需要申请一段大内存。
页: [1]
查看完整版本: 苦逼的人你伤不起啊伤不起,为啥用printf输出浮点数就死机~~