你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

#双节活动 4.touchGFX生成代码中调用printf()仿真时存在的问题及解决

[复制链接]
patch1582 发布时间:2026-10-2 10:37

在touchGFX生成的MDK工程中调用printf()存在一个问题,仿真时,前三次点击RUN,程序自动停止,直到第四次才会停止在断点上。且 printf () 不能打印字符。注释掉 printf () 语句,仿真程序点一次运行,程序就正常跑起来。

经过分析,newlib 会通过 semihosting(BKPT 0xAB)依次打开stdin/stdout/stderr,仿真器不处理这条请求,程序就停在 BKPT 上,所以每点一次 Run 只穿过一次打开调用,约 3 次后(第 4 次)才到达断点,此前程序会卡在仿真程序。

针对以上问题,我把 C 库换成 MicroLIB,它本身不依赖 semihosting,再把 printf() 的输出通过 fputc() 重定向到串口。

如下:

include <stdio.h>

int fputc(int ch, FILE *f)

{

HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);

return ch;

}

然而经过实际测试,还是同样现象,加printf ()就卡,不加printf ()正常。

此时问题可能出在 HAL 函数本身:HAL_UART_Transmit 内部靠 HAL_GetTick ()(SysTick 中断) 做超时判断,还要轮询 TXE/TC 标志、管理状态机; 在仿真器里,HAL 依赖的是时钟推进 + 标志位时序和仿真器的外设模型配合不上,SysTick 计数不按预期推进,或 USART 模型的 TXE/TC 没按 HAL 等待的条件置位; 结果每个字符都卡在 HAL 的等待循环里,字符根本没写进 TDR,所以既没输出、每个字符还制造一次停顿。

因此将fputc 改成LL库的串口发送,如下:

include "stm32h7xx_ll_usart.h"

int fputc(int ch, FILE *f)

{

volatile uint32_t guard = 0;

while (!LL_USART_IsActiveFlag_TXE(huart3.Instance))

{

if (++guard > 1000000)

break;

}

LL_USART_TransmitData8(huart3.Instance, (uint8_t)ch);

return ch;

}

应用以上LL库的串口重定向,解决了printf ()卡代码的问题。

CubeMX生成的工程暂未发现类似问题。

赞 收藏 评论0 发布时间:2026-10-2 10:37

举报

0个回答

所属标签

ST中文论坛活动

即日起开启活动话题入口,之后的活动统一都放在此处,欢迎大家的加入!


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版