STM32 HAL库重定向printf函数
环境:STM32cube(HAL)、Keil5(MDK)
说明1:Micro LIB
Micro LIB是默认 C 库的备选库,由MDK提提供。对C语言代码进行高度优化以使代码变得很小,通常用于必须在极少量内存环境下运行的深层嵌入式应用程序。这些应用程序不在操作系统中运行,不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()。
说明2:semihost mode(半主机模式)
半主机是用于 ARM 目标的一种机制(参考ITM调试机制),可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。
usart.c:
1.勾选了Use Micro LIB,使用MDK提供的Micro LIB
#include "stdio.h"
/*If "Options for target->Target->Use Micro LIB" selected*/
/* Remapping printf*/
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch;
HAL_UART_Receive(&huart5,&ch, 1, 0xFFFF);
return ch;
}
{
uint8_t ch;
HAL_UART_Receive(&huart5,&ch, 1, 0xFFFF);
return ch;
}
2.未勾选Use Micro LIB,使用默认的C语言标准函数库
#include "stdio.h"
/*If "Options for target->Target->Use Micro LIB" not selected*/
/* Remapping printf*/
#pragma import(__use_no_semihosting)
//Support functions required by standard library
struct __FILE
{
int handle;
};
/* Remapping printf*/
#pragma import(__use_no_semihosting)
//Support functions required by standard library
struct __FILE
{
int handle;
};
FILE __stdout;
//Define _sys_exit() to avoid semihost mode
void _sys_exit(int x)
{
x = x;
}
//Remapping fputc functions
int fputc(int ch, FILE *f)
{
// while(__HAL_UART_GET_FLAG(&huart5,UART_FLAG_TC) == RESET);
// {
HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
// }
return ch;
}
void _sys_exit(int x)
{
x = x;
}
//Remapping fputc functions
int fputc(int ch, FILE *f)
{
// while(__HAL_UART_GET_FLAG(&huart5,UART_FLAG_TC) == RESET);
// {
HAL_UART_Transmit(&huart5, (uint8_t *)&ch, 1, 0xFFFF);
// }
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch;
HAL_UART_Receive(&huart5,&ch, 1, 0xFFFF);
return ch;
}
{
uint8_t ch;
HAL_UART_Receive(&huart5,&ch, 1, 0xFFFF);
return ch;
}
对于半主机模式还是不懂,所以定义的_sys_exit()就不知道何用,如果您对此有了解还请不吝赐教!
(PS:如果既没有禁用半主机也没有重定义fputc函数,程序将一直停在中断处,现象就是能下载程序到单片机,但跑不起来)


浙公网安备 33010602011771号