如何将 STM32 的 fprintf 正确重定向到多个目的地(UART)?

huangapple go评论62阅读模式
英文:

How to properly retarget STM32 fprintf to multiple destinations (uarts)?

问题

我正在尝试使用fprintf(或printf)将输出发送到多个目标(UARTS),使用GCC编译器。

覆盖_write_r仅适用于stderr:

    int _write_r(void *reent, int fd, char *ptr, size_t len) // stderr
    {
    	__asm volatile ("nop");
    	__asm volatile ("nop");
    
        return _write((FILE*)fd, ptr, len);
    
    	//return 0;
    }

    fprintf(stdout, "Error reading file"); // 正常工作!

但是尝试以下操作没有效果,根本不会调用_write_r():

    fprintf((FILE *)USART1, "Error reading file 2");

所以基本上我计划使用switch/case根据不同的目标进行输出。

ST社区上有一些示例,但它们使用__io_putchar(int ch),这样就无法在不同目标之间切换。

有什么想法吗?

谢谢!
英文:

I am trying to use fprintf (or printf) to multiple destinations (UARTS) using GCC

Overriding _write_r works only for stderr:

int _write_r(void *reent, int fd, char *ptr, size_t len) // stderr
{
	__asm volatile ("nop");
	__asm volatile ("nop");

    return _write((FILE*)fd, ptr, len);

	//return 0;
}

fprintf (stdout, "Error reading file" ) ; // works!

But trying this is not working, _write_r() is not called at all.

fprintf ((FILE *)USART1, "Error reading file 2" ) ;

So basically I plan to use a switch/case depending on destinations.

Some examples are available on ST community, but are using __io_putchar(int ch) which leaves no possibility to switch between destinations.

Any idea?

Thank you!

答案1

得分: 1

使用 fopencookie 函数打开具有自定义回调的流。您可以创建类似以下方式的 fopenusart 函数:

#define _GNU_SOURCE
#include <stdio.h>
static ssize_t usart_read(void *cookie, char *buf, size_t size) {
    UART_HandleTypeDef *usart = cookie;
    HAL_StatusTypeDef s = HAL_UART_Transmit(usart, buf, size);
    return s == HAL_OK ? size : -1;
}
// 等等。
static const cookie_io_functions_t usart_functions = {
    .read = usart_read,
    // 等等。
};
FILE *fopenusart(UART_HandleTypeDef *usart, const char *mode) {
    return fopencookie(usart, mode, usart_functions);
}
英文:

Use fopencookie to open your own stream with custom callbacks. You could create your like fopenusart built on top like the following:

   #define _GNU_SOURCE
   #include &lt;stdio.h&gt;
   static ssize_t usart_read(void *cookie, char *buf, size_t size) {
      UART_HandleTypeDef *usart = cookie;
      HAL_StatusTypeDef s = HAL_UART_Transmit(usart, buf, size);
      return s == HAL_OK ? size : -1;
   }
   // etc.
   static const cookie_io_functions_t usart_functions = {
       .read = usart_read,
       // etc.
   };
   FILE *fopenusart(UART_HandleTypeDef *usart, const char *mode) {
       return fopencookie(usart, mode, usart_functions);
   }

答案2

得分: 0

抱歉回复自己的问题,但我发现现有的方法对于STM32 Cortex M0平台来说过于复杂。标准NANO库仍然占用4K,没有提到重定向实现。

我只是想要一个通用的printf()函数,能够在运行时重定向到USARTs、RAM、LCD或所有其他设备。

最简单的方法是采用一个简单(小型)的printf实现,首次谷歌搜索我找到了这个
https://github.com/heartoftechnology/embedded-printf

将原型修改为:

void embedded_printf(void *stream, const char *format, ...)

将putchar()修改为以下内容(也接受stream参数):

void embedded_putChar(void *stream, uint8_t c)

设计putchar()如下:

void embedded_putChar(void *stream, uint8_t c) {

    switch ((uint32_t)(stream))
    {
        default:

            break;

        case (uint32_t)USART2:

            // 对于USART2的putc()
            break;

    }
}

就是这样。

英文:

Sorry to reply my own question, but all that I found is a way too complicated for a STM32 Cortex M0 platform. Standard NANO library still occupies 4K, no mention redirect implementation.

I simply wanted a common printf() function able to redirect to USARTs, RAM, LCD or ALL other devices at runtime.

The easiest way to do it was to take a simple (tiny) printf implementation, at first google search I found this one
https://github.com/heartoftechnology/embedded-printf

Modify the prototype to this

void embedded_printf(void *stream, const char *format, ...)

Modify the putchar() to this (to accept stream also)

void embedded_putChar(void *stream, uint8_t c) 

Design the putchar() like this

void embedded_putChar(void *stream, uint8_t c) {

	switch ((uint32_t)(stream))
	{
		default:
	
			break;
	
		case (uint32_t)USART2:
	
				// putc() for USART2
			break;

	}
}

And that's all.

huangapple
  • 本文由 发表于 2023年3月7日 18:35:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660853.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定