首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32 C++与重定向std::cout to UART

STM32 C++与重定向std::cout to UART
EN

Stack Overflow用户
提问于 2022-03-11 17:13:05
回答 1查看 801关注 0票数 1

我在试图获得std::cout在使用STM32 (通常是从包中安装STM32CubeIDE的标准安装)时遇到困难。

我已经查阅了许多关于为stdio.h和printf重定向UART的资料,但我正在尝试使用std::cout在C++环境中实现这一切。我发现的主要来源是:https://www.keil.com/support/man/docs/armlib/armlib_chr1358938931411.htm

根据包含标题的方式和时间,我得到了不同的错误,下面是我尝试过的:

推迟。h:

代码语言:javascript
复制
#ifndef _RETARGET_H__
#define _RETARGET_H__

#include "stm32f1xx_hal.h"
#include <sys/stat.h>
#include <stdio.h>

void RetargetInit(UART_HandleTypeDef *huart);

int _isatty(int fd);
int _write(int fd, char* ptr, int len);
int _close(int fd);
int _lseek(int fd, int ptr, int dir);
int _read(int fd, char* ptr, int len);
int _fstat(int fd, struct stat* st);


namespace std {

int fputc(int, FILE *);

}

#endif //#ifndef _RETARGET_H__

retarget.cc (剪短了一点)更正了这是一个c++文件

代码语言:javascript
复制
void RetargetInit(UART_HandleTypeDef *huart) {
  gHuart = huart;

  /* Disable I/O buffering for STDOUT stream, so that
   * chars are sent out as soon as they are printed. */
  setvbuf(stdout, NULL, _IONBF, 0);
}

int _write(int fd, char* ptr, int len) {
  HAL_StatusTypeDef hstatus;

  if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
    hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);
    if (hstatus == HAL_OK)
      return len;
    else
      return EIO;
  }
  errno = EBADF;
  return -1;
}

namespace std {

struct __FILE
{
  int handle;
  /* Whatever you require here. If the only file you are using is */
  /* standard output using printf() for debugging, no file handling */
  /* is required. */
};
FILE __stdout;
FILE __stdin;
FILE __stderr;


int fputc(int c, FILE *stream)
{
      char tOut = c;

      return _write(STDOUT_FILENO, &tOut, 1);

  /* Your implementation of fputc(). */
}

}

和main.cpp (也被剪短了一点):

代码语言:javascript
复制
#include "retarget.h"
#include <iostream>

int main(void)
{
  /* HAL Init stuff Clipped */
  RetargetInit(&huart1);
  std::cout << "\n\nSTM32 main.c Startup\n" << std::endl;

  while(1){
      std::cout << "*";

      HAL_Delay(1000);
  }
}

如果我转到printf (改为和std::cout到printf),一切都会正常工作,所以_write函数可以正确地发送到UART,所以我知道很多功能都在工作。

现在,我们来看看错误。

如前所述,编者抛出:

代码语言:javascript
复制
In file included from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ext\string_conversions.h:43,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\basic_string.h:6557,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\string:55,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\locale_classes.h:40,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\ios_base.h:41,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ios:42,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ostream:38,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\iostream:39,
                 from ../Core/Src/main.cc:26:
c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\cstdio:111:11: error: 'int fputc(int, FILE*)' conflicts with a previous declaration
  111 |   using ::fputc;
      |           ^~~~~
In file included from ../Core/Src/main.cc:25:
../Core/Inc/retarget.h:23:5: note: previous declaration 'int std::fputc(int, FILE*)'
   23 | int fputc(int, FILE *);
      |     ^~~~~
make: *** [Core/Src/subdir.mk:41: Core/Src/main.o] Error 1 

如果我在我的main.cc文件中翻转包含,使iostream首先被拉进来,我得到:

代码语言:javascript
复制
In file included from ../Core/Src/main.cc:26:
../Core/Inc/retarget.h:23:22: error: 'int std::fputc(int, FILE*)' conflicts with a previous declaration
   23 | int fputc(int, FILE *);
      |                      ^
In file included from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\cstdio:42,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ext\string_conversions.h:43,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\basic_string.h:6557,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\string:55,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\locale_classes.h:40,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\bits\ios_base.h:41,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ios:42,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\ostream:38,
                 from c:{stm32 tools path snipped}arm-none-eabi\include\c++\10.3.1\iostream:39,
                 from ../Core/Src/main.cc:25:
c:{stm32 tools path snipped}arm-none-eabi\include\stdio.h:214:5: note: previous declaration 'int fputc(int, FILE*)'
  214 | int fputc (int, FILE *);
      |     ^~~~~
make: *** [Core/Src/subdir.mk:41: Core/Src/main.o] Error 1

有什么建议吗?提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-14 18:13:52

最后偶然发现了这个解决方案,这取决于_write()函数是如何编译的。这个函数必须用C编译器编译才能正确工作(据我所知)。

因此,的解决方案,就我的工作而言:

我将retarget.cc重命名为retarget.c (除了retarget.h的包含路径之外,它保持为retarget.c,未修改)。

对于retarget.h,我使用关联的retarget.h文件包装了extern“C”中的函数原型:

代码语言:javascript
复制
#ifndef _RETARGET_H__
#define _RETARGET_H__

#include "stm32f1xx_hal.h"
#include <sys/stat.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

void RetargetInit(UART_HandleTypeDef *huart);

int _isatty(int fd);
int _write(int fd, char* ptr, int len);
int _close(int fd);
int _lseek(int fd, int ptr, int dir);
int _read(int fd, char* ptr, int len);
int _fstat(int fd, struct stat* st);

#ifdef __cplusplus
} //extern "C"
#endif

#endif //#ifndef _RETARGET_H__

现在一切都如期而至-- std::cout << "Working now!" << std::endl;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71442249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档