SNSへはこちら

STM32でprintfをサクッと使う方法

この間は RX マイコンの printf 実装例を示しましたが、なんだか需要がありそうなので STM32 バージョンも示しておきます。

参考サイトは以下です。というかほぼそのままです。

何だかんだこのシリーズも6個目ですねw前回まででUARTの基本的な使い方はマスターしたと思います。 今回はCubeMXでの出力は詳しくは解説しないのでまだの方は1から読んでみてくださいgsmcustomeffects.hatenablog.comgsmcustomeffects.hatenablog.comgsmcus...

用意するもの

System Workbench でプロジェクトを作成した際に syscalls.c がありますね。それを使うので削除しないでくださいね。

中身

printfwrite システムコールを使います。その中身を見てみましょう。さっきの syscalls.c では

int _write(int file, char *ptr, int len)
{
    int DataIdx;

    for (DataIdx = 0; DataIdx < len; DataIdx++)
    {
        __io_putchar(*ptr++);
    }
    return len;
}

となり、__io_putchar が使われていることがわかります。その定義は同ファイル上部にて

extern int __io_putchar(int ch) __attribute__((weak));

として extern されています。このままでは実装がありませんので使うことは出来ません。では実際に作りましょう。

実装

以下の関数は main.c でも syscalls.c でもお好きなところに作ってやってください。多分 syscalls.c じゃないほうが良いと思います。

int __io_putchar(int ch) {
    if( ch == '\n' ) {
        uart_send('\r');
    }
    uart_send(ch);
    return 0;
}

要は uart_send() するだけなのですが、シリアル通信時の改行コード \r\n をするのが面倒だったので、__io_putchar 内部で、\n が来たらその直前に \r を足すように指示してしまいました。はい。これで printf のための実装は終わりです。

使用準備

最後にちょっとだけ準備をする必要があります。やることは割と単純。

  • どっかしらプログラムの最初に setbuf(stdout, NULL) を追加しておく
  • printf を使いたい箇所を含むファイルの先頭で #include <stdio.h> をする

これで OK です。