当前位置: 首页 > news >正文

linux之framebuffer(1)

kernel版本:linux-4.19 

1. 重要的即几个结构体

(a) struct fb_fix_screeninfo

(b) struct fb_var_screeninfo

头文件: <linux/fb.h>

源文件:drivers/video/fbmem.c 

1. struct fb_fix_screeninfo 

struct fb_fix_screeninfo {
	char id[16];			/* identification string eg "TT Builtin" 设备驱动名称 */
	unsigned long smem_start;	/* Start of frame buffer mem 显存起始物理地址*/
					/* (physical address) */
	__u32 smem_len;			/* Length of frame buffer mem 显存大小 */
	__u32 type;			/* see FB_TYPE_*	显卡类型	*/
	__u32 type_aux;			/* Interleave for interleaved Planes 附加类型 */
	__u32 visual;			/* see FB_VISUAL_*	色彩模式	*/ 
	__u16 xpanstep;			/* zero if no hardware panning 水平方向每步进的像素值  */
	__u16 ypanstep;			/* zero if no hardware panning 垂直方向每步进的像素值*/
	__u16 ywrapstep;		/* zero if no hardware ywrap   类似ypanstep,当其显示到底部时,能回到显存的开始处进行显示 */
	__u32 line_length;		/* length of a line in bytes    */
	unsigned long mmio_start;	/* Start of Memory Mapped I/O 显存映射I/O首地址   */
					/* (physical address) */
	__u32 mmio_len;			/* Length of Memory Mapped I/O 显存映射I/O长度 */
	__u32 accel;			/* Indicate to driver which	显示所支持的硬件加速设备 */
					/*  specific chip/card we have	*/
	__u16 capabilities;		/* see FB_CAP_*			*/
	__u16 reserved[2];		/* Reserved for future compatibility */
};

2. struct fb_var_screeninfo

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 从虚拟到可见偏移值x */
	__u32 yoffset;			/* resolution			*/

	__u32 bits_per_pixel;		/* guess what	每个像素所占的比特位  		*/
	__u32 grayscale;		/* 0 = color, 1 = grayscale, 灰度级(默认0,彩色)	*/
					/* >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 是否为标准像素格式(0:标准 非0:非标准) */

	__u32 activate;			/* see FB_ACTIVATE_*	设置生效的时刻	默认FB_ACTIVATE_NOW,立刻生效 */

	__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 基于FOURCC模式的颜色空间 */
	__u32 reserved[4];		/* Reserved for future compatibility */
};

struct fb_bitfield {
	__u32 offset;			/* beginning of bitfield 颜色分类起始比特位	*/
	__u32 length;			/* length of bitfield	颜色分类所占比特长度	*/
	__u32 msb_right;		/* != 0 : Most significant bit is 右边的比特是否为最高有效位 */ 
					/* right */ 
};

在fbmem.c文件中, 初始化函数 fbmem_init 如下:

int __init fbmem_init(void)
{
    //在/proc下创建名为fb的文件;
    proc_create("fb",0, NULL, &fb_proc_fops);
    
    //注册字符设备
    register_chrdev(FB_MAJOR, "fb", &fb_fops);
    
    //在/sys/class/下创建graphics
    fb_class = class_create(THIS_MODULE, "graphics");
}

其中fb_fops 内容如下:

static const struct file_operations fb_fops = {
	.owner =	THIS_MODULE,
	.read =		fb_read, 
	.write =	fb_write,
	.unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl = fb_compat_ioctl,
#endif
	.mmap =		fb_mmap,
	.open =		fb_open,
	.release =	fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
	.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	.fsync =	fb_deferred_io_fsync,
#endif
	.llseek =	default_llseek,
};

其中 fb_ioctl 函数为应用层ioctl调用提供接口;

2. ioctl函数

 1. 获取屏幕可变信息

int ioctl(int fd,  FBIOGET_VSCREENINFO, struct fb_var_screeninfo *var);

 主要包括分辨率和像素格式等;

2. 设置屏幕可变信息

int ioctl(int fd,  FBIOPUT_VSCREENINFO, struct fb_var_screeninfo *var); 

3. 获取屏幕固定信息

 int ioctl(int fd,  FBIOGET_FSCREENINFO, struct fb_fix_screeninfo *fix); 

获取FrameBuffer固定信息,包括显存起始物理地址,显存大小和行间距等; 

4. 设置PAN显示

int ioctl(int fd,  FBIOPAN_DISPLAY, struct fb_var_screeninfo *var);  

 设置从虚拟分辨率中的不同偏移处开始显示; 

 其中xres_virtual,yres_virtual为虚拟分辨率, xres,yres为实际显示分辨率,xoffset,yoffset为显示的偏移量;

注:必须保证实际分辨率与偏移量和在虚拟分辨率范围内,否则设置不成功;另最好保证xoffset与yoffset形成的偏移地址是16byte对齐的;

代码示例:

//以下参数表示ARGB1555,A占1bit,RGB各占用5位,共16bit;
struct fb_bitfield r16 = {10, 5, 0}; //bit10~bit14
struct fb_bitfield g16 = {5, 5, 0}; //bit5~bit9
struct fb_bitfield b16 = {0, 5, 0}; //bit0~bit4
struct fb_bitfield b16 = {15, 1, 0};//bit15

struct fb_var_screeninfo vinfo;
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0){
    return -1;
}

//虚拟分辨率等于实际显示分辨率;
vinfo.xres_virtual = 1280;
vinfo.yres_virtual = 960;
vinfo.xres = 1280;
vinfo.yres = 960;

vinfo.activate = FB_ACTIVATE_NOW;//设置后立即生效
vinfo.bits_per_pixel = 16;
vinfo.xoffset = 0;
vinfo.yoffset = 0;
vinfo.red = r16;
vinfo.green = g16;
vinfo.blue = b16;
vinfo.transp = a16;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo) < 0){
    return -1;
}

....

//偏移到320,160处;
vinfo.xoffset = 320;
vinfo.yoffset = 160;
if (ioctl(fd, FBIOPAN_DISPLAY, &vinfo) < 0){
    return -1;
}

相关文章:

  • Linux常用基本命令详解(二)-------磁盘分区和磁盘管理类命令
  • Vue:列表排序和筛选(运用计算属性和监视属性(侦听属性))
  • 难点:树的代码
  • vulnhub blogger: 1
  • php项目宝塔搭建实战ThinkAdmin通用公众号小程序后台开发框架
  • Web前端系列技术之Web APIs基础(从基础开始)⑥
  • FPGA学习笔记(四)通过数码管学习顶层模块和例化的编写
  • kafka 代码使用
  • 两个单链表相交的一系列问题
  • 连接查询
  • ArrayList源码解析
  • iptables防火墙 (SNAT、DNAT)
  • idea2021.3.3 创建maven-scala项目并解决遇到的问题:通过add frameworks support找到不到scala插件
  • 模板模式【Java设计模式】
  • openGL 材质
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • canvas 绘制双线技巧
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  •  D - 粉碎叛乱F - 其他起义
  • Java IO学习笔记一
  • JAVA并发编程--1.基础概念
  • MySQL-事务管理(基础)
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 从重复到重用
  • 动态规划入门(以爬楼梯为例)
  • 动态魔术使用DBMS_SQL
  • 区块链分支循环
  • 如何学习JavaEE,项目又该如何做?
  • 网络应用优化——时延与带宽
  • 我有几个粽子,和一个故事
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • $ git push -u origin master 推送到远程库出错
  • (30)数组元素和与数字和的绝对差
  • (70min)字节暑假实习二面(已挂)
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (转)程序员疫苗:代码注入
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net IOC框架入门之一 Unity
  • .net Stream篇(六)
  • .NET 表达式计算:Expression Evaluator
  • .NET/C# 使窗口永不获得焦点
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • .NET面试题(二)
  • .NET下的多线程编程—1-线程机制概述
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [1159]adb判断手机屏幕状态并点亮屏幕
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [C# WPF] DataGrid选中行或选中单元格的背景和字体颜色修改