本帖最后由 kylongmu 于 2017-7-28 12:56 编辑 使用平台NUCLEO 767ZI以下代码 现象描述,当调用100次以后,第二个printf会被执行到。把字符数组大小改为200后,调用200次后,第二个printf有打印输出。测试几组数组大小,均出现严格的错误现象。 目前怀疑sprintf函数影响,或者是for循环体导致循环变量i在离开for结构后被不正确的置零了。 ------------------------------------------------ 工程生成: CUBEMX 4.22 ------------------------------------------------问题已解决:FreeRTOS默认线程里的Stack size是128字节,我的程序是放到线程里的,估计是变量申请越界了,调整此处Stack size 到256字节问题解决。 前面一个CDC主机找不到设备的问题,感谢act8238建议加大Heap size解决。 也感谢moyanming2013对我程序中问题的挑剔,toofree的热心帮忙。 总结一下:CubeMX以及FreeRTOS为了突出性能,空间占用小,默认设置的Heap与Stack尺寸很小,必须小心,尤其是当使用USB,sprintf这类会动态申请空间的库时。而出错的现象却很难定位。 |
楼主,老改主楼帖子,这样不好。
帖子错了,可以往上加,备注一下什么时间修改过什么东西。
你这样老改,让其它人看到回复的楼层,不知道怎么回事。换种说法,你这样是对回复你帖子和看你帖子人的不尊重。
改正语法错误,现象依旧,换代码测试定位问题,
目前测试sprintf的内容没有问题,看来是for循环里的变量i有问题,另外一组代码来做测试:
char Dbg_QMsg[100];
uint8_t P_msg1[]="Err\n\r";
sprintf(Dbg_QMsg,"Hello %d\n\r\0",i);
for(i=0;i<100;i++)
{
if(Dbg_QMsg【i】=='\0')//不用中文括号,这里无法显示
{
if(i==0)
HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//不会执行
break;
}
}
if(i==0)
HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//会执行到
在for循环体内i不会等于0,但是循环体外在循环字符分配大小次数后,i就会变为0,而且是在循环数大于等于字符数组分配空间的情况下才会出现。
多谢各位大神的意见。
我用的是CubeMX生成的keil工程,目前可以确认的是编译优化等级从o1到o3,都出现相同的状况,就是for循环体外变量被置零,而且是根据设置的缓冲区大小决定循环次数。
keil里面用的是5.06版本的编译器,还有个6.4编译器,可是一换6.4就一堆错误出来,无法编译,看来目前的CubeMX还没有更新支持keil的新编译器,关于这点各位有什么建议。
uint8_t P_msg1[]="Err\n\r";
sprintf(Dbg_QMsg,"Hello %d\n\r\0",i);
for(i=0;i<100;i++)
{
if(Dbg_QMsg【i】=='\0')//不用中文括号,这里无法显示
{
if(i==0)
HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//不会执行此处
break;
}
}
if(i==0)
HAL_UART_Transmit(&huart3, P_msg1,sizeof(P_msg1), 0xFFFF);//会执行此处
也就是说变量i一旦出了for循环体就被置零了,而且这种现象是循环次数达到Dbg_QMsg[100]分配的大小数来决定的,如果循环99次以内,出了for,i并不会变0;一旦大于等于100,出了for后i就会被置零;奇怪的是把空间分配为200的数组,那么问题点就变成199了。
不是那个编译优化,是iar 里 project-options-general options - library options,针对 printf scanf 库的优化!
如果仍不行可以在win32里编译运行测试下,找找问题!