tommyMel 发表于 2012-10-9 13:56:37

编译器不开警告的惨痛教训。

最近在做一个项目,用AVR, 跑Freertos。由于堆栈原因,无法使用自带的printf.
于是在自己的串口驱动上面,实现了简单的类似printf的可变参数函数:
uart_fmt_P(uint8_t port, const char *fmt, ...)
{
    va_list va;
   
   va_start(va, fmt);
   ...
   va_end(va);
}

在serialconsole.c中调用这个函数,结果串口老打不出东西。调试发现:
1. 调用函数uart_fmt_P的时候,参数都是通过寄存器传递的。
2. 在uart_fmt_P中va_start是从堆栈中取参数的。

检查了编译器参数,尝试了不同版本的编译器,google了n久无果。
最后阅读AVR-GCC的文档上说,可变参数函数,编译器会自动选择用堆栈传递参数。
可俺的代码怎么不行呢,尝试用不同的优化选项,调试选项都不行。

最终灵光一现,终于找到原因:
在调用uart_fmt_P的源文件中忘记包含uart_fmt_P所在的头文件了,所以uart_fmt_P的函数没有声明,编译器发了警报,函数未声明,然后按照普通函数编译了,结果参数都在寄存器中,没有入栈,

以前都挺注意的,一时疏忽,白白浪费了自己一天的时间。所以,一定不要放过编译器的警告,最好把-Werror打开,把警告变成错误提示,终止编译,这样可以强迫自己修正警告。

yklstudent 发表于 2012-10-9 19:38:16

楼主高手啊 FREERTOS这个怎么移植到AVR上的啊

cumtgao 发表于 2012-10-9 19:50:58

学习了,~~~~
页: [1]
查看完整版本: 编译器不开警告的惨痛教训。