mini6410 framebuffer

1、framebuffer

linux内核用struct fb_info来描述一个framebuffer,定义在linux/include/fb.h

struct fb_info {
	int node;
	int flags;
	struct mutex lock;		/* Lock for open/release/ioctl funcs */
	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
	struct fb_var_screeninfo var;	/* Current var */
	struct fb_fix_screeninfo fix;	/* Current fix */
	struct fb_monspecs monspecs;	/* Current Monitor specs */
	struct work_struct queue;	/* Framebuffer event queue */
	struct fb_pixmap pixmap;	/* Image hardware mapper */
	struct fb_pixmap sprite;	/* Cursor hardware mapper */
	struct fb_cmap cmap;		/* Current cmap */
	struct list_head modelist;      /* mode list */
	struct fb_videomode *mode;	/* current mode */

#ifdef CONFIG_FB_BACKLIGHT
	/* assigned backlight device */
	/* set before framebuffer registration, 
	   remove after unregister */
	struct backlight_device *bl_dev;

	/* Backlight level curve */
	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;		/* This is the parent */
	struct device *dev;		/* This is this fb device */
	int class_flag;                    /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTING
	struct fb_tile_ops *tileops;    /* Tile Blitting */
#endif
	char __iomem *screen_base;	/* Virtual address */
	unsigned long screen_size;	/* Amount of ioremapped VRAM or 0 */ 
	void *pseudo_palette;		/* Fake palette of 16 colors */ 
#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 */
	/* From here on everything is device dependent */
	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_fix_screeninfo fix; 记录了用户不能修改的显示器控制参数,如显示缓存的物理地址等

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    */
	__u32 line_length;		/* length of a line in bytes    */
	unsigned long mmio_start;	/* Start of Memory Mapped I/O   */
					/* (physical address) */
	__u32 mmio_len;			/* Length of Memory Mapped I/O  */
	__u32 accel;			/* Indicate to driver which	*/
					/*  specific chip/card we have	*/
	__u16 reserved[3];		/* Reserved for future compatibility */
};

其中struct fb_var_screeninfo 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 Graylevels instead of colors */

	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 reserved[5];		/* Reserved for future compatibility */
};


其中struct fb_ops *fbops;是包含对framebuffer操作的指针函数集。

struct fb_ops {
	/* open/release and usage marking */
	struct module *owner;
	int (*fb_open)(struct fb_info *info, int user);
	int (*fb_release)(struct fb_info *info, int user);

	/* For framebuffers with strange non linear layouts or that do not
	 * work with normal memory mapped access
	 */
	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);

	/* checks var and eventually tweaks it to something supported,
	 * DO NOT MODIFY PAR */
	int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);

	/* set the video mode according to info->var */
	int (*fb_set_par)(struct fb_info *info);

	/* set color register */
	int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
			    unsigned blue, unsigned transp, struct fb_info *info);

	/* set color registers in batch */
	int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);

	/* blank display */
	int (*fb_blank)(int blank, struct fb_info *info);

	/* pan display */
	int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);

	/* Draws a rectangle */
	void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
	/* Copy data from area to another */
	void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
	/* Draws a image to the display */
	void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);

	/* Draws cursor */
	int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);

	/* Rotates the display */
	void (*fb_rotate)(struct fb_info *info, int angle);

	/* wait for blit idle, optional */
	int (*fb_sync)(struct fb_info *info);

	/* perform fb specific ioctl (optional) */
	int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
			unsigned long arg);

	/* Handle 32bit compat ioctl (optional) */
	int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
			unsigned long arg);

	/* perform fb specific mmap */
	int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);

	/* get capability given var */
	void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
			    struct fb_var_screeninfo *var);

	/* teardown any resources to do with this framebuffer */
	void (*fb_destroy)(struct fb_info *info);

	/* called at KDB enter and leave time to prepare the console */
	int (*fb_debug_enter)(struct fb_info *info);
	int (*fb_debug_leave)(struct fb_info *info);
};

对LCD的操作分为三个步骤

1、打开后用ioctl获得当前屏幕设备的参数,根据屏幕的大小计算缓冲区的大小、

2、用mmap将屏幕的缓冲区映射到用户空间

3、以后直接写入内存相当于写入缓冲区


测试代码

#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

#define FB_DEVICE_NAME "/dev/fb0"


#define RED_COLOR565		0X0F100
#define GREEN_COLOR565		0X007E0
#define BLUE_COLOR565		0X0001F

typedef struct fb_dev	{
	int fd;				/* 帧缓冲设备硬件描述符 */
	void *pfb;			/* 指向帧缓冲映射到用户空间的首地址 */
	int xres;			/* 一帧图像的宽度 */
	int yres;			/* 一帧图像的高度 */
	int size;			/* 一帧图像的大小 */
	int bits_per_pixel;	/* 每个像素的大小 */
} fb_dev_t;

int fb_open(fb_dev_t *fbd, char *fbn)
{
	struct fb_var_screeninfo vinfo;

	if((fbd->fd = open(fbn, O_RDWR)) == -1)	{
		printf("Error: Cannot open framebuffer device.\n");
		_exit(EXIT_FAILURE);
	}

	/* 获取LCD 的可变参数 */
	ioctl(fbd->fd, FBIOGET_VSCREENINFO, &vinfo);

	fbd->xres = vinfo.xres;
	fbd->yres = vinfo.yres;
	fbd->bits_per_pixel = vinfo.bits_per_pixel;

	/* 计算一帧图像的大小 */
	fbd->size = fbd->xres * fbd->yres * fbd->bits_per_pixel / 8;

	printf("%d * %d,%d bits_per_pixel,screensize = %d.\n",fbd->xres,fbd->yres,fbd->bits_per_pixel,fbd->size);

	/* 将帧映射到内存 */
	/* mmap的应用 */
	/* mmap可以把文件内容映射到一段内存中,准确说是虚拟内存,通过对这段内存的读取和修改,实现对文件的读取和修改。 */
	/* addr:指定映射的起始地址,通常为NULL,由系统指定 */
	/* length:将文件的多大长度映射到内存 */
	/* prot:映射区的保护方式,可以是可被执行(PROT_EXEC),可被写入(PROT_WRITE),可被读取(PROT_READ),映射区不能存取(PROT_NONE) */
	/* flags:映射区的特性,对映射区的写入数据会复制回文件,且允许其他映射文件的进城共享(MAP_SHARED),对映射区的写入操作会产生一个映射的复制,对此区域所做的修改不会写会源文件(MAP_PRIVATE) */
	/* fd:由open返回的文件描述符,代表要映射的文件 */
	/* offset:以文件开始出的偏移,必须是分页大小的整数倍,通常为0,表示从头开始映射 */

	/* 注意:在修改映射文件时,只能在原长度上修改,不能增加文件长度,因为内存是已经分配好的 */
	
	fbd->pfb = mmap(NULL, fbd->size, PROT_READ | PROT_WRITE, MAP_SHARED, fbd->fd, 0);

	if((int)fbd->pfb == -1)	{
		printf("Error: Failed to map frambuffer device to memory!\n");
		_exit(EXIT_FAILURE);
	}

	return 0;
}

int fb_close(fb_dev_t *fbd)
{
	/* 解除映射 */
	munmap(fbd->pfb,fbd->size);

	/* 关闭设备文件 */
	close(fbd->fd);
}

int fb_drawrect(fb_dev_t *fbd, int x0, int y0, int w, int h, int color)
{
	int x,y;

	for(y=y0; y<y0+h; y++)	{
		for(x=x0; x<x0+w; x++)	{
			*((short *)(fbd->pfb) + y*fbd->xres +x) = color;
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	fb_dev_t *fbd;

	fbd = (fb_dev_t *)malloc(sizeof(fb_dev_t));

	fb_open(fbd, FB_DEVICE_NAME);

	if(fbd->bits_per_pixel == 16)	{
		printf("Red/Green/Blue Screen!");

		fb_drawrect(fbd, 0, 0, fbd->xres, fbd->yres/3, RED_COLOR565);
		fb_drawrect(fbd, 0, fbd->yres/3, fbd->xres, fbd->yres/3, GREEN_COLOR565);
		fb_drawrect(fbd, 0, fbd->yres*2/3, fbd->xres, fbd->yres/3, BLUE_COLOR565);
	}

	else	
		printf("16 bits only!");

	fb_close(fbd);

	return 0;
}


成功后可以看到屏幕上显示三种颜色条、

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值