linux直接写framebuffer linux 直接 对 Frame Buffer 操作,写画面缓存例子,c语言读写framebuffer

提供的中断调用来实现直接写屏,故Linux抽象出FrameBuffer这个设备来供用户态
  进程实现直接写屏。
  在继续下面的之前,先说明几个背景知识:
  1、FrameBuffer主要是根据VESA标准的实现的,所以只能实现最简单的功能。
  2、由于涉及内核的问题,FrameBuffer是不允许在系统起来后修改显示模式等一系
  列操作。(好象很多人都想要这样干,这是不被允许的,当然如果你自己与驱动
  的话,是可以实现的)
  3、对FrameBuffer的操作,会直接影响到本机的所有控制台的输出,包括XWIN的图
  形界面。


  好,现在可以让我们开始实现直接写屏:
  1、打开一个FrameBuffer设备
  2、通过mmap调用把显卡的物理内存空间映射到用户空间
  3、直接写内存。

//
// 这个程序是可以用的,在我的开发板上面编译通过,显示彩色
/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h> 
#include <linux/fb.h>
#include <time.h>
#include <sys/mman.h>
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;
long int location = 0;
fbfd = open("/dev/fb0", O_RDWR); // Open the file for reading and writing
if (!fbfd)
{
printf("Error: cannot open framebuffer device.\n");
exit(0);
}
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(0);
}


// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) 
{            
printf("Error reading variable information.\n");
exit(0);
}
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
        // 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(0);
}


printf("The framebuffer device was mapped to memory successfully.\n");
x = 100; y = 100;


// Where we are going to put the pixel   
// Figure out where in memory to put the pixel
for (y = 100; y < 300; y++)
for (x = 100; x < 300; 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

int b = 10;//assume 16bpp
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;
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,以下是一段用C语言的通过framebuffer控制LCD的程序示例: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include <linux/fb.h> #include <linux/kd.h> #define DEVICE_PATH "/dev/fb0" int main() { int fb_fd = open(DEVICE_PATH, O_RDWR); if (fb_fd < 0) { perror("Failed to open framebuffer device"); exit(EXIT_FAILURE); } struct fb_var_screeninfo vinfo; if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) { perror("Failed to get variable screen information"); exit(EXIT_FAILURE); } int xres = vinfo.xres; int yres = vinfo.yres; int bpp = vinfo.bits_per_pixel; size_t fb_size = xres * yres * bpp / 8; char *fbp = (char *) mmap(NULL, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); if (fbp == MAP_FAILED) { perror("Failed to mmap framebuffer device"); exit(EXIT_FAILURE); } int x, y; for (y = 0; y < yres; y++) { for (x = 0; x < xres; x++) { long int location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel / 8) + (y + vinfo.yoffset) * vinfo.bytes_per_line; if (bpp == 32) { // ARGB *(fbp + location + 0) = 0x00; // blue *(fbp + location + 1) = 0x00; // green *(fbp + location + 2) = 0xFF; // red *(fbp + location + 3) = 0x00; // alpha } else if (bpp == 16) { // RGB565 unsigned short int color = 0xF800; // red *((unsigned short int *)(fbp + location)) = color; } } } munmap(fbp, fb_size); close(fb_fd); return 0; } ``` 这段程序使用了Linux系统提供的framebuffer设备文件"/dev/fb0"来控制LCD显示。程序首先通过ioctl函数获取屏幕信息,包括分辨率、位深等。然后通过mmap函数将framebuffer映射到用户空间,之后就可以通过修改映射内存来改变LCD显示内容。 程序中的示例操作是将屏幕上所有像素点设置为蓝色(ARGB格式)或红色(RGB565格式),可以根据实际需求修改。值得注意的是,操作framebuffer需要有足够的权限,通常需要以root用户身份运行。 ### 回答2: 使用C语言通过framebuffer控制LCD的程序,可以通过以下步骤完成: 步骤1:打开framebuffer设备文件 首先,需要通过打开framebuffer设备文件与LCD屏幕进行交互。我们可以使用open()函数来打开设备文件,例如: int fbfd = open("/dev/fb0", O_RDWR); 步骤2:获取屏幕参数 获取LCD屏幕的信息,例如分辨率、色深等。可以使用ioctl()函数调用FBIOGET_VSCREENINFO命令获取,例如: struct fb_var_screeninfo vinfo; ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); 步骤3:映射framebuffer内存到用户空间 使用mmap()函数将LCD屏幕数据的物理内存映射到应用程序的用户空间,以便实现对屏幕的直接读写。例如: char *fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); 步骤4:绘制图像 使用C语言的图形绘制函数,例如直线、矩形、圆等,以及更高级的绘图库(如SDL、OpenGL等),在framebuffer上进行图像绘制。例如: for (y = 0; y < vinfo.yres; y++) { for (x = 0; x < vinfo.xres; x++) { location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + (y+vinfo.yoffset) * finfo.line_length; *(fbp + location) = 255; // 设置像素点的红色分量 *(fbp + location + 1) = 0; // 设置像素点的绿色分量 *(fbp + location + 2) = 0; // 设置像素点的蓝色分量 *(fbp + location + 3) = 0; // 设置像素点的透明度 } } 步骤5:刷新屏幕 在完成图像绘制后,需要调用刷屏函数,将缓冲区的图像数据刷新到LCD屏幕上。例如: ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo); 步骤6:关闭framebuffer设备文件 在程序结束时,需要关闭framebuffer设备文件,例如: munmap(fbp, screensize); close(fbfd); 通过上述步骤,使用C语言的程序即可通过framebuffer控制LCD屏幕,实现图像的显示和更新。请注意,具体实现可能需要根据不同的硬件平台和操作系统做相应的调整和修改。 ### 回答3: 使用C语言通过framebuffer控制LCD的程序需要以下步骤: 1. 打开framebuffer设备:首先需要打开framebuffer设备文件,一般位于/dev/fb0。可以使用open()函数来打开该设备文件,并获取文件描述符。 2. 获取设备可变参数:通过调用ioctl()函数获取framebuffer设备的可变参数,包括分辨率、像素格式、颜色位数等信息。这些参数会存储在一个结构体变量中,比如fb_var_screeninfo。 3. 分配内存缓冲区:根据设备分辨率和色彩格式,计算出所需的内存缓冲区大小,并使用malloc()函数分配足够的内存空间来存储图像数据。 4. 清空内存缓冲区:使用memset()函数将内存缓冲区清空为全黑色或全白色,以便在刚开始时显示正确的颜色。 5. 绘制图像数据:根据显示需求将需要显示的图像数据填充到内存缓冲区中。可以通过修改内存缓冲区的相应像素值来绘制图像。 6. 将图像数据刷新到屏幕:通过write()函数将内存缓冲区的图像数据framebuffer设备文件,从而实现将图像显示到屏幕上。 7. 关闭framebuffer设备:完成显示操作后,使用close()函数关闭framebuffer设备文件。 需要注意的是,具体的控制LCD的方式和步骤可能因LCD型号和设备驱动的不同而有所差异,上述步骤仅为一般情况的简单示意。在实际开发中,建议查阅相关LCD设备的文档和驱动代码,以便获取更准确的操作方法和参数设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值