printf函数的重向定义的问题,为何在keil中能用在vscode的eide插件中中用不了?
摘要: 当使用GCC编译器时,原基于Keil环境的printf重定向代码(含#pragma import(__use_no_semihosting))失效。原因在于该指令仅适用于Keil,而GCC无法识别。解决方案是改用GCC兼容的重定向函数_write,通过串口逐个发送数据字节,并检测发送完成标志。修改后,printf在GCC环境下可正常输出数据到PC端。
·
问题:我检查了一下时钟配置没有问题,用串口直接发送数据到pc端也没有问题,当我使用printf函数的时候pc端无法显示任何数据。
在keil中的fput函数的重向定义参考正点原子的代码如下,我最开始也是用的这一版的代码:
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
UART_SendByte('Z');
while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET); // 等待发送完成
USART_SendData(USART2, (uint8_t)ch);
return ch;
}
#endif
问题所在:
#pragma import(__use_no_semihosting)
其中这一行代码,只在keil的环境中有效,而我eide使用的c语言编译器是gcc,因此无法识别这个代码,重向定义无效。
解决方案:(gcc下的printf函数重向定义)
#if 1
int _write(int fd, const void *buf, size_t count)
{
const uint8_t *ptr = (const uint8_t *)buf;
for (size_t i = 0; i < count; i++)
{
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, ptr[i]);
}
return count;
}
#endif
改成这样就能正常使用了。我贴一张串口助手上面的运行结果吧

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)