使用带有两个UART的printf

时间:2013-01-23 09:30:04

标签: c embedded serial-port printf

我在retarget.c中实现了fputcfgetc,以便在Cortex-M3上通过UART0成功使用printf。

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

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

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

我想,一旦我将它指向另一个'FILE',那么它只是检查fputc中指向的是哪个,但它是我正在努力解决的FILE指针的初始设置。 / p>

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

在microlib中也是fprintf?如果没有,是否有更好的方法来实现它?

谢谢!

1 个答案:

答案 0 :(得分:10)

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

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

fprintf (stderr, "Error reading file" ) ;

例如。

最小重定向(特定于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 ;
}

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

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

  

在microlib中也是fprintf?如果没有,是否有更好的方法来实现它?

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