豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応
豊四季Tiny BASIC for Arduino(オリジナル版)のSRAM消費を軽減する修正を行ってみました。
Arduino UNOでは、SRAMが2kバイトしかありません。
オリジナル版のまま利用した場合、グローバル変数が1481バイト(72%)を利用しており、
残りが567バイトです。機能拡張するにはちょっと辛いです。
そこで、キーワード、エラーメッセージ等のグローバルな固定データをフラッシュメモリ上に
配置する修正をおこない、SRAMの消費を少々押さえました。
参考にしたサイト
・How can I compare __FlashStringHelper* with char* on Arduino?
https://stackoverflow.com/questions/40334026/how-can-i-compare-flashstringhelper-with-char-on-arduino
良く知られているテクニックですが、
Arduino(AVRマイコン)でPROGMEMキーワードを使って変数の宣言を行うことで、
SRAMではなく、フラッシュメモリ上にデータを配置することが出来ます。
ただし、データの参照がちょっと面倒で、専用の参照を行う関数を利用する必要があります。
データ構造にも制約があり、キーワードテーブル等で使う2次元配列は対応されていません。
入れ子になる1次元配列を定義してから、その一次元配列のアドレスを配列として宣言して
2次元配列っぽい構造を作成します。
修正前のキーワードテーブル(オリジナル版よりソースを引用しています)
// Keyword table const char *kwtbl[] = { "GOTO", "GOSUB", "RETURN", "FOR", "TO", "STEP", "NEXT", "IF", "REM", "STOP", "INPUT", "PRINT", "LET", ",", ";", "-", "+", "*", "/", "(", ")", ">=", "#", ">", "=", "<=", "<", "@", "RND", "ABS", "SIZE", "LIST", "RUN", "NEW" };
修正したキーワードテーブル
// Keyword table #define KW(k,s) const char k[] PROGMEM=s // キーワード定義マクロ KW(k000,"GOTO"); KW(k001,"GOSUB"); KW(k002,"RETURN"); KW(k003,"FOR"); KW(k004,"TO"); KW(k005,"STEP"); KW(k006,"NEXT"); KW(k007,"IF"); KW(k008,"REM"); KW(k009,"STOP"); KW(k010,"INPUT"); KW(k011,"PRINT"); KW(k012,"LET"); KW(k013,","); KW(k014,";"); KW(k015,"-"); KW(k016,"+"); KW(k017,"*"); KW(k018,"/"); KW(k019,"("); KW(k020,")"); KW(k021,">=");KW(k022,"#"); KW(k023,">"); KW(k024,"="); KW(k025,"<="); KW(k026,"<"); KW(k027,"@"); KW(k028,"RND"); KW(k029,"ABS"); KW(k030,"SIZE"); KW(k031,"LIST"); KW(k032,"RUN"); KW(k033,"NEW"); const char* const kwtbl[] PROGMEM = { k000,k001,k002, k003,k004,k005,k006, k007,k008,k009, k010,k011,k012, k013,k014, k015,k016,k017,k018,k019,k020, k021,k022,k023,k024,k025,k026, k027,k028,k029,k030, k031,k032,k033, };
KW()マクロは、
const char k000[] PROGMEM="GOTO"; const char k001[] PROGMEM="GOSUB";
と定義するのを省略するのに利用しています。
テーブルの参照はちょっと面倒です。
キーワード比較を行う部分は、一旦、SRAM上のメモリーにコピーして利用しています。
char* pkw = 0; //ひとつのキーワードの内部を指すポインタ char kwtbl_str[16]; // コマンド比較用 // オリジナル pkw = (char *)kwtbl[i]; //キーワードの先頭を指す // 修正版 pkw = strcpy_P(kwtbl_str, (char*)pgm_read_word(&(kwtbl[i])));
フラッシュメモリ上に配置してくれて、かつ参照はSRAMと同等に行えるのと比べると
ちょっと面倒ですね。
とりあえず、この修正によりSRAM消費量を712バイト抑えることが出来ました。
SRAMは1279バイトほど余っているので、ちょっとした機能追加は出来ると思います。
もしかしたら、もっと効率の良いやり方があるかもしれませんが、これで良しとします。

ちょっといじった感じでは、オリジナル版と同じ感じで動いています。

この修正版は、下記にて公開いたいます。
https://github.com/Tamakichi/ttbasic_arduino_uno
« micro:bitをArduino環境で使う (7) シリアル通信 | トップページ | アクティブマトリクス蛍光表示管の実験用表示モジュールの試用 (2) »
「arduino」カテゴリの記事
- Freenove Mecanum ホイール カー キットを購入しました(2025.05.28)
- Arduino IDE+Arduino STM32環境で指定と異なるgccが使われてしまう(2025.01.23)
- Zorin OSでArduino Uno互換機(CH340)が認識しない(2025.01.19)
- Arduino IDE 2.3.4でArduino STM32を利用する(2025.01.12)
- Arduino用 SKK日本語変換ライブラリの開発 その1(2024.12.28)
「AVR」カテゴリの記事
- NeoPixel(WS2812B)の制御 その5(2024.09.15)
- Arduino用SJIS漢字フォントライブラリ SDカード版を作成しました(2018.10.30)
- ATtiny13AでI2C接続キャラクタLCDを利用する(4)(2018.04.16)
- ATtiny13Aで赤外線リモコン受信センサーを使う(2)(2018.04.15)
- ATtiny13AでHC-SR04を使った距離計測(2018.04.14)
« micro:bitをArduino環境で使う (7) シリアル通信 | トップページ | アクティブマトリクス蛍光表示管の実験用表示モジュールの試用 (2) »

コメント