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;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天未及海宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值