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の空きを確認(数値の増減がない)すれば問題ないかとおもいます。