問題の認識
第一日目のEdisonアドベントカレンダーでは,MRAAライブラリを使ってLEDをチカチカ点灯させました.このときのIOアクセスを手段を詳しく見てみると,ポートをファイルデバイスとしてopenし,writeで書き込んでいることがわかります.
この方法だとポートの状態を変更するのに19.1[us]ほどかかるのですが,実はもっと早く,変更にかかる時間を0.4[us]ほどまで短縮できる方法があります.それが,ポートに対応するメモリを直接叩く方法です.Edisonは,マイコン等とは違いポートが直接メモリにマップされてはいないですが,このアクセス方法は有効なようです.このへんによると,実際は,100[MHz]で動作しているコプロセッサのQuarkでリアルタイムOSが動作して,IOを担当しているらしいです.そのため,IOはどんなに改善したとしても50[MHz]が限界なのだとか.
プログラム
#include <stdio.h>
#include <unistd.h>
#include <mraa.h>
int main(int argc, char *argv[])
{
mraa_init();
fprintf(stdout, "Hello mraa.\nVersion: %s\n", mraa_get_version());
mraa_gpio_context gpio;
gpio = mraa_gpio_init(20);
if(gpio == NULL){
return 1;
}
mraa_gpio_dir(gpio, MRAA_GPIO_OUT);
// FastIOの指定
mraa_gpio_use_mmaped(gpio, 1);
int i;
for(i=0;i<10;i++){
mraa_gpio_write(gpio, 1);
usleep(1000*1000);
mraa_gpio_write(gpio, 0);
usleep(1000*1000);
}
mraa_gpio_dir(gpio, MRAA_GPIO_IN);
mraa_deinit();
return ret;
}
$ gcc -lmraa -o led_fast led_fast.c
前回のコードと比べても,変わったところは,ポートの入出力を設定した後に, mraa_gpio_use_mmaped の関数を呼んでいるところだけです.この関数を呼んでおくと,mraa_gpio_write関数の中で,自動的にメモリを直接叩くようになります.
実験
いつものアクセス方法で叩いた動画.
メモリを直接叩いたほうの動画.
・・違い,よーわからんですな..
まとめ
- EdisonでFastIOを使うときは,mraa_gpio_use_mmapedを一度呼ぶだけでOK.