framebuffer 子系统分析

 come from :https://blog.csdn.net/u012728256/article/details/70274465

struct fb_info {
	int node;
	int flags;
	struct mutex lock;		/* 调用open/release/ioctl时的锁 */
	struct mutex mm_lock;		/* fb_mmap和smem_*的锁 */
	struct fb_var_screeninfo var;	/* 当前LCD的可变参数 */
	struct fb_fix_screeninfo fix;	/* 当前LCD的固定参数 */
	struct fb_monspecs monspecs;	/* 当前LCD标准 */
	struct work_struct queue;	/* 帧缓冲工作队列 */
	struct fb_pixmap pixmap;	/* 图像硬件mapper */
	struct fb_pixmap sprite;	/* 光标硬件mapper */
	struct fb_cmap cmap;		/* 当前LCD的颜色表 */
	struct list_head modelist;      /* mode list */
	struct fb_videomode *mode;	/* 当前的video模式 */
 
#ifdef CONFIG_FB_BACKLIGHT
	/* 对应的背光设备,在framebuffer之前注册及其之后注销 */
	struct backlight_device *bl_dev;
 
	/* 背光等级调整 */
	struct mutex bl_curve_mutex;	
	u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
	struct delayed_work deferred_work;
	struct fb_deferred_io *fbdefio;
#endif
 
	struct fb_ops *fbops;           /* 帧缓冲底层操作函数接口 */
	struct device *device;		/* 父设备 */
	struct device *dev;		/* fb设备*/
	int class_flag;                    /* 私有sysfs标志 */
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
	char __iomem *screen_base;	/* 虚拟基地址即framebuffer起始虚拟地址 */
	unsigned long screen_size;	/* 显存大小 */ 
	void *pseudo_palette;		/* 伪16色颜色表 */ 
#define FBINFO_STATE_RUNNING	0
#define FBINFO_STATE_SUSPENDED	1
	u32 state;			/* Hardware state i.e suspend */
	void *fbcon_par;                /* fbcon use-only private area */
	/* 私有数据 */
	void *par;
	/* we need the PCI or similiar aperture base/size not
	   smem_start/size as smem_start may just be an object
	   allocated inside the aperture so may not actually overlap */
	struct apertures_struct {
		unsigned int count;
		struct aperture {
			resource_size_t base;
			resource_size_t size;
		} ranges[0];
	} *apertures;
};
struct fb_var_screeninfo {
	__u32 xres;			/* 可视分辨率 */
	__u32 yres;
	__u32 xres_virtual;		/* 虚拟分辨率 */
	__u32 yres_virtual;
	__u32 xoffset;			/* 虚拟到可视之间的偏移 */
	__u32 yoffset;		
 
	__u32 bits_per_pixel;		/* 每个像素点占用的位数 */
	__u32 grayscale;		/* 非0时指灰度值 */
 
	struct fb_bitfield red;		/* fb内存的RGB位域 */
	struct fb_bitfield green;
	struct fb_bitfield blue;
	struct fb_bitfield transp;	/* 透明度 */	
 
	__u32 nonstd;			/* 非0时代指非标准像素格式 */
 
	__u32 activate;			/* see FB_ACTIVATE_* */
 
	__u32 height;			/* 高度 mm */
	__u32 width;			/* 宽度 mm */
 
	__u32 accel_flags;		/* (OBSOLETE) see fb_info.flags */
 
	/* 时序: 除pixel以外,其他的都以像素时钟为单位 */
	__u32 pixclock;			/* 像素时钟(皮秒) */
	__u32 left_margin;		/* 行前肩:从行同步信号到有效数据开始的时钟数 */
	__u32 right_margin;		/* 行后肩:从有效数据末尾到行同步信号的时钟数 */
	__u32 upper_margin;		/* 帧前肩:从帧同步信号到有效行开始的行数 */
	__u32 lower_margin;             /* 帧后肩:从有效行末尾到帧同步信号的行数 */
	__u32 hsync_len;		/* 行同步信号占用的时钟数 */
	__u32 vsync_len;		/* 帧同步信号占用的行数 */
	__u32 sync;			/* see FB_SYNC_*		*/
	__u32 vmode;			/* see FB_VMODE_*		*/
	__u32 rotate;			/* 旋转角度 */
	__u32 reserved[5];		/* 保留备用 */
};
struct fb_fix_screeninfo {
	char id[16];			/* 标识符 */
	unsigned long smem_start;	/* framebuffer的物理起始地址 */
	__u32 smem_len;			/* framebuffer的长度 */
	__u32 type;			/* see FB_TYPE_*		*/
	__u32 type_aux;			/* 隔行扫描参数 */
	__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    */
	__u32 line_length;		/* 一行的字节数 */
	unsigned long mmio_start;	/* 内存映射I/O的物理起始地址 */
	__u32 mmio_len;			/* 内存映射I/O的长度 */
	__u32 accel;			
	__u16 reserved[3];		/* 保留备用 */
};

这两个结构体分别记录了显示器可以修改和不可修改的信息,这些数据成员需要在驱动程序中初始化。其中fix.visual代表显示器使用的色彩模式,Linux中支持的色彩模式如下:

#define FB_VISUAL_MONO01		0	/* 黑白. 1=Black 0=White */
#define FB_VISUAL_MONO10		1	/* 黑白. 1=White 0=Black */
#define FB_VISUAL_TRUECOLOR		2	/* 真彩色,由红绿蓝三基色构成*/
#define FB_VISUAL_PSEUDOCOLOR		3	/* 伪彩色,采用索引颜色 */
#define FB_VISUAL_DIRECTCOLOR		4	/* 查表显示 */
#define FB_VISUAL_STATIC_PSEUDOCOLOR	5	/* 只读的伪彩色 */

fb_bitfield结构体描述每一个像素在显示缓冲区中的组织方式。

struct fb_bitfield {
	__u32 offset;			/* 位域偏移 */
	__u32 length;			/* 位域长度 */
	__u32 msb_right;		/* != 0 : 最高有效位在右边 */ 
};

 

 

struct fb_ops {
	/* 打开/释放 */
	struct module *owner;
	int (*fb_open)(struct fb_info *info, int user);
	int (*fb_release)(struct fb_info *info, int user);
 
	/* 下面两个函数是非线性布局的/常规内存映射无法工作的缓冲设备需要的接口 */
	ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
			   size_t count, loff_t *ppos);
	ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
			    size_t count, loff_t *ppos);
 
	/* 检测可变参数并调整到支持的值 */
	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
 
	/* 根据info->var设置video模式 */
	int (*fb_set_par)(struct fb_info *info);
 
	/* 设置颜色寄存器 */
	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
			    unsigned blue, unsigned transp, struct fb_info *info);
 
	/* 批量设置颜色寄存器 */
	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
 
	/* 清屏 */
	int (*fb_blank)(int blank, struct fb_info *info);
 
	/* pan display */
	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
 
	/* 绘制一个矩形 */
	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
	/* 拷贝数据 */
	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
	/* 绘制一幅图像 */
	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
 
	/* 绘制光标 */
	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
 
	/* 旋转显示 */
	void (*fb_rotate)(struct fb_info *info, int angle);
 
	/* 等待blit空闲(可选) */
	int (*fb_sync)(struct fb_info *info);
 
	/* ioctl函数(可选) */
	int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
			unsigned long arg);
 
	/* 32位的compat ioctl(可选) */
	int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
			unsigned long arg);
 
	/* fb特定的mmap */
	int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
 
	/* 根据var得到显示器的功能信息 */
	void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
			    struct fb_var_screeninfo *var);
 
	/* 销毁fb */
	void (*fb_destroy)(struct fb_info *info);
};

二、framebuffer注册流程分析

static struct platform_driver tccfb_driver = {  // 底层函数接口
	.probe		= tccfb_probe,
	.remove		= tccfb_remove,
	.suspend	= tccfb_suspend,
	.shutdown	= tccfb_shutdown,
	.resume		= tccfb_resume,
	.driver		= {
		.name	= "tccxxx-lcd",
		.owner	= THIS_MODULE,
	},
};
 
static int __init tccfb_init(void)
{
    printk(KERN_INFO " %s (built %s %s)\n", __func__, __DATE__, __TIME__);
 
	fb_power_state = 1;
 
	tca_fb_init();   // 初始化控制器
 
#ifdef TCC_VIDEO_DISPLAY_BY_VSYNC_INT   // 初始化锁
	spin_lock_init(&vsync_lock) ;
	spin_lock_init(&vsync_lockDisp ) ;
#endif
 
	return platform_driver_register(&tccfb_driver);
}
 
static void __exit tccfb_cleanup(void)
{
	tca_fb_cleanup();  // 注销控制器
	platform_driver_unregister(&tccfb_driver);
}
 
module_init(tccfb_init);
module_exit(tccfb_cleanup);
struct tccfb_info {
	struct fb_info		*fb;  // fbi结构体
	struct device		*dev;
 
	//struct tccfb_mach_info *mach_info;
 
	/* raw memory addresses */
	dma_addr_t		map_dma;	/* physical */
	u_char *		map_cpu;	/* virtual */
	u_int			map_size;
 
	/* addresses of pieces placed in raw buffer */
	u_char *		screen_cpu;	/* virtual address of buffer */
	dma_addr_t		screen_dma;	/* physical address of buffer */
 
	u_int			imgch;
 
	struct tccfb_platform_data *pdata;
#ifdef CONFIG_HAS_EARLYSUSPEND
    struct early_suspend early_suspend;
    struct early_suspend earlier_suspend;
#endif
};

 

上一篇:DataBinding examples


下一篇:使用unidac 连接FB 3.0 (含嵌入版)