Arduino先読みプログラム Malloc,Freeram,Qsort,bserch
スタンドアローンのMIDIeventプロセッサーを作っていたとき、データをi2cメモリに置いていました。完成後Ramが余っていましたのでデータを先読みできないか試してみました。その時の覚書です。
なお今回は先読みプログラムの大枠ですのでi2c読み込み、midi関連等省略して書いています。malloc、freeram、qsort、bserchのサンプルです。このまま実行してもあまり意味がありません。
想定としてはmallocで確保した領域にデータ保管>MidiFootSwのプログラムチェンジを受け取とる>データがあればi2c読込データを付加してMIDI発砲>プログラムチェンジNoをもとにそのNo前後のデータをi2cより読込malloc領域にデータのコピー作成>以下繰り返し
bserchは順番通りでないと調べられないので検索用の配列をQsortで作ります。ここであればMalloc領域から読込、なければi2cから読込をします。
#include <stdlib.h> byte preary[320];/* 64*5 */ int ansaryS[5]; int *pItem; boolean dataOk = true; byte inpn=0; /*incoming prognumber*/ int freeRam () { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); } int compareints (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } void setup() { Serial.begin(9600); inpn = 0; } void loop() { byte *preary = (byte*)malloc(320); if (preary == NULL) { /*領域確保失敗*/ }else{ /*inpnをもとに使うデータをi2cMemなどからprearyに書き込み今回は手抜きで10*/ for(int i = 0 ; i < 320; i++) { preary[i]= 10; } /*i2cなどから読み込んだ時の番地アドレスを配列にする今回は手抜き*/ ansaryS[0] = 126; ansaryS[1] = 127; ansaryS[2] = 0;/*inpn*/ ansaryS[3] = 1; ansaryS[4] = 2; /*Program Change*/ qsort (ansaryS, 5, sizeof (int), compareints); /***確保後の空き容量確認****/ Serial.print("malloc:"); Serial.print(freeRam()); /***/ dataOk = true; } do{ /*midi ProgramChangeを受け取る今回は手抜きでinpn=0*/ /*inpn = 受け取ったPGnumber*/ pItem =(int*) bsearch (&inpn, ansaryS, 5, sizeof (int), compareints); if (pItem != NULL){ /*prearyから読込*/ } else { /*i2cから読込*/ } /*読込データをMIDI Send*/ dataOk = false; } while (dataOk == true); free(preary); /**確認 **/ Serial.print(" free:"); Serial.println(freeRam()); delay(1000); /***/ }
Arduinoではmallocを嫌うプログラマーも多いようですが、freeramでramの空きを確認(数値の増減がない)すれば問題ないかとおもいます。