PYNQかZYBO Z7-20が欲しい中の人です(誰かくれないかなぁ)。前回からの続きで、printfでfloatを表示させる話です。
マイコンのデバッグでは、UARTを出力先に指定したprintfを実行させることがあります(なんか変な感じするけど)。STM32の場合syscalls.cの__io_putchar()を書き換えてUARTに吐き出したり(weak定義に関してはこちらから)、_write()関数の中身を書き換えることで実装するのが楽なようです(こことかここを参照)。
1. とりあえずprintfをUARTで使えるようにする
*UARTが使えている前提で話を進めていきます。HAL_UART_Transmitとかが使えていれば大丈夫。CubeIDEでも同様にしてprintfの出力先をUARTに変更できます。/(プロジェクト名)/Srcの中にsyscalls.cがあるはずなので、それを開き_write()のところまで行きます。で、その中身をこんな感じで書き換えます。
__attribute__((weak)) int _write(int file, char *ptr, int len) { int DataIdx; for (DataIdx = 0; DataIdx < len; DataIdx++) { // __io_putchar(*ptr++); HAL_UART_Transmit(&huart1, ptr++, 1, 1); } return len; }
このままコンパイルすると"huart1ってなんだよ"って怒られるので、ヘッダと変数の宣言部分に
/* Includes */ #include...#include #include #include #include #include
と書き換えておきます。これでprintf()を実行するとTerminalとかになんか出てくるはずです(%fに関しては後述)。
2. %fを出力する
さて、ここまででprintfは%fフォーマットを除いて動くようになったはずです。で、%fはこのままでは動きません(TrueStudioやSW4STM32同様)。原因はリンカの設定なのでここを修正していきます。*ここからの話はSTM32Cube FW_F4 V1.24.1での話です(2019/05/10時点で最新)。バージョンの違いに注意してください。
とりあえず、リンカオプションの設定から。
Project->Propertiesを選択し、C++/C Buildを選択します。
次にSettings->MCU GCC Linkerを選択し、Other flagsに"-u _printf_float"を追加します。
ここまで終われば動きそうな気がしますが、うまくいかない(
この原因についてはまだわからないこともありますが、ここを参考にすることで%fを有効化できました。手順としては、STM32F413CHUX_FLASH.ldの_estackの値を0x2004FFFFから0x20050000に書き換えるだけです。この値に関しては、データシートの21ページに書いてある
"CPU can access SRAM1 memory via S-bus, when SRAM1 is mapped at the address range: 0x2000 0000 to 0x2003 FFFF. CPU can access SRAM2 memory via S-bus, when SRAM2 is mapped at the address range: 0x2004 0000 to 0x2004 FFFF."
を見ながら決めました。_estackにはRAM領域の終端アドレスを指定するのですが、
@osaboh さんからの指摘で、Application Binary Interface(ABI)の呼び出し規約の中に
5.2.1.1 Universal stack constraints At all times the following basic constraints must hold:
(中略)
SP mod 4 = 0. The stack must at all times be aligned to a word boundary.
(中略)
5.2.1.2 Stack constraints at a public interface The stack must also conform to the following constraint at a public interface:
SP mod 8 = 0. The stack must be double-word aligned.
とあるので、アドレスは4 or 8 Byteで割り切れる必要があるそうです。
参考:Procedure Call Standard for the ARM Architecture
謝辞
@osaboh さん, @sora_siro1 さん、@Sakurai_Tatuyosさんには%fが表示できない件に関して、動作検証や改善手順の提案などで有益な情報をいただきました。本当にありがとうございます。
©2018 shts All Right Reserved.