当前位置:网站首页>19. Framebuffer application programming
19. Framebuffer application programming
2022-07-04 05:28:00 【anieoo】
stay Linux The display devices in the system are classified as framebuffer The device is the frame buffer device . For the application layer ,Linux The system LCD And other display devices are abstracted as a video memory buffer , Allow the upper application to read and write the video memory buffer directly , Don't worry about the physical address of the hardware , It greatly simplifies the speed and convenience of reading and writing .
One 、 Use ioctl Function to read the parameter information of the screen
Want to operate a piece LCD The screen , First of all, we must clearly understand the parameter information of the screen , Such as resolution and so on . In this way, the size of the display buffer should be calculated . Read information using ioctl function .
ioctl function
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
The first parameter fd For file descriptor
The second parameter is request, about LCD Commonly used for screens request Yes
FBIOGET_VSCREENINFO: obtain LCD Variable parameter information of
FBIOPUT_VSCREENINFO: Set up LCD Variable parameter information of
FBIOGET_FSCREENINFO: obtain LCD Invariant parameter information of
The third parameter is the structure that holds the information .
macro set The righteous FBIOGET_VSCREENINFO 、 FBIOPUT_VSCREENINFO 、
FBIOGET_FSCREENINFO as well as 2 Data structures struct fb_var_screeninfo and struct fb_fix_screeninfo It's all defined in <linux/fb.h> Header file
obtain LCD Screen information :
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
int main(int argc, char *argv[])
{
struct fb_fix_screeninfo fb_fix; // Save the fixed parameters of the screen
struct fb_var_screeninfo fb_var; // Save the variable parameters of the screen
int fd; // Save the file descriptor
// Check whether the command line parameters are correct
if(argc != 2) {
fprintf(stderr, "Error used!\n");
exit(-1);
}
// open LCD file
fd = open(argv[1], O_RDWR); // Read write mode on
if(fd < 0) {
perror("open failed!\n");
exit(-1);
}
/* Get parameter information */
ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);
ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix);
printf(" The resolution of the : %d*%d\n"
" Pixel depth bpp: %d\n"
" The number of bytes in a line : %d\n"
" Pixel format : R<%d %d> G<%d %d> B<%d %d>\n",
fb_var.xres, fb_var.yres, fb_var.bits_per_pixel,
fb_fix.line_length,
fb_var.red.offset, fb_var.red.length,
fb_var.green.offset, fb_var.green.length,
fb_var.blue.offset, fb_var.blue.length);
/* Close the device file and exit the program */
close(fd);
exit(0);
}
The operation results are as follows :
Two 、 Use mmap Function maps the display buffer to user space
about Framebuffer Programming is common I/O How to read and write , When the amount of data is large, it is inefficient and troublesome . Therefore, storage mapping is usually used I/O The display buffer of the display ( memory ) Map to the address space of the process , In this way, the application can directly read and write to the display buffer . Called by system mmap() To achieve . Its function prototype is as follows :
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
To use this function, you need to include a header file <sys/mman.h>.
Function parameters and return values have the following meanings :
addr: Parameters addr Used to specify the starting address mapped to the memory area . It is usually set to NULL, This means that the system selects the
The starting address of the mapping area , This is the most common setting method ; If parameters addr Not for NULL, It means that you specify the start of the mapping area by yourself
Address , The return value of this function is the starting address of the mapping area .
length: Parameters length Specify the mapping length , Indicates how much of the file is mapped to the memory area , In bytes , for example
length=1024 * 4, Indicates that the file will be 4K The byte size is mapped to the memory area .
offset: Offset of file mapping , It is usually set to 0, Indicates that the mapping starts from the header of the file ; So parameters offset And parameters length It determines the starting position and length of the file , Map this part of the file to the memory area
fd: File descriptor , Specify the file to map to the memory area .
prot: Parameters prot Specifies the protection requirements of the mapping area , The values are as follows :
PROT_EXEC: The mapping area can execute ;
PROT_READ: The mapping area is readable ;
PROT_WRITE: The mapping area is writable ;
PROT_NONE: The mapping area is not accessible .
flags: Parameters flags Multiple attributes that can affect the mapping area , Parameters flags You must specify one of the following two flags : MAP_SHARED: This flag specifies when data is written to the mapping area , The data is written to the file , That is, it will be written to the map
The data in the shooting area is updated to the file , And allow other processes to share .
MAP_PRIVATE: This flag specifies when data is written to the mapping area , A private copy of the mapping file will be created (copy-onwrite), Any operation on the mapping area will not be updated to the file , Just read and write a copy of the file .
besides , It is also possible to use the following symbols 0 Combine one or more parameters flags in , Combining by bitwise OR operator :
MAP_FIXED: If this flag is not specified , If parameters addr It's not equal to NULL, Indicates that the caller specifies
The starting address of the mapping area , But this is just a suggestion 、 Not mandatory , So the kernel does not guarantee the use of parameters addr designated
Value as the starting address of the mapping area ; If you specify MAP_FIXED sign , It means that the parameter... Must be used addr designated
Value as the starting address , If the mapping cannot be successfully established with the specified value , Give up ! Usually , This flag is not recommended , because
This is not conducive to transplantation .
MAP_ANONYMOUS: Set up anonymous mapping , The parameter is ignored fd and offset, There are no documents involved , And the mapping area
Cannot share with other processes .
MAP_ANON: And MAP_ANONYMOUS Symbol synonymy , Not recommended .
MAP_DENYWRITE: This flag is ignored .
MAP_EXECUTABLE: This flag is ignored .
MAP_FILE: Compatibility mark , Has been ignored .
MAP_LOCKED: Lock the mapping area .
In addition to the above marks , There are other signs , There will be no more introduction here , It can be done by man Check the manual . In many signs when
in , Usually , Parameters flags Only... Is specified in MAP_SHARED.
Return value : In case of success , The return value of the function is the starting address of the mapping area ; When something goes wrong , return (void *)-1, Usually use
MAP_FAILED To express , And it will set errno To indicate the cause of the error .
3、 ... and 、LCD Basic operation of application programming ( Draw lines, etc )
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
static int width; //LCD X The resolution of the
static int height; //LCD Y The resolution of the
static unsigned short *screen_base = NULL; // Mapped video memory base address
static void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color); // Drawing point function
static void lcd_draw_line(unsigned int x, unsigned int y, int dir,unsigned int length, unsigned int color);// Line drawing function
static void lcd_draw_rectangle(unsigned int start_x, unsigned int end_x,unsigned int start_y, unsigned int end_y,unsigned int color); // Draw a rectangular
static void lcd_fill(unsigned int start_x, unsigned int end_x,unsigned int start_y, unsigned int end_y,unsigned int color); // Filled rectangle
unsigned int argb8888_to_rgb565(unsigned int color); //RGB88 to RGB565
int main(int argc, char *argv[])
{
struct fb_fix_screeninfo fb_fix; // Save the unchanged parameters of the screen
struct fb_var_screeninfo fb_var; // Save the variable parameters of the screen
unsigned int screen_size;
int fd;
if(argc != 2) {
fprintf(stderr, "Erroe used!\n");
exit(-1);
}
fd = open(argv[1], O_RDWR);
if(fd < 0) {
perror("open failed!\n");
exit(-1);
}
/* Get parameter information */
ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);
ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix);
/* Calculate screen size */
screen_size = fb_fix.line_length * fb_var.yres;
width = fb_var.xres;
height = fb_var.yres;
printf("width = %d,height = %d\n",width,height);
/* Map the display buffer to user space */
screen_base = mmap(NULL, screen_size, PROT_WRITE, MAP_SHARED, fd, 0);
if ((void *)screen_base == MAP_FAILED) {
perror("mmap error");
close(fd);
exit(-1);
}
/* Draw line : Crosshairs */
lcd_draw_line(0, height * 0.5, 1, width, 0xFFFFFF);// The white line
lcd_draw_line(width * 0.5, 0, 0, height, 0xFFFFFF);// The white line
/* sign out */
munmap(screen_base, screen_size); // Unmap
close(fd); // Close file
exit(0); // Withdraw from the process
}
unsigned int argb8888_to_rgb565(unsigned int color)
{
unsigned int temp = (color);
temp = (temp & 0xF80000UL) >> 8 | (temp & 0xFC00UL) >> 5 | (temp & 0xF8UL) >> 3;
return temp;
}
static void lcd_draw_point(unsigned int x, unsigned int y, unsigned int color)
{
unsigned short rgb565_color = argb8888_to_rgb565(color);// obtain RGB565 Color value
/* Verification of incoming parameters */
if (x >= width)
x = width - 1;
if (y >= height)
y = height - 1;
/* Fill color */
screen_base[y * width + x] = rgb565_color;
}
static void lcd_draw_line(unsigned int x, unsigned int y, int dir,unsigned int length, unsigned int color)
{
unsigned short rgb565_color = argb8888_to_rgb565(color);// obtain RGB565 Color value
unsigned int end;
unsigned long temp;
/* Verification of incoming parameters */
if (x >= width)
x = width - 1;
if (y >= height)
y = height - 1;
/* Fill color */
temp = y * width + x;// Go to the starting point
if (dir) { // Level
end = x + length - 1;
if (end >= width)
end = width - 1;
for ( ; x <= end; x++, temp++)
screen_base[temp] = rgb565_color;
}
else { // Vertical line
end = y + length - 1;
if (end >= height)
end = height - 1;
for ( ; y <= end; y++, temp += width)
screen_base[temp] = rgb565_color;
}
}
static void lcd_draw_rectangle(unsigned int start_x, unsigned int end_x,
unsigned int start_y, unsigned int end_y,
unsigned int color)
{
int x_len = end_x - start_x + 1;
int y_len = end_y - start_y - 1;
lcd_draw_line(start_x, start_y, 1, x_len, color);// above
lcd_draw_line(start_x, end_y, 1, x_len, color); // Underside
lcd_draw_line(start_x, start_y + 1, 0, y_len, color);// On the left
lcd_draw_line(end_x, start_y + 1, 0, y_len, color);// On the right
}
static void lcd_fill(unsigned int start_x, unsigned int end_x,
unsigned int start_y, unsigned int end_y,
unsigned int color)
{
unsigned short rgb565_color = argb8888_to_rgb565(color);// obtain RGB565 Color value
unsigned long temp;
unsigned int x;
/* Verification of incoming parameters */
if (end_x >= width)
end_x = width - 1;
if (end_y >= height)
end_y = height - 1;
/* Fill color */
temp = start_y * width; // Go to the beginning of the line
for ( ; start_y <= end_y; start_y++, temp+=width) {
for (x = start_x; x <= end_x; x++)
screen_base[temp + x] = rgb565_color;
}
}
Code flow :
First call open() open LCD Device files get file descriptors fd;
Then use ioctl Function to obtain LCD Variable parameter information and fixed parameter information , Calculate through the obtained information LCD Memory size 、 obtain LCD The resolution of the screen , From the picture 19.3.1 You know , ALPHA/Mini I.MX6U The development board factory system will LCD Implemented as a RGB565 Display device , So it is customized in the program 4 A function is operating LCD Pixels 、 It's all about RGB565 Write color values in the format of .
Then use mmap Building mapping ;
After the mapping is successful, you can operate directly in the application layer LCD Video memory , Call the custom function in LCD Draw a line
After the operation , call munmap Unmap , call close close LCD Device file , Exit procedure .
边栏推荐
- Etcd database source code analysis - initialization overview
- Two sides of the evening: tell me about the bloom filter and cuckoo filter? Application scenario? I'm confused..
- Notepad++ -- display related configurations
- Risc-v-qemu-virt in FreeRTOS_ Lock mechanism analysis of GCC
- Introduction to AMBA
- SQL performance optimization skills
- 2022G2电站锅炉司炉特种作业证考试题库及答案
- LM小型可编程控制器软件(基于CoDeSys)笔记二十二:错误4268/4052
- PostgreSQL has officially surpassed mysql. Is this guy too strong!
- Zkevm (12) state proof of appliedzkp
猜你喜欢
Simulated small root pile
Just do it with your hands 7 - * project construction details 2 - hook configuration
LM small programmable controller software (based on CoDeSys) note 22: error 4268/4052
[paper summary] zero shot semantic segmentation
LabVIEW错误对话框的出现
[technology development -25]: integration technology of radio and television network, Internet, telecommunication network and power grid
C # character similarity comparison general class
2022g2 power station boiler stoker special operation certificate examination question bank and answers
What are the reasons for the frequent high CPU of ECS?
Appearance of LabVIEW error dialog box
随机推荐
LC weekly 300
LM small programmable controller software (based on CoDeSys) note 22: error 4268/4052
Simulated small root pile
Simulink and Arduino serial port communication
1480. 一维数组的动态和
【QT】定时器
C语言简易学生管理系统(含源码)
Evolution of system architecture: differences and connections between SOA and microservice architecture
(4) Canal multi instance use
2022危险化学品经营单位安全管理人员上岗证题库及答案
VB. Net calls ffmpeg to simply process video (class Library-6)
2022年A特种设备相关管理(电梯)考试题模拟考试平台操作
Flutter ‘/usr/lib/libswiftCore. dylib‘ (no such file)
flink1.13 sql基础语法(二)join操作
Exercise bubble sort
Easy change
数据标注是一块肥肉,盯上这块肉的不止中国丨曼孚科技
Appearance of LabVIEW error dialog box
With the advent of the IP era, how can E-sports hotels take advantage of the "east wind" of games?
远程桌面客户端 RDP