使用带有两个UART的printf

Mar*_*ark 6 c embedded printf serial-port

我已经实现fputcfgetc在retarget.c中通过UART0在Cortex-M3上成功使用printf.

但是,我想要第二个uart通道来获取其他调试信息.我如何使用printf将UART0整合得很好?

例如,使用fprintf到自定义目标并检查fputc将字符发送到哪个目标.例如,用于正常输出fprintf(UART0,"..");和用于调试输出fprintf(UART1,"..");

但我无法看到fopen是否被调用stdout所以我很难看到如何手动实现它.(如果我只是打电话fprintf(RANDOM_VALUE,..),我不知道这会怎么样.

我想,一旦我将它定向到一个不同的'FILE',那么它只是检查在fputc中指向哪个,但它是我正在努力的FILE指针的初始设置.

也许某种方式来区分stdout和stderr,尽管那时我仍然有同样的问题从两个独立的通道获取输入.

microlib中也是fprintf?如果没有,有没有更好的方法来实现这个?

谢谢!

Cli*_*ord 10

fputc()接受一个流指针参数,有两个标准输出流stdin,stdout和stderr.在重定向的较低级别,它们分别与文件描述符0,1和2相关联,您可以使用此信息将stderr与设备驱动程序级别的备用UART关联.

然后,您可以使用stderr输出调试数据:

fprintf (stderr, "Error reading file" ) ;
Run Code Online (Sandbox Code Playgroud)

例如.

最小的重定向(特定于Keil ARM-MDK/RealView)可能如下所示:

struct __FILE 
{
    int handle;  
};

enum 
{
    STDIN_HANDLE,
    STDOUT_HANDLE,
    STDERR_HANDLE
} ;

FILE __stdin = {STDIN_HANDLE} ;
FILE __stdout = {STDOUT_HANDLE} ;
FILE __stderr = {STDERR_HANDLE} ;

int fputc(int ch, FILE *f) 
{
    int ret = EOF ;

    switch( f->handle )
    {
        case STDOUT_HANDLE :
            // Write character to UART0
            ...
            ret = ch ;
            break ;

        case STDERR_HANDLE :
            // Write character to UART1
            ...
            ret = ch ;
            break ;

        default :
            break ;

    return ret ;
}
Run Code Online (Sandbox Code Playgroud)

显然,如果需要,这也是您可以在文件系统中挂钩的地方,在这种情况下,您的__FILE结构无疑会有其他成员.

如果您不想为此目的使用stderr,则必须重新定位fopen()以将设备名称(例如"dbg:")转换为所需端口的文件描述符,然后使用stdio输出到相关流.

microlib中也是fprintf?如果没有,有没有更好的方法来实现这个?

文档会告诉你,但是.Microlib stdio支持由#pragma import(__use_full_stdio)指令控制,如果不使用,则文档不清楚排除的内容.不用尝试,如果遗漏任何东西就使用它.这就是说我会想象printf()是作为stdout流的fprintf()实现的,所以如果你有printf()你就有fprintf().