STM32CubeIDEのprintfでfloatが使えない問題の解決方法をご紹介します。
STM32CubeIDEのprintfでfloatを使うには設定が必要ですが、STM32CubeIDEのバージョンによって設定方法が違うので注意しましょう。
目次
STM32CubeIDE ver.1.0.2以降
ver.1.0.2以降の場合は、下記の設定を行うだけで使えるようになります。
- プロジェクトを右クリック→Properties
- C/C++ Build→Settings→MCU Settings
- Use float with printf from newlib-nano (-u _printf_float)にチェック
STM32CubeIDE ver.1.0.2より古いバージョン
ver.1.0.2より古いバージョンでは、バグの影響もあって設定方法がだいぶ異なります。注意しましょう。
printfでfloatを使う設定
ver.1.0.0、ver.1.0.1共通して下記の設定が必要です。
- プロジェクトを右クリック→Properties
- C/C++ Build→Settings→MCU GCC Linker→Miscellaneous
- Other flagsに『-u _printf_float』を追加
リンカスクリプトの修正
ver.1.0.0の場合はさらに、リンカスクリプトに対し下記の修正を行う必要があります。
具体的には例えばSTM32F401REの場合、リンカスクリプト:STM32F401RETX_FLASH.ldの中身を下記のように修正します。
変更後:_estack = 0x20018000; /* end of “RAM” Ram type memory */
バグ情報
これ以降は補足のバグ情報です。気になる方はご覧になってください。
-u _printf_floatを直接入力する理由
実はチェックを入れる方法でもプログラムは正しくビルドされます。問題なのはエディタ上でエラー表示されてしまうことです。なので、エディタ上のエラーを気にしなければ特に問題はありません。(絶対気になりますけどね)
この問題はver.1.0.2で解消されました。
リンカスクリプトを編集する理由
STM32CubeMXのバグで正しくないリンカスクリプトを生成しているためだそうです。
This is a lesson of Thou shall not steal. I borrowed the gcc linker script which came with the STMCubeMX code generator. Unfortunately, the script along with the startup file is broken.
…
The Cortex-M stack pointer should always point to the last item in the stack. At startup there are no items in the stack and thus the pointer should point to the first address above the actual memory, 0x020010000 in this case. With the original linker script the stack pointer is set to 0x0200ffff, which actually results in sp = 0x0200fffc (the hardware forces word-aligned stack).
引用:https://stackoverflow.com/questions/28746062/snprintf-prints-garbage-floats-with-newlib-nano
この問題はver.1.0.1で解消されました。