怎样通过framebuffer来传递关屏信息

    本人的项目是一个用oled来显示的android项目;需要在系统睡眠关闭主屏幕的时候,一起把oled屏幕关掉。但这是并没有进入系统睡眠。因此不能使用kernel里的suspend 与resume机制来控制oled的显示和背光。 可以使用framebuffer的功能来从用户态到kernel态来传递命令。

     在用户层,可以使用消息的机制,来获得用户关屏的动作,无论是短按电源键还是时间到关屏,都会有一个消息发布;这是上层hardware从可以获得这个消息,然后通过framebuffer来告知kernel层;本文主要说明这个用户层和kernel之间的通信机制。

一. kernel对framebuffer的注册和使用

    1. probe函数里的变量定义:

	struct fb_info *info;
	u32 vmem_size;
	struct ssd1307fb_par *par;
	u8 *vmem;

    2. 主要变量的初始化:(只有部分)

	info = framebuffer_alloc(sizeof(struct ssd1307fb_par), &client->dev);
	if (!info) {
		dev_err(&client->dev, "Couldn't allocate framebuffer.\n");
		return -ENOMEM;
	}
	vmem_size = par->width * par->height / 8;

	vmem = vmalloc(vmem_size);
	if (!vmem) {
		dev_err(&client->dev, "Couldn't allocate graphical memory.\n");
		ret = -ENOMEM;
		goto fb_alloc_error;
	}

	info->fbops = &ssd1307fb_ops;
	info->fix = ssd1307fb_fix;
	info->fix.line_length = par->width / 8;
	info->fbdefio = &ssd1307fb_defio;

	dev_info(&client->dev, "%s info->fix.line_length=%d\n",
        __func__, info->fix.line_length);

	info->var = ssd1307fb_var;
	info->var.xres = par->width;
	info->var.xres_virtual = par->width;
	info->var.yres = par->height;
	info->var.yres_virtual = par->height;

	info->var.red.length = 1;
	info->var.red.offset = 0;
	info->var.green.length = 1;
	info->var.green.offset = 0;
	info->var.blue.length = 1;
	info->var.blue.offset = 0;

	info->screen_base = (char *)vmem;
	info->fix.smem_start = (unsigned long)vmem;
	info->fix.smem_len = vmem_size;

	fb_deferred_io_init(info);
     3. 注册

	ret = register_framebuffer(info);
	if (ret) {
		dev_err(&client->dev, "Couldn't register the framebuffer\n");
		goto panel_init_error;
	}
     4. 在上面的注册中,还有一些文件节点需要定义:

static struct fb_fix_screeninfo ssd1307fb_fix = {
	.id		= "Solomon SSD1307",
	.type		= FB_TYPE_PACKED_PIXELS,
	.visual		= FB_VISUAL_MONO10,
	.xpanstep	= 0,
	.ypanstep	= 0,
	.ywrapstep	= 0,
	.accel		= FB_ACCEL_NONE,
};

static struct fb_var_screeninfo ssd1307fb_var = {
	.bits_per_pixel	= 1,
};

static struct fb_ops ssd1307fb_ops = {
	.owner		= THIS_MODULE,
	.fb_read	= fb_sys_read,
	.fb_write	= ssd1307fb_write,
	.fb_fillrect	= ssd1307fb_fillrect,
	.fb_copyarea	= ssd1307fb_copyarea,
	.fb_imageblit	= ssd1307fb_imageblit,
	.fb_blank   = ssd1305fb_blank,
};
static void ssd1307fb_deferred_io(struct fb_info *info,
				struct list_head *pagelist)
{
	ssd1305fb_update_display(info->par);
}

static struct fb_deferred_io ssd1307fb_defio = {
	.delay		= HZ,
	.deferred_io	= ssd1307fb_deferred_io,
};

    在上面的注册中, .fb_blank = ssd1305fb_blank,   就是对关屏动作的回调函数的调用。

二、 上层对framebuffer的调用

    int fbfd = 0;
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    char *fbp = 0;

    // Open the file for reading and writing
    fbfd = open("/dev/graphics/fb3", O_RDWR);
    if (fbfd < 0) {
        printf("Error: cannot open framebuffer device.\n");
        exit(1);
    }
    printf("The framebuffer device was opened successfully. fbfd=%x\n", fbfd);

    screensize = 128 * 8;

    printf("the screensize is %d\n", screensize );

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
                       fbfd, 0);
    if ((int)fbp == -1) {
        printf("Error: failed to map framebuffer device to memory.\n");
        exit(4);
    }
    printf("The framebuffer device was mapped to memory successfully.\n");

    memcpy(fbp, picture5, screensize);

    munmap(fbp, screensize);

	sleep(10);

    printf("start blank OLED\n");
	ioctl(fbfd, FBIOBLANK, 0);  // enable bklight
	ioctl(fbfd, FBIOBLANK, 1);  // disable bkilght

    close(fbfd);

在上面中,ioctl(fbfd, FBIOBLANK,  0) ;   函数就是对底层函数ssd1305fb_blank()的调用。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值