|
最近在做一个项目,用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打开,把警告变成错误提示,终止编译,这样可以强迫自己修正警告。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|