画面上の特定のピクセルの色に応じて RGB LED の色を制御する小さなプログラムを作成しようとしています。これは Raspbmc を実行している Raspberry Pi 上にあるため、すべてがフレーム バッファーから描画されるため、XLib を使用できません (これが正しいかどうかはわかりませんが、FAQ を読んだところ、これが当てはまるようです)。XLib を使用してみましたが、ディスプレイを検出できませんでした (現在動作しない理由は理にかなっています)。
これは私がオンラインで見つけた例です。問題は、コンパイルは正常に行われますが、実行すると 2 番目のエラー メッセージ「固定情報の読み取りエラー」が表示されることです。fbfd の内容を表示しようとしましたが、セグメンテーション エラーが発生します。では、fbfd には何も書き込まれていないように見えますか?
フレームバッファについて見つけたものはすべて基本的にこれと同じコードであるため、意味がわかりません。なぜ機能しないのかわかりません。
誰かが助けてくれることを願っています!
#include <unistd.h>
#include <fcntl.h> /* for fcntl */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h> /* for mmap */
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
long int screensize = 0;
int fbfd =0; /* frame buffer file descriptor */
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
char* fbp; /* pointer to framebuffer */
int location; /* iterate to location */
int x, y; /* x and y location */
/* open the file for reading and writing */
fbfd = open("/dev/fb0", O_RDWR);
//printf("%s\n",fbfd);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
printf ("The framebuffer device was opened successfully.\n");
/* get the fixed screen information */
if (ioctl (fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
/* get variable screen information */
if (ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
exit(3);
}
/* figure out the size of the screen in bytes */
//screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
/* map the device to memory */
fbp = (char*)mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
if ((int)fbp == -1) {
printf ("Error: failed to map framebuffer device to memory.\n");
exit(4);
}
printf ("Framebuffer device was mapped to memory successfully.\n");
// Figure out where in memory to put the pixel
for ( y = 0; y < (vinfo.yres/2); y++ )
for ( x = 0; x < vinfo.xres; x++ ) {
location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length;
if ( vinfo.bits_per_pixel == 32 ) {
*(fbp + location) = 100; // Some blue
*(fbp + location + 1) = 15+(x-100)/2; // A little green
*(fbp + location + 2) = 200-(y-100)/5; // A lot of red
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
int b = 10; int g = (x-100)/6; // A little green
int r = 31-(y-100)/16; // A lot of red
unsigned short int t = r<<11 | g << 5 | b;
*((unsigned short int*)(fbp + location)) = t;
}
}
munmap(fbp, screensize);
close(fbfd);
return 0;
}