Arduino IDEで直接バイナリファイルをROMに取り込む


どんな内容か?

前回WioTerminalでJpeg画像をSDカード無で取り込む方法について記述しましたが、@fujitanozomuさんからコメントで、『インラインアセンブラで書けるよ』と情報をいただいたので試してみました。(fujitaさんありがとうございます。)
確かに、コードがスッキリしますし画像のように大きなデータの場合は、このような記述が良さそうです。
今回、WioTerminalを利用していますが、もちろん他のArduinoでも利用できますし応用範囲は広いのではないかと思います。

プログラムについて

前回は、Jpeg画像を使ってサンプル作りましたが、利用しているLovyanGFXライブラリは、PNGの表示もサポートしていることに気づいたので今回はPNGにしてみました。

WioMemoryPng.ino
#include "arduino.h"

// https://platformio.org/lib/show/7359/LovyanGFX
#include <LGFX_TFT_eSPI.hpp>

static TFT_eSPI tft;

#define IMG_WIDTH  (320)
#define IMG_HEIGHT (240)

// これが重要なインラインアセンブラで指定したファイルをROMに配置するコードです。
#define  INC_BIN(file, sym) \
__asm(\
  ".globl " #sym "\n"\
  #sym ":\n"\
  ".incbin " #file "\n"\
  ".global _sizeof_" #sym "\n"\
  ".set _sizeof_" #sym ", . - " #sym "\n"\
);

extern const uint8_t png[], _sizeof_png[];

// ここは、各自の環境に合わせてフルパスを記述する必要がある。(相対パスだとファイルが見つからない)
INC_BIN("C:\\Projects\\GitHub\\WioMemoryPng\\data\\wio.png", png);

void setup()
{
  tft.init();
  tft.setRotation(3);
  tft.drawPng(png, (int)_sizeof_png, 0, 0, IMG_WIDTH, IMG_HEIGHT);
}

void loop() {
}

少し残念だったのは、上手く相対パスで指定することができませんでした。(やり方が分からなかった)
もし上手いやり方知っている方いれば教えてください。

肝は、『incbin』ですね。ファイル名を指定すると指定場所に配置してくれるようです。
残念ながらC言語のsizeofでサイズが取得できないので、別途名前を定義してファイルサイズが分かるようになっています。

前回作ったサイトがムダになってしまいそうですが、まあアレはアレで何か別な使い道もあるかと思いますのでそのまま残しておくことにします。


やっぱりイラストは、JpegよりPngの方が綺麗だし、サイズも小さくて良いですね。素晴らしい画像ライブラリにも感謝。

以上です。

参考にしたサイト
https://gsmcustomeffects.hatenablog.com/entry/2019/02/05/055259