当前位置:网站首页>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 .
边栏推荐
猜你喜欢
C # character similarity comparison general class
[interested reading] advantageous filtering modeling on long term user behavior sequences for click through rate pre
【QT】制作MyComboBox点击事件
Flutter calls Gaode map app to realize location search, route planning and reverse geocoding
Two sides of the evening: tell me about the bloom filter and cuckoo filter? Application scenario? I'm confused..
A summary of the 8544 problem that SolidWorks Standard cannot obtain a license
19.Frambuffer应用编程
SQL injection - injection based on MSSQL (SQL Server)
[QT] timer
VB.net 简单的处理图片,黑白(类库——7)
随机推荐
力扣(LeetCode)184. 部门工资最高的员工(2022.07.03)
Zhongke Panyun - module a infrastructure setting and safety reinforcement scoring standard
IP时代来临,电竞酒店如何借好游戏的“东风”?
Viewing and using binary log of MySQL
Automated testing selenium foundation -- webdriverapi
Analysis of classical pointer and array written test questions in C language
Supplement the JS of a video website to decrypt the video
[wechat applet] template and configuration (wxml, wxss, global and page configuration, network data request)
Unity is connected to the weather system
VB. Net simple processing pictures, black and white (class library - 7)
LM小型可编程控制器软件(基于CoDeSys)笔记二十一:错误3703
How to use postman to realize simple interface Association [add, delete, modify and query]
[matlab] communication signal modulation general function - low pass filter
PostgreSQL has officially surpassed mysql. Is this guy too strong!
C语言简易学生管理系统(含源码)
EVM proof in appliedzkp zkevm (11)
2022危险化学品经营单位安全管理人员上岗证题库及答案
Write a complete answer applet (including single choice questions, judgment questions and multiple topics) (III) single choice questions, judgment questions, and the first question display
19.Frambuffer应用编程
小程序毕业设计---美食、菜谱小程序