使用arm-none-eabi工具链时重新定义fputc函数

时间:2018-07-25 09:07:51

标签: c gcc g++ stm32 redefinition

我们有一个STM32 C / C ++项目,并且我们重新定义了弱的fputc(int, FILE *)函数,以便将printf的输出重定向到某个UART通道。

到目前为止,我们正在使用IAR compiler IAR 下构建项目。通过UART的日志记录工作正常。

我们现在已切换到arm-none-eabi toolchain,并且正在使用g++构建项目。但是看来fputc函数的重新定义不再链接了,因此UART日志记录不起作用。

如何强制printf使用重新定义的功能?

2 个答案:

答案 0 :(得分:2)

arm-none-eabi-工具链使用的是newlib,它使您可以重新定义_write(int fd, const void *buf, size_t count),然后所有stdio输出函数都将使用该接口。 fd==1对应于stdoutfd==2stderr。您必须提供更多的存根函数,例如

void _exit(int) {
  while(1)
    ;
}

等其中大多数都是微不足道的,但是printf()也需要有效的_sbrk(),因为它在内部使用malloc()

答案 1 :(得分:1)

将项目从Keil转换为Cube时遇到了同样的问题。在GitHub上找到了这种优雅的STM32 printf retarget to UART解决方案(请原谅复制粘贴):

iterator_base<T>::p

这可能会或可能不会在您的特定情况下起作用,但是您会收到想法... 就我而言,我必须在函数类型前面加上/*# 7- Retarget printf to UART (std library and toolchain dependent) #########*/ #if defined(__GNUC__) int _write(int fd, char * ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t *) ptr, len, HAL_MAX_DELAY); return len; } #elif defined (__ICCARM__) #include "LowLevelIOInterface.h" size_t __write(int handle, const unsigned char * buffer, size_t size) { HAL_UART_Transmit(&huart1, (uint8_t *) buffer, size, HAL_MAX_DELAY); return size; } #elif defined (__CC_ARM) int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; } #endif // OR: // Add syscalls.c with GCC #ifdef __GNUC__ #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 { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); return ch; }

extern "C"