问题发现

在platform io中开发stm32g0系列芯片的串口通信程序,想使用printf函数,根据传统的方法重定义fputc函数,串口中没有输出。但是用keil同样的代码是可以输出的。

问题分析

根据传统的方法要使用printf函数,只需重定义fputc函数就可以了,如下:

#include "stdio.h"

#ifdef __GNUC__            //gcc编译器宏定义
  /* 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 

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&hlpuart1,(uint8_t *)&ch,1,0xFFFF);
  return ch;
}

该方法在keil arm-mdk中能够实现的。但是到了platformio就不行了
应该是keil用的编译器编译资源跟platformio用的是不一样的。
爬了几天论坛发现有相似的问题,链接在下面
解决方案,论坛链接

接着干脆也写了个syscalls.c

重写_write函数

//syscalls.c文件

#include "main.h"
#include "usart.h"
#include  <errno.h>
#include  <sys/unistd.h> // STDOUT_FILENO, STDERR_FILENO


int _write(int file, char *data, int len)
{
   if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
   {
      errno = EBADF;
      return -1;
   }

   // arbitrary timeout 1000
   HAL_StatusTypeDef status =
      HAL_UART_Transmit(&hlpuart1, (uint8_t*)data, len, 1000);

   // return # of bytes written - as best we can tell
   return (status == HAL_OK ? len : 0);
}

这个_writre()函数是弱定义的,所以用户可以直接定义它