今回もラズパイで遊んでみます。
この前、ラズパイ用の小型液晶ディスプレイを購入したのですが、下写真のように、やっぱりこのサイズではテキストの編集やGUIアプリの表示はあまり現実的ではありませんでした(´・ω・)
とはいえ、このまま封印するのも勿体ないので、少しでも遊びの自由度を広げるために、ディスプレイ表示を制御する方法を調べてみることにしました。
フレームバッファを叩けばOK
Linuxでは、デバイスの制御はデバイスファイルへのデータの読み書きで行います。例に漏れず、ディスプレイ表示の制御も専用のデバイスファイルとしてフレームバッファというものが用意されているので、このフレームバッファに対して読み書きをすればOKそうです。
ということで、さっそく以下のコマンドで適当な値をフレームバッファに書き込んでみます。ちなみに、ラズパイ上では「/dev/fb0」がデフォルトのフレームバッファになります。
コマンドを実行すると、ラズパイにつないだディスプレイの表示が変わりました。
ランダムな値を書き込んでいるので砂嵐のような表示になっていますが、ディスプレイの制御自体はできていそうです(・∀・)
プログラムから制御してみる
フレームバッファに書き込んで表示を制御できることは分かったので、次はプログラムから制御してみることにします。
まず、いまのディスプレイ設定をfbsetコマンドで調べます。
mode "480x320"
geometry 480 320 480 320 32
timings 0 0 0 0 0 0 0
rgba 8/16,8/8,8/0,8/24
endmode
この結果から解像度は480×320でデータはrgbaのフォーマットとなっていることが分かります。ここまで分かれば、後はなんとなく実装できそうなので、以下のようなプログラムを書いてみました。
#include <fcntl.h>
#define DEV_FB "/dev/fb0"
#define WIDTH 480
#define HEIGHT 320
int main(void) {
char blue[] = { 0xff, 0x00, 0x00, 0x00 };
char green[] = { 0x00, 0xff, 0x00, 0x00 };
char red[] = { 0x00, 0x00, 0xff, 0x00 };
int i, j;
int fb;
fb = open(DEV_FB, O_RDWR);
if(fb < 0) {
fprintf(stderr, "framebuffer open error\n");
return -1;
}
/* red */
for(i = 0; i < HEIGHT / 3; i++) {
for(j = 0; j < WIDTH; j++){
write(fb, red, sizeof(red));
}
}
/* green */
for(i = 0; i < HEIGHT / 3; i++) {
for(j = 0; j < WIDTH; j++){
write(fb, green, sizeof(green));
}
}
/* blue */
for(i = 0; i < HEIGHT / 3; i++) {
for(j = 0; j < WIDTH; j++){
write(fb, blue, sizeof(blue));
}
}
return 0;
}
単純に画面を縦方向に3分割し、赤・緑・青の順番でカラーバーを表示させるプログラムです。これを実行してみた結果がこんな感じです。
ちゃんと3色のカラーバーが表示できました(・∀・)こんなちょっとしたことでも期待通りに動いてくれると嬉しいですね。
高さがきれいに3等分できていないせいで一番下の列にゴミが残っていたり、コンソールのカーソル表示が残っていたりと雑なところはありますが、ひとまずやりたいことはできました。
もう少しちゃんとした制御ができるように、これからもう少し手を入れたいと思います。
ではではノシ