GNU Arm Compiler のPRINTF と SCANF の 浮動小数点サポートについて – Community Translated (JA)
- RSS フィードを購読する
- 新着としてマーク
- 既読としてマーク
- ブックマーク
- 購読
- 印刷用ページ
- 不適切なコンテンツを報告
Community Translated by MoTa_728816 Version : *A
質問:PSoC® Creator™ でsprintf を使用した文字列に浮動小数点の値が反映されません。原因と対策を教えてください。
回答:PSoC Creator 3.0 のリリースで、私たちはGNU Armコンパイラを CodeSourcery から GNU Arm に変更しました。
後者はnewlib とnewlib-nanoのライブラリを選択できます。PSoC はメモリ容量に余裕がないため、ほとんどの PSoC 4と PSoC 5LP の設計においてフラッシュとRAMを節約するために、newlib-nano をデフォルトとしました。しかし、newlib-nano では浮動小数点文字列のフォーマットをサポートするためには浮動小数点処理を有効にする必要があります。
問題:下記のようなコードの一部を考えます。
char My_String[30] ;
double My_Float = 3.14159;
sprintf(My_String, “Value of pi is %.2f to 2dp”, My_Float);
この結果のMy_Stringは “Value of pi is: to 2dp” です。
3.14 は My_String に含まれません。
これは新しくGNU Arm コンパイラツールチェーンを使用した PSoC 4 と PSoC 5LP のプロジェクトのデフォルト C ランタイムライブラリとなった newlib-nano ライブラリが浮動小数点フォーマットをサポートするためには、浮動小数点サポート関数をリンクする必要があるためです。これらの関数はデフォルトではリンクされません。
対策:
- Newlib-nano の浮動小数点フォーマットサポートを有効にする
メニューから Project > Build Settings > Arm GCC 4.7.3 > Linker > Command Line を開いてください。Custom Flags 欄に “-u _printf_float” を追加してください。
この変更はアプリケーションのフラッシュ使用量を 10Kバイトから15Kバイト程度、RAMの使用量を少々増加させます。
2. ライブラリ全体を変更する
二つ目の方法はライブラリ全体を変更することです。
メニューから Project > Build Settings Arm GCC 4.7.3 > Linker > General を開いてください。“Use newlib-nano” を False に設定してください。
これでライブラリは newlib に変更され、すべてのランタイムライブラリの機能がサポートされますが、フラッシュの使用量が25Kバイトから 35Kバイト程度増加しRAMの使用量も 2Kバイト程度増加します。
sscanf の対策:sscanf についても同様の問題が存在します。例えば、下記のようなコードの一部を考えます。
char My_String[30] = “Pi is 3.14” ;
char My_Str1[10], My_Str2[10] ;
float Pi = 2.0;
sscanf(My_String, “%s %s %f”, My_Str1, My_Str2, &Pi);
これは My_Str1 に “Pi” を、My_Str2 に “is” を代入しますが、Pi は2.0のままで期待した 3.14 は代入されません。
sprintf の使用方法で説明したものと同様の対策が適用できます。
ただし1.の方法では、追加するフラグを“-u _scanf_float”としてください。
の方法でprintf と scanf 関数の両方を使用する場合は、両方のフラグを使用する必要があります。
PSoC Creator 3.1 および以降のバージョンでは設定が少し異なります。newlib-nano で浮動小数点サポートを直接有効にするオプションが追加されています。この設定は下図を参照してください。
注:プロジェクトの設定でsprintf とsscanf をサポートするのに必要なHeapサイズが設定されていることを確認してください (.cydwr > System > Heap Size)。デフォルトの値は0x80ですが、これらの関数をサポートするためには十分ではありません。もっと大きな 0x1000 等の値に設定することが可能です。