我在retarget.c中实现了fputc
和fgetc
,以便在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?如果没有,是否有更好的方法来实现它?
谢谢!
答案 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()。