fputc() はストリーム ポインタ引数を取り、2 つの標準出力ストリーム 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 を使用して出力先に出力する必要があります。関連するストリーム。
fprintf も microlib にありますか? そうでない場合、これを実装するより良い方法はありますか?
ドキュメントはあなたに教えてくれますが、そうです。Microlib stdio サポートは#pragma import(__use_full_stdio)ディレクティブによって制御されます。ドキュメントでは、これが使用されていない場合に除外されるものについて明確ではありません。なしで試してみて、何か不足している場合は使用してください。つまり、printf() は stdout ストリームへの fprintf() として実装されているので、printf() がある場合は fprintf() があると思います。