STM32 printf问题总结 semihosting microLIB理解

STM32使用printf问题总结

背景:使用STM32F4开发板串口时,想用c语言自带的printf函数把字符串输出到串口调试助手。

  1. 首先需要重定义fputc()、fgetc()函数
///重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
	/* 发送一个字节数据到串口DEBUG_USART */
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);	
	
	return (ch);
}

///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
	int ch;
	HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);	
	return (ch);
}
  1. 勾选options for Target–>Target–>Use MicroLIB,使用MicroLIB库。
    -microLIB 是标准C库的一个备选库,用于极少内存的嵌入式硬件中。
    -microLIB不支持标准库
    -主要完成以下工作:
    -创建一个可执行C程序的环境:创建一个堆栈、创建一个堆(如果需要)、初始化程序用到的库
    -调用main()开始执行

  2. 半主机(semi-hosting):它是一种机制,使得运行在ARM目标机上的代码能够通信,并使用运行了调试器的主机上的Input/Output工具

    -开发初期,开发者可能根本不知道该ARM器件上有什么输入输出设备,而半主机机制使得开发者不用知道ARM器件的外设,利用主机电脑的外设就可以实现输入输出调试。

    -如果要使用ARM器件上的输入、输出设备,首先要关闭semihosting。然后再将输入输出重定向到ARM器件上。
    function structure
    -microLIB 编译时通过Low-Level Functions与硬件连接,采用删减版high-level functions,没用system I/O functions。

  3. 如果不使用microLIB库,而使用标准库(默认使用semihosting),调用printf()之类的函数,会导致死机。解决方法:
    -在程序中添加编译设置,不使用semihosting

//C语言中
#pragma import(__use_no_semihosting_swi)
//汇编语言中
IMPORT __use_no_semihosting_swi

2. 新增20240403

printf 在不同的编译器下,名称不同:

  • GNUC下: __io_putchar()
  • keil MDK下的arm_gcc下: fputc()
#ifdef __GNUC__
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    #define GETCHAR_PROTOTYPE int __io_getchar(FILE *f)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    #define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif

//重定向printf函数
PUTCHAR_PROTOTYPE
{
    txcplt_flag1 = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)&ch, 1);
    while(txcplt_flag1==0);
    return ch;
}
//不能用中断方式获取
GETCHAR_PROTOTYPE
{
    char c = 0;
    while(ring_buffer_read((unsigned char *)&c, &test_buffer) != 0);
    return c;
}

参考:

  1. KeilMDK配置项中Use MicroLIB
  2. I/O retargeting
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值