printfリダイレクト印刷ログのデバッグが容易なブログのまとめについて
4472 ワード
説明:このブログは要約の性質で、内容はすべて転載します
一、STM 32 IARにおいてprintf関数を呼び出す一つの方法シリアルポートが配置されている場合、工程の一つのcファイルに以下のコードを加える:注:直接main.cファイルの前にこのコードを入れてもいいですが、このようなコードは習慣があまりよくなく、コードが雑然としていて、個人的にはお勧めしません.私は習慣的に新しいredefineprintfを作りました.cファイル、このファイルにこのコードを追加し、プロジェクトにファイルを追加することを忘れないように注意してください.
その後、コンパイル中にidentifier"FILE"is undefinedが表示された場合、Options->GeneralOptions->Library ConfiguationのLibraryをfullに選択すればよい.
二、IARでprintfを使用するいくつかの方法
1、ライブラリファイルの変更
2、
1、option->C/C++compiler----->defined symbolsの下に行を追加するDLIB_FILE_DESCRIPTOR
3、
エラー:FILE is undefined
FILEはstdioです.hの中の、だからこのファイルを見ます
#if _DLIB_FILE_DESCRIPTOR typedef _Filet FILE; #endif/* _DLIB_FILE_DESCRIPTOR */
FILEを使うにはまず_DLIB_FILE_DESCRIPTOR
調べてみた
stdio.h中
/* Module consistency. */#pragma rtmodel="__dlib_file_descriptor",_STRINGIFY(_DLIB_FILE_DESCRIPTOR)
Dlibを再確認Defaults.h
#ifndef _DLIB_FILE_DESCRIPTOR #define _DLIB_FILE_DESCRIPTOR 0 #endif
0を1に変更すればいいので、まず読み取り専用属性を除去します.
三、インターネットを検索する上で、このような問題の解決に関する文章資料も豊富だが、その考え方によっては多くの問題に直面している.
まず,コードを貼り付け,ほとんどのコードは類似のスキームであり,putcharまたはfputc関数を書き換える.
実際のプログラムはマクロUSEを定義しましたIAR、すなわちputchar()関数が実装されているが、実際にデバッグするとprintf()関数はputchar()およびfputs()を順次呼び出すので、いずれかの関数を実装すればよい.つまり、私がUSEを定義しなくても、上記のコードです.IARは、依然として利用可能です.
書き換えたputchar()関数はch変数を返さなければならないことに注意してください.そうしないと、最初の文字が一度しか印刷されません.
STM 32を使用したシリアルポート送信はブロックされています.つまり、1文字プログラムを送信してから、次の文字の送信が続行されます.
IARを構成する環境Options->General Options->Library ConfiguationのLibraryはFullであることを覚えておいてください.
printf()関数を追加IARの最適化機能を使用しない場合、8.5 KBytes程度のreadonly code memory、30 Bytesのreadonly data memory、2.4 KBytes程度のreadwrite data memoryが増加します.
四、
今日、マクロ定義の部分を抽出するコードが表示されます.値は次のようになります.
#define DEBUG(fmt,args...) printf("%s(%d)-%s -> "#fmt "", __FILE__, __LINE__, __FUNCTION__, ##args);
プログラミング界にデビューした多くの新人の友达(私も新人です.汗..)を信じて、これを見ると疑問に思います.
1.fmtおよび#fmtとは何ですか. 2.##argsとは何ですか.
ここでは、これらの問題について理解しやすい説明をします.
1.fmtはマクロ定義の最初のパラメータであり、コードの展開時に直接代入され、fmtが伝えられた内容を文字列形式で出力することを意味することに注意してください.
2.args..変更可能なパラメータテーブルを表します.前の可変パラメータが無視されたり、空になったりすると、前のカンマがプリプロセッサから削除されます.マクロ呼び出し時に可変パラメータがいくつか提供されている場合は、カンマの後ろにこれらの可変パラメータが配置されます.
#include #include
#define DEBUG_PRINT(fmt,args...) printf("%s(%d)-%s -> "#fmt "", __FILE__, __LINE__, __FUNCTION__, ##args);
void main(void) { char a = 'T', b = 'e', c = 's', d = 't'; DEBUG_PRINT(%c%c%c%c,a,b,c,d); }
五、標準Cは可変パラメータの関数のみをサポートし、関数のパラメータが固定されていないことを意味する.例えばprintf()関数の原型はint printf(const char*format[,argument]...);一方、GNU Cでは、マクロは、可変数のパラメータ、例えば、#define pr_を受け入れることもできるdebug(fmt,arg...)\printk(fmt,##arg)ここでargは残りのパラメータが0個以上であることを示し、これらのパラメータとパラメータ間のカンマはargの値を構成し、マクロ拡張時にargを置換し、例えば以下のコード:pr_debug('%s:%d',filename,line)はprintk('%s:%d',filename,line)に拡張されます.
六.本人のIAR工事の中で使うリダイレクトのprintf配置、iar for arm、華大136プラットフォーム
#define CONFIG_RELASE 0
#if (CONFIG_RELASE == 0) #define Debug(fmt,arg...) printf(fmt,##arg) #else #define Debug(fmt,arg...) #endif
PUTCHAR_PROTOTYPE { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ //USART_SendData(USART3, (uint8_t) ch); Uart_SendData(UARTCH0, (uint8_t) ch); /* Loop until transmit data register is empty */ while (Uart_GetStatus(UARTCH0, UartTxe)==0)//TCではなくTxeを使用していることに注意してください.TCはUart_にあります.SendData関数で使用される{
}
return ch; }
#ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif/* __GNUC__ */
一、STM 32 IARにおいてprintf関数を呼び出す一つの方法シリアルポートが配置されている場合、工程の一つのcファイルに以下のコードを加える:注:直接main.cファイルの前にこのコードを入れてもいいですが、このようなコードは習慣があまりよくなく、コードが雑然としていて、個人的にはお勧めしません.私は習慣的に新しいredefineprintfを作りました.cファイル、このファイルにこのコードを追加し、プロジェクトにファイルを追加することを忘れないように注意してください.
#include
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
USART_SendData(USART1, (u16) ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{}
return ch;
}
その後、コンパイル中にidentifier"FILE"is undefinedが表示された場合、Options->GeneralOptions->Library ConfiguationのLibraryをfullに選択すればよい.
二、IARでprintfを使用するいくつかの方法
1、ライブラリファイルの変更
2、
1、option->C/C++compiler----->defined symbolsの下に行を追加するDLIB_FILE_DESCRIPTOR
3、
エラー:FILE is undefined
FILEはstdioです.hの中の、だからこのファイルを見ます
#if _DLIB_FILE_DESCRIPTOR typedef _Filet FILE; #endif/* _DLIB_FILE_DESCRIPTOR */
FILEを使うにはまず_DLIB_FILE_DESCRIPTOR
調べてみた
stdio.h中
/* Module consistency. */#pragma rtmodel="__dlib_file_descriptor",_STRINGIFY(_DLIB_FILE_DESCRIPTOR)
Dlibを再確認Defaults.h
#ifndef _DLIB_FILE_DESCRIPTOR #define _DLIB_FILE_DESCRIPTOR 0 #endif
0を1に変更すればいいので、まず読み取り専用属性を除去します.
三、インターネットを検索する上で、このような問題の解決に関する文章資料も豊富だが、その考え方によっては多くの問題に直面している.
まず,コードを貼り付け,ほとんどのコードは類似のスキームであり,putcharまたはfputc関数を書き換える.
#ifdef USE_IAR
#define PUTCHAR_PROTOTYPE int putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endif
PUTCHAR_PROTOTYPE{
HAL_UART_Transmit(&huart1, (char *)(&(ch)), 1, 10);
return ch;
}
実際のプログラムはマクロUSEを定義しましたIAR、すなわちputchar()関数が実装されているが、実際にデバッグするとprintf()関数はputchar()およびfputs()を順次呼び出すので、いずれかの関数を実装すればよい.つまり、私がUSEを定義しなくても、上記のコードです.IARは、依然として利用可能です.
書き換えたputchar()関数はch変数を返さなければならないことに注意してください.そうしないと、最初の文字が一度しか印刷されません.
STM 32を使用したシリアルポート送信はブロックされています.つまり、1文字プログラムを送信してから、次の文字の送信が続行されます.
IARを構成する環境Options->General Options->Library ConfiguationのLibraryはFullであることを覚えておいてください.
printf()関数を追加IARの最適化機能を使用しない場合、8.5 KBytes程度のreadonly code memory、30 Bytesのreadonly data memory、2.4 KBytes程度のreadwrite data memoryが増加します.
四、
今日、マクロ定義の部分を抽出するコードが表示されます.値は次のようになります.
#define DEBUG(fmt,args...) printf("%s(%d)-%s -> "#fmt "", __FILE__, __LINE__, __FUNCTION__, ##args);
プログラミング界にデビューした多くの新人の友达(私も新人です.汗..)を信じて、これを見ると疑問に思います.
1.fmtおよび#fmtとは何ですか. 2.##argsとは何ですか.
ここでは、これらの問題について理解しやすい説明をします.
1.fmtはマクロ定義の最初のパラメータであり、コードの展開時に直接代入され、fmtが伝えられた内容を文字列形式で出力することを意味することに注意してください.
2.args..変更可能なパラメータテーブルを表します.前の可変パラメータが無視されたり、空になったりすると、前のカンマがプリプロセッサから削除されます.マクロ呼び出し時に可変パラメータがいくつか提供されている場合は、カンマの後ろにこれらの可変パラメータが配置されます.
#include #include
#define DEBUG_PRINT(fmt,args...) printf("%s(%d)-%s -> "#fmt "", __FILE__, __LINE__, __FUNCTION__, ##args);
void main(void) { char a = 'T', b = 'e', c = 's', d = 't'; DEBUG_PRINT(%c%c%c%c,a,b,c,d); }
五、標準Cは可変パラメータの関数のみをサポートし、関数のパラメータが固定されていないことを意味する.例えばprintf()関数の原型はint printf(const char*format[,argument]...);一方、GNU Cでは、マクロは、可変数のパラメータ、例えば、#define pr_を受け入れることもできるdebug(fmt,arg...)\printk(fmt,##arg)ここでargは残りのパラメータが0個以上であることを示し、これらのパラメータとパラメータ間のカンマはargの値を構成し、マクロ拡張時にargを置換し、例えば以下のコード:pr_debug('%s:%d',filename,line)はprintk('%s:%d',filename,line)に拡張されます.
六.本人のIAR工事の中で使うリダイレクトのprintf配置、iar for arm、華大136プラットフォーム
#define CONFIG_RELASE 0
#if (CONFIG_RELASE == 0) #define Debug(fmt,arg...) printf(fmt,##arg) #else #define Debug(fmt,arg...) #endif
PUTCHAR_PROTOTYPE { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ //USART_SendData(USART3, (uint8_t) ch); Uart_SendData(UARTCH0, (uint8_t) ch); /* Loop until transmit data register is empty */ while (Uart_GetStatus(UARTCH0, UartTxe)==0)//TCではなくTxeを使用していることに注意してください.TCはUart_にあります.SendData関数で使用される{
}
return ch; }
#ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to 'Yes') calls __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif/* __GNUC__ */