I. Basic usage of framebuffer:
1. linux is working in the protection mode, so user-mode processes cannot use the interrupt call provided in the graphics card BIOS as DOS to achieve direct screen writing, linux abstracts the framebuffer device for the user-state process to directly write the screen. For users, there is no difference between framebuffer and other devices under/dev. Users can regard framebuffer as a piece of memory, which can write data to this piece of memory, you can also read data from this memory. In application programs, it is generally used by ing the framebuffer device to the process address space.
2. In this mechanism, although framebuffer requires the support of a real video card driver, all the display tasks are completed by the CPU, so the CPU burden is very heavy.
3. The PCI device can map its own control registers to the physical memory space. Then, access to these control registers becomes access to the physical memory. Therefore, these registers are also called "memio ". Once mapped to the physical memory, common processes in Linux can map these memory I/O to the process address space through MMAP, so that these registers can be directly accessed.
4. The frame buffer device is a character device and adopts the "file layer-driver layer" interface. Linux defines the driver layer interface for the frame buffer device as the struct fb_info structure. At the file level, the user calls the struct file_operations function operation, and indirectly calls the struct fb_ops function to operate the hardware. when you register an FB device with the kernel, you also register the pointer of struct fb_ops. when the FB device is enabled, call xxxfb_init () of fb_drivers [] to initialize the device;
5. The minor of the first registered framebuffer is equal to 0, the minor of the second registered framebuffer is equal to 1, and so on. For example,/dev/fb0,/dev/Fb1.
Run the following command: # dd If =/dev/Zero of =/dev/FB to clear the screen.
If the display mode is 1024x7688-bit, run the command $ dd If =/dev/Zero of =/dev/fb0 BS = 1024 COUNT = 768.
Run the following command to clear the screen: # dd If =/dev/FB of = fbfile to save the content in FB;
You can write back the screen: # dd If = fbfile of =/dev/FB
Ii. Internal Structure of framebuffer:
The source file of framebuffer is in the Linux/Drivers/Video/directory. The total abstract device file is fbcon. C, which contains the source files related to various graphics/card drivers. The framebuffer device driver is based on the following files:
1) Linux/include/Linux/FB. h defines some variable structures and macros.
2) Linux/Drivers/Video/fbmem. c implements device entry and initialization.
3) xxxfb. C: the device driver file added by yourself, such as struct fb_info; implements the entry point function: xxxfb_init; xxxfb_setup;
1. First, FB. h. The framebuffer device relies heavily on the following data structure.
1). struct fb_var_screeninfo describes the features of the graphics card. It is usually set by the user.
2). struct fb_fix_screeninfo defines the hardware features of the graphics card and cannot be changed.
3). struct fb_cmap describes device-independent color ing information. You can use the ioctl operation corresponding to fbiogetcmap and fbioputcmap to set or obtain
Color ing information.
4). struct fb_info defines the status of the framebuffer device of the current graphics card. A graphics card may have two framebuffers. In this case, two
Fb_info structure. This structure is only visible in the kernel space. In this structure, there is an fb_ops pointer pointing to the function set required for the driver to work.
5). the struct fb_ops user application can use the ioctl () System Call to operate the device. This structure is used to support the ioctl () operations. (Note: fb_ops
The structure is different from the file_operations structure. fb_ops is the abstraction of underlying operations, while file_operations is the interface provided for upper-level system calls and can be directly called.
The.) IOCTL () system call is implemented in the file fbmem. C. We can observe the relationship between the ioctl () Command and the function in fb_ops's:
Fbioget_vscreeninfo fb_get_var
Fbioput_vscreeninfo fb_set_var
Fbioget_fscreeninfo fb_get_fix
Fbioputcmap fb_set_cmap
Fbiogetcmap fb_get_cmap
Fbiopan_display fb_pan_display
If we define the fb_xxx_xxx method, the user program can use the ioctl () Operation of the fbioxxxx macro to operate the hardware.
2. fbmem. C. Fbmem. C is in the center of the framebuffer Device Driver technology. it provides system calls for upper-layer applications and interfaces for specific hardware drivers at the next layer. These underlying hardware drivers need to use these interfaces to register themselves with the system kernel. fbmem. C provides common interfaces for all device drivers that support framebuffer.
1) global variables
Struct fb_info * registered_fb [fb_max];
Int num_registered_fb;
These two variables record all the instances of the fb_info structure. The fb_info Structure describes the current status of the video card. The fb_info structure of all devices is stored in
In this array, when a framebuffer Device Driver registers itself with the system, its corresponding fb_info structure will be added to this structure.
Num_registered_fb automatically adds 1.
2) fbmem. c implements the following functions.
Register_framebuffer (struct fb_info * fb_info );
Unregister_framebuffer (struct fb_info * fb_info );
These two interfaces are provided to the underlying framebuffer device drivers. The device drivers use these two functions to register or deregister themselves with the system. Drivers of almost underlying Devices
All you need to do is fill in the fb_info structure and register or deregister it with the system.
3. xxxfb. C. The driver file added by yourself, such as the following.
Static struct fb_ops xxxfb_ops = {
Owner: this_module,
Fb_open: xxxfb_open,
/* Only if you need it to do something */
Fb_release: xxxfb_release,/* only if you need it to do something */
Fb_get_fix: fbgen_get_fix,
Fb_get_var: fbgen_get_var,
Fb_set_var: fbgen_set_var,
Fb_get_cmap: fbgen_get_cmap,
Fb_set_cmap: fbgen_set_cmap,
Fb_pan_display: fbgen_pan_display,
Fb_ioctl: xxxfb_ioctl,/* optional */
};
Iii. framebuffer DRIVER:
1. First, add the following code to fbmem. C.
Static struct {
Const char * Name;
INT (* init) (void );
INT (* setup) (char *);
}
Fb_drivers [] _ initdata = {
# Ifdef config_fb_yourcard // Add part in red
{"Driver_name", xxxfb_init, xxxfb_setup },
# Endif
2. In xxxfb. C, re-allocate the memory size as needed. For example:
# Define videomemsize (1*1024*1024)/* 1 MB */
Modify the corresponding var information based on your hardware device. Major changes
Xxxfb_set_var (struct fb_var_screeninfo * var, int con, struct fb_info * info)
The following are the execution steps of the function fb_set_var:
1) check whether the mode must be set
2) set the Mode
3) set color ing
4) reset the registers of the LCD controller according to the previous settings.
4. Configure and add a driver:
1. When making menuconfig, first enter character devices and select virtualterminal in it. If you want the console to be output on the LCD, select support for console on virtual terminal.
2. Go back to the previous page and we can see the options of the console device. After Entering, place the cursor on framebuffer support, press the Enter key to enter, and select the required framebuffer device.
3. In advanced low level, you can configure BPP packed pixel support and select selectcompiled-in fonts.
After the operating system runs, you will see the FB device under/dev. Its major should be 29, and the minor of the first device should be 0.
V. Others:
When compiling the kernel, select the framebuffer mode. When starting, there is a penguin picture on the screen. I wonder how this picture can be removed or changed?
A: You can remove the IF (logo) {} code in drivers/Video/fbcon. C: fbcon_setup.
6. perform the following steps to operate framebuffer:
1. Open an available framebuffer device;
2. Map the physical memory space of the video card to the user space through MMAP calls;
3. Change and display the pixel data in the memory space;
4. Disable the framebuffer device when exiting.
The following example draws a gradient progress bar using framebuffer. The Code framebuf. C is as follows:
# Include <unistd. h>
# Include <stdio. h>
# Include <fcntl. h>
# Include <Linux/FB. h>
# Include <sys/Mman. h>
Inline static unsigned short int make16color (unsigned char R, unsigned char g, unsigned char B)
{
Return (r> 3) & 31) <11) | (G> 2) & 63) <5) | (B> 3) & 31 ));
}
Int main (){
Int fbfd = 0;
Struct fb_var_screeninfo vinfo;
Struct fb_fix_screeninfo finfo;
Long int screensize = 0;
Char * FBP = 0;
Int x = 0, y = 0;
Int guage_height = 20, step = 10;
Long int location = 0;
// Open the file for reading and writing
Fbfd = open ("/dev/graphics/fb0", o_rdwr );
If (! Fbfd ){
Printf ("error: cannot open framebuffer device. \ n ");
Exit (1 );
}
Printf ("The framebuffer device was opened successfully. \ n ");
// Get 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 );
}
Printf ("sizeof (unsigned short) = % d \ n", sizeof (unsigned short ));
Printf ("% DX % d, % dbpp \ n", vinfo. xres, vinfo. yres, vinfo. bits_per_pixel );
Printf ("xoffset: % d, yoffset: % d, line_length: % d \ n", vinfo. xoffset, vinfo. yoffset, finfo. line_length );
// 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, screensize, 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 ("The framebuffer device was mapped to memory successfully. \ n ");
// Set to black color first
Memset (FBP, 0, screensize );
// Draw rectangle
Y = (vinfo. yres-guage_height)/2-2; // where we are going to put the pixel
For (x = Step-2; x <vinfo. xres-step + 2; X ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) + (Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
Y = (vinfo. yres + guage_height)/2 + 2; // where we are going to put the pixel
For (x = Step-2; x <vinfo. xres-step + 2; X ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) + (Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
X = Step-2;
For (y = (vinfo. yres-guage_height)/2-2; y <(vinfo. yres + guage_height)/2 + 2; y ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) + (Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
X = vinfo. xres-step + 2;
For (y = (vinfo. yres-guage_height)/2-2; y <(vinfo. yres + guage_height)/2 + 2; y ++ ){
Location = (x + vinfo. xoffset) * (vinfo. bits_per_pixel/8) + (Y + vinfo. yoffset) * finfo. line_length;
* (Unsigned short int *) (FBP + location) = 255;
}
// Figure out where in memory to put the pixel
For (x = step; x <vinfo. xres-step; X ++ ){
For (y = (vinfo. yres-guage_height)/2; y <(vinfo. yres + guage_height)/2; y ++ ){
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
Unsigned char B = 255 * x/(vinfo. xres-step );
Unsigned char G = 255; // (X-100)/6 a little green
Unsigned char r = 255; // a lot of red
Unsigned short int T = make16color (R, G, B );
* (Unsigned short int *) (FBP + location) = T;
}
}
// Printf ("x = % d, temp = % d \ n", X, temp );
// Sleep to see it
Usleep (200 );
}
// Clean framebuffer
Munmap (FBP, screensize );
Close (fbfd );
Return 0;
}
Copy code
Note: In the android environment, the framebuffer device is not like/dev/fb0 in Linux, but/dev/graphics/fb0,
Fbfd = open ("/dev/graphics/fb0", o_rdwr );
Enable the framebuffer device,
FBP = (char *) MMAP (0, screensize, prot_read | prot_write, map_shared,
Fbfd, 0 );
Map the device to a memory, and then you can operate on the memory space to display the image you want to draw.
Don't forget to close the device:
Munmap (FBP, screensize );
Close (fbfd );
As follows:
Copy search
Copy search