フォト
2018年11月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
無料ブログはココログ

« micro:bitをArduino環境で使う (7) シリアル通信 | トップページ | アクティブマトリクス蛍光表示管の実験用表示モジュールの試用 (2) »

2018年2月11日 (日)

豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応

豊四季Tiny BASIC for Arduino(オリジナル版)のSRAM消費を軽減する修正を行ってみました。

Arduino UNOでは、SRAMが2kバイトしかありません。
オリジナル版のまま利用した場合、グローバル変数が1481バイト(72%)を利用しており、
残りが567バイトです。機能拡張するにはちょっと辛いです。

そこで、キーワード、エラーメッセージ等のグローバルな固定データをフラッシュメモリ上に
配置する修正をおこない、SRAMの消費を少々押さえました。

参考にしたサイト

・Arduinoで遊ぶページ - Arduino Uno編 - メモリの種類
・武蔵野電波 - Arduino 日本語リファレンス - PROGMEMとFマクロ
・Arduino - PROGMEM

良く知られているテクニックですが、
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])));

ARM cortex-M系のgccでは、constキーワードを付ければ、
フラッシュメモリ上に配置してくれて、かつ参照はSRAMと同等に行えるのと比べると
ちょっと面倒ですね。

とりあえず、この修正によりSRAM消費量を712バイト抑えることが出来ました。
SRAMは1279バイトほど余っているので、ちょっとした機能追加は出来ると思います。

もしかしたら、もっと効率の良いやり方があるかもしれませんが、これで良しとします。

Arduino IDE 1.8.15

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

ttbasic

この修正版は、下記にて公開いたいます。
https://github.com/Tamakichi/ttbasic_arduino_uno


« micro:bitをArduino環境で使う (7) シリアル通信 | トップページ | アクティブマトリクス蛍光表示管の実験用表示モジュールの試用 (2) »

arduino」カテゴリの記事

AVR」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/571408/66382522

この記事へのトラックバック一覧です: 豊四季Tiny BASIC for ArduinoのSRAM消費軽減対応:

« micro:bitをArduino環境で使う (7) シリアル通信 | トップページ | アクティブマトリクス蛍光表示管の実験用表示モジュールの試用 (2) »