[ZLG-ARM] 由vsprintf引起的M3内存分配问题思考

[复制链接]
 楼主| 疯子8972 发表于 2009-1-14 14:46 | 显示全部楼层 |阅读模式
最近才上手M3,出了不少奇怪的问题:)<br />也发过帖子问为什么不能使用vsprintf<br />周立功给的答案是不要用vsprintf,改用sprintf<br />但是在使用sprintf时还是有奇怪问题<br />代码如下<br />void&nbsp;OnTimer1&nbsp;(void)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;int&nbsp;OldTemperature;<br />&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;NowTemperature;<br />&nbsp;&nbsp;&nbsp;&nbsp;float&nbsp;a;<br />&nbsp;&nbsp;&nbsp;&nbsp;NowTemperature&nbsp;=&nbsp;ReadTemperature();<br />&nbsp;&nbsp;&nbsp;&nbsp;if(OldTemperature&nbsp;!=&nbsp;NowTemperature)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OldTemperature&nbsp;=&nbsp;NowTemperature;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;(float)NowTemperature&nbsp;/&nbsp;8;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(UARTString,&nbsp;&quot;现在的温度是%.3f摄氏度
&quot;,&nbsp;a);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UARTPrintf(UART0_BASE,&nbsp;UARTString);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;SetTimer(1,&nbsp;1000);<br />}<br />SetTimer(1,&nbsp;1000)的意思是1秒后让系统回调OnTimer1(),(呵呵自己写的小系统)。这样就相当于每1秒钟调用一次&nbsp;OnTimer1(),一直循环下去,<br />照理说只有温度发生变化的时候才从串口打印出数据,但是实际情况是即使温度不变,每秒都有数据从串口打印出来。<br />改动代码为<br />if(OldTemperature&nbsp;!=&nbsp;NowTemperature)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;=&nbsp;(float)NowTemperature&nbsp;/&nbsp;8;<br />&nbsp;&nbsp;&nbsp;&nbsp;sprintf(UARTString,&nbsp;&quot;现在的温度是%.3f摄氏度
&quot;,&nbsp;a);<br />&nbsp;&nbsp;&nbsp;&nbsp;UARTPrintf(UART0_BASE,&nbsp;UARTString);<br />&nbsp;&nbsp;&nbsp;&nbsp;OldTemperature&nbsp;=&nbsp;NowTemperature;<br />}<br />问题解决。<br />说明代码:<br />a&nbsp;=&nbsp;(float)NowTemperature&nbsp;/&nbsp;8;<br />sprintf(UARTString,&nbsp;&quot;现在的温度是%.3f摄氏度
&quot;,&nbsp;a);<br />UARTPrintf(UART0_BASE,&nbsp;UARTString);<br />改变了OldTemperature的值。<br />于是猜想局部变量冲出堆栈了。<br />将STACK_SIZE改为1024,代码回复原来,问题解均。<br />试着使用vsprintf,也没有问题。<br />在我上个询问vsprintf的帖子中,有个大大在ucOS下使用vsprintf就没有问题,应该是那个模板STACK_SIZE为64,和重入没有关系。<br />猜想M3中堆和栈的生长方向相同,和以前使用的AVR不一样。<br />AVR即使设置错了,局部变量也不一定会冲到全局里面。<br />分析完毕,大大们看看对不对啊。<br /><br /><br />
computer00 发表于 2009-1-14 14:55 | 显示全部楼层

在编译器中,只有栈,没有堆。堆是操作系统的概念

这里的临时变量都是分配在栈上面的。
 楼主| 疯子8972 发表于 2009-1-14 19:01 | 显示全部楼层

呵呵

概念错误<br />应该把堆改称为静态区<br />应该不影响我对于意思的表达:)
Swd21ic 发表于 2009-1-15 22:06 | 显示全部楼层

re

在编译器中,只有栈,没有堆。堆是操作系统的概念<br /><br />00你没用过IAR么?&nbsp;heap&nbsp;=&nbsp;堆&nbsp;
by674868212 发表于 2011-1-12 17:12 | 显示全部楼层
今天遇到这个问题~~~改了堆栈大小,问题解决了~~~~

难道 vprintf 会申请很多堆栈空间?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

576

帖子

37

粉丝
快速回复 在线客服 返回列表 返回顶部

32

主题

576

帖子

37

粉丝
快速回复 在线客服 返回列表 返回顶部