Linux 应用基础 Framebuffer应用编程

简介: 在 Linux应用基础中,Framebuffer 驱动程序主要用来控制 LCD。今天带大家来了解一下如何通过 Framebuffer 来编程 LCD。在此之前,我们要先了解一下 Framebuffer 和 LCD。

前言


在 Linux应用基础中,Framebuffer 驱动程序主要用来控制 LCD。今天带大家来了解一下如何通过 Framebuffer 来编程 LCD。

在此之前,我们要先了解一下 Framebuffer 和 LCD。


一、了解Framebuffer


Frame是帧的意思,buffer是缓冲的意思,这意味着 Framebuffer 就是一块内存,里面保存着一帧图像。Framebuffer 中保存着一帧图像的每一个像素颜色值,假设LCD的分辨率是1024x768,每一个像素的颜色用32位来表示,那么Framebuffer的大小就是:1024x768x32/8=3145728字节。


二、了解LCD


1.LCD的操作原理


① 根据LCD分辨率、BPP分配Framebuffer

② APP使用ioctl获得LCD分辨率、BPP

③ APP通过mmap映射Framebuffer,在Framebuffer中写入数据


2.LCD坐标

1879f22b89ba737512dbafd66c5580f.png



假设 fb_base 是APP执行 mmap 后得到的Framebuffer地址,可以用以下公式算出(x,y)坐标处像素对应的Framebuffer地址:

(x,y)像素起始地址=fb_base + (xres*bpp/8) * y + x * bpp / 8


三. Framebuffer 程序分析


1. 打开设备:(open)


open (const char pathname, int flags) ;

pathname: 表示打开文件的路径。


73      fd_fb = open("/dev/fb0", O_RDWR);
74      if (fd_fb < 0)
75      {
76              printf("can't open /dev/fb0\n");
77              return -1;
78      }


fd_fb: 打开 LCD 设备返回的文件句柄。

/dev/fb0 :LCD的设备节点。

Flags表示打开文件的方式。


2. 获取LCD参数 : ( ioctl )


ioctl ( int fd, unsigned long request, …);

fd : 文件句柄。


12 static struct fb_var_screeninfo var; /* Current var */
……
79      if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
80      {
81              printf("can't get var\n");
82              return -1;
83      }


FBIOGET_VSCREENINFO : 它表示get var screen info,获得屏幕的可变信息.

获取 lcd 屏幕的信息,并将其存放在 var 结构体中。以下是 var 结构体:


struct fb_var_screeninfo {
  __u32 xres;   /* visible resolution  */
  __u32 yres;
  __u32 xres_virtual;  /* virtual resolution  */
  __u32 yres_virtual;
  __u32 xoffset;    /* offset from virtual to visible */
  __u32 yoffset;    /* resolution   */
  __u32 bits_per_pixel;  /* guess what    */
  __u32 grayscale;  /* 0 = color, 1 = grayscale,  */
      /* >1 = FOURCC    */
  struct fb_bitfield red;  /* bitfield in fb mem if true color, */
  struct fb_bitfield green; /* else only length is significant */
  struct fb_bitfield blue;
  struct fb_bitfield transp;  /* transparency   */  
  __u32 nonstd;   /* != 0 Non standard pixel format */
  __u32 activate;   /* see FB_ACTIVATE_*  */
  __u32 height;   /* height of picture in mm    */
  __u32 width;    /* width of picture in mm     */
  __u32 accel_flags;  /* (OBSOLETE) see fb_info.flags */
  /* Timing: All values in pixclocks, except pixclock (of course) */
  __u32 pixclock;   /* pixel clock in ps (pico seconds) */
  __u32 left_margin;  /* time from sync to picture  */
  __u32 right_margin;  /* time from picture to sync */
  __u32 upper_margin;  /* time from sync to picture */
  __u32 lower_margin;
  __u32 hsync_len;  /* length of horizontal sync  */
  __u32 vsync_len;  /* length of vertical sync  */
  __u32 sync;   /* see FB_SYNC_*  */
  __u32 vmode;    /* see FB_VMODE_*  */
  __u32 rotate;   /* angle we rotate counter clockwise */
  __u32 colorspace;  /* colorspace for FOURCC-based modes */
  __u32 reserved[4];  /* Reserved for future compatibility */
};



3. 映射 framebuffer: ( mmap )

void *mmap ( void *addr, size_t length, int prot, int flags, int fd, off_t offset);


要映射一块内存,需要知道它的地址──这由驱动程序来设置,需要知道它的大小──这由应用程序决定。


85      line_width  = var.xres * var.bits_per_pixel / 8;
86      pixel_width = var.bits_per_pixel / 8;
87      screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
88      fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
89      if (fb_base == (unsigned char *)-1)
90      {
91              printf("can't mmap\n");
92              return -1;
93      }


screen_size : 代表整个 framebuffer 的大小。

fb_base : framebuffer 是存在于驱动程序中的,在应用程序中无法使用。则需要使用 mmap 将驱动程序的内存映射到应用程序中。


四. 描点函数: ( lcd_put_pixel )


大家在 lcd 上显示字符时,需要进行描点。pen_8,pen_16,pen_32都是起笔点。不同的只需要将pen_8变换一下即可。

void lcd_put_pixel(int x, int y, unsigned int color)
{
  unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;
  unsigned short *pen_16; 
  unsigned int *pen_32; 
  unsigned int red, green, blue;  
  pen_16 = (unsigned short *)pen_8;
  pen_32 = (unsigned int *)pen_8;
  switch (var.bits_per_pixel)
  {
  case 8:
  {
    *pen_8 = color;
    break;
  }
  case 16:
  {
    /* 565 */
    red   = (color >> 16) & 0xff;
    green = (color >> 8) & 0xff;
    blue  = (color >> 0) & 0xff;
    color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
    *pen_16 = color;
    break;
  }
  case 32:
  {
    *pen_32 = color;
    break;
  }
  default:
  {
    printf("can't surport %dbpp\n", var.bits_per_pixel);
    break;
  }
  }
}



相关文章
|
11天前
|
安全 Linux
Linux通配符及其在文件搜索和管理中的应用
Linux通配符及其在文件搜索和管理中的应用
|
7天前
|
存储 数据管理 Linux
Linux命令sg的深入解析与应用
**Linux的`sg`命令用于高效管理SCSI设备,它基于DMA和Scatter-Gather技术,提供直接设备控制和高效数据传输。`sg`常通过`sg3_utils`工具集来使用,例如`sg_io`,用于执行SCSI命令。在实际应用中,需注意权限、数据安全和兼容性问题,遵循备份、详细阅读文档和逐步测试的最佳实践。**
|
9天前
|
Linux 网络安全 开发工具
linux 常用命令【编程必备】
linux 常用命令【编程必备】
23 4
|
10天前
|
小程序 Linux
【编程小实验】利用Linux fork()与文件I/O:父进程与子进程协同实现高效cp命令(前半文件与后半文件并行复制)
这个小程序是在文件IO的基础上去结合父子进程的一个使用,利用父子进程相互独立的特点实现对数据不同的操作
|
10天前
|
缓存 网络协议 算法
【Linux系统编程】深入剖析:四大IO模型机制与应用(阻塞、非阻塞、多路复用、信号驱动IO 全解读)
在Linux环境下,主要存在四种IO模型,它们分别是阻塞IO(Blocking IO)、非阻塞IO(Non-blocking IO)、IO多路复用(I/O Multiplexing)和异步IO(Asynchronous IO)。下面我将逐一介绍这些模型的定义:
|
12天前
|
安全 数据挖掘 Linux
Linux命令repotrack的详解与应用
在Linux系统中,软件包管理是一项至关重要的任务,尤其是在没有网络连接或需要离线安装软件包的场景中。`repotrack`命令就是这样一个强大的工具,它帮助用户下载RPM包及其所有依赖项,从而简化了离线安装的过程。本文将详细介绍`repotrack`命令,包括其定义、工作原理、主要特点、使用示例以及最佳实践。
|
13天前
|
数据可视化 安全 Linux
探索Linux命令repo-graph:深入解析与应用实践
`repo-graph`是Linux的Yum-utils工具,用于可视化仓库中软件包的依赖关系,简化复杂网络管理。它通过分析元数据生成图形,支持自定义输出格式和特定包分析。例如,`repo-graph --repoid=updates`显示更新仓库的依赖,而`--packages=httpd`则专注httpd包。注意权限、复杂性和选择合适输出格式。定期分析和图形化展示是最佳实践。
|
21天前
|
NoSQL Linux 程序员
Linux objdump命令:深入解析与实战应用
`objdump`是Linux下的反汇编工具,用于将二进制文件转换为汇编代码,便于理解程序底层。它可以反汇编目标文件、可执行文件和库,支持多种参数,如显示符号表(-t)、反汇编代码(-d)、源代码与汇编混合视图(-S)。在实践中,结合-g编译选项和特定段(-j)反汇编,能辅助调试和分析。使用时注意包含调试信息,选择适当参数,并与其他工具(如gdb)配合使用。
|
1天前
|
监控 安全 Linux
Linux命令ssltap的深入解析与应用实践
`ssltap`是一个假想的Linux命令,用于模拟SSL/TLS流量分析。它捕获、解密(如果有密钥)并分析加密流量,提供实时监控、协议解析和安全审计。特点包括实时性、灵活性、可扩展性和安全性。示例用法包括捕获特定端口流量和实时监控会话状态。在实际操作中应注意私钥安全、性能影响及合规性,建议定期审计和自动化监控。
|
25天前
|
数据挖掘 Linux 数据处理
探索Linux下的Lua命令:轻量级脚本语言在数据处理和分析中的应用
**探索Linux上的Lua:轻量级脚本语言用于数据处理。Lua通过命令行解释器执行,适用于游戏开发、数据分析及自动化。特点包括小巧、高效、可扩展和动态类型。使用`lua`或`luajit`,配合-e、-l、-i参数执行脚本或互动模式。示例:执行`hello.lua`脚本打印&quot;Hello, Lua!&quot;。最佳实践涉及版本兼容、性能优化、使用C API、测试和文档编写。**