What is framebuffer ?
The Linux framebuffer is an abstraction layer, hardware independant, to display
graphical elements in Linux console. Framebuffer is often used in embedded
devices. Thanks to DirectFB
, hadware acceleration can be used.
How to program framebuffer ?
Programming the Linux framebuffer is quite simple:
ioctl
commands and structs are located in/usr/include/linux/fb.h
- use
open(2)
to open/dev/fb0
- use various
ioctl(2)
calls to get or set properties mmap(2)
framebuffer device to memory- write to the mmaped memory to display your graphics
Usefull structs are:
struct fb_var_screeninfo; /* Get variable screen informations with FBIOGET_VSCREENINFO */
struct fb_fix_screeninfo; /* Get fixed screen informations with FBIOGET_FSCREENINFO */
A simple program
Return codes are not checked for simplicity.
Includes:
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
First, open the framebuffer device,
int fbfd;
fbfd = open("/dev/fb0", O_RDWR);
Get various screen informations with ioctl
,
static struct fb_fix_screeninfo finfo;
static struct fb_var_screeninfo vinfo;
ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo);
ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo);
fprintf(stdout, "Fixed screen informations\n"
"-------------------------\n"
"Id string: %s\n"
"FB start memory: %p\n",
finfo.id, (void *)finfo.smem_start);
fprintf(stdout, "Variable screen informations\n"
"----------------------------\n"
"xres: %d\n"
"yres: %d\n"
"xres_virtual: %d\n"
"yres_virtual: %d\n"
"bits_per_pixel: %d\n",
vinfo.xres, vinfo.yres, vinfo.xres_virtual,
vinfo.yres_virtual, vinfo.bits_per_pixel);
Mmap framebuffer device,
screen_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
fbp = mmap(NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
Yon can now draw a green rectangle in console mode
int x = 20; int y = 20; /* Upper left corner */
int w = 40; int h = 60; /* Width and height */
for (int j = 0; j < h; ++j) {
for (int i = 0; i < w; ++i) {
unsigned char *p;
p = fbp + ((y + j) * vinfo.xres + (x + i)) * vinfo.bits_per_pixel/8;
/* We consider a 32 bits per pixels */
p[0] = 0; /* blue */
p[1] = 255; /* green */
p[2] = 0; /* red */
p[3] = 0; /* alpha */
}
}
Do not forget to release allocated resources,
munmap(fbp, 0);
close(fbfd);