framebuffer 应用层函数

显示屏里面有一些自带的驱动寄存器,我们要操作显示器的亮灭显示及颜色等,其实就是对该显示器的寄存器进行操作,有一些寄存器是只读的,里面包含了该显示屏的一些基本且不可更改的信息,比如说该显示器实际的长和宽,还有一些信息是可以改变的,比如说屏幕的分辨率。

我们首先需要读取显示器找中的一些特定的信息,在程序的实现中是通过
ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
来实现读取硬件不可变的信息。
而通过
ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
则可以读取硬件的可变信息,然后再对这些读取到的信息进行调整,然后再写进去到屏幕的寄存器中即可改变显示器的设置

        vinfo.xres = 1024;
        vinfo.yres = 600;
        vinfo.xres_virtual = 1024;
        vinfo.yres_virtual = 1200;
        ret = ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo); 

而显示背景和显示字体颜色其实就是对某个像素点的地址进行写值,地址的不同决定了像素点的坐标不同,值的不同决定了该坐标像素点的颜色和亮度不同。首先需要获得该显示屏地址的基址,然后随着偏移地址累加会逐渐扫描各个像素点。我们只需要在里面赋相应的值即可。

 pfb = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  
 *(pfb + y * WIDTH + x) = color;

完整代码如下:
本程序参考朱友鹏老师视频程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#define FBDEVICE        "/dev/fb0"

//#define WIDTH         800     
//#define HEIGHT        480
#define WIDTH           1024    
#define HEIGHT          600
#define WHITE           0xffffffff      // test ok
#define BLACK           0x00000000
#define RED             0xffff0000
#define GREEN           0xff00ff00      // test ok
#define BLUE            0xff0000ff                      

#define GREENP          0x0000ff00   
void draw_back(unsigned int width, unsigned int height, unsigned int color);
void draw_line(unsigned int color);
unsigned int *pfb = NULL;

int main(void)
{
        int fd = -1, ret = -1;
        struct fb_fix_screeninfo finfo = {0};
        struct fb_var_screeninfo vinfo = {0};

        fd = open(FBDEVICE, O_RDWR);
        if (fd < 0)
        {
                perror("open");
                return -1;
        }
        printf("open %s success.\n", FBDEVICE);

        ret = ioctl(fd, FBIOGET_FSCREENINFO, &finfo);  //
        if (ret < 0)
        {
                perror("ioctl");
                return -1;
        }
        printf("smem_start = 0x%x, smem_len = %u.\n", finfo.smem_start, finfo.smem_len);

        ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);    //
        if (ret < 0)
        {
                perror("ioctl");
                return -1;
        }
        printf("xres = %u, yres = %u.\n", vinfo.xres, vinfo.yres);
        printf("xres_virtual = %u, yres_virtual = %u.\n", vinfo.xres_virtual, vinfo.yres_virtual);
        printf("bpp = %u.\n", vinfo.bits_per_pixel);


        vinfo.xres = 1024;
        vinfo.yres = 600;
        vinfo.xres_virtual = 1024;
        vinfo.yres_virtual = 1200;
        ret = ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo);  
        if (ret < 0)
         {
                perror("ioctl");
                return -1;
        }

        ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
        if (ret < 0)
        {
                perror("ioctl");
                return -1;
        }
        printf("xres = %u, yres = %u.\n", vinfo.xres, vinfo.yres);
        printf("xres_virtual = %u, yres_virtual = %u.\n", vinfo.xres_virtual, vinfo.yres_virtual);
        printf("bpp = %u.\n", vinfo.bits_per_pixel);


        unsigned long len = vinfo.xres_virtual * vinfo.yres_virtual * vinfo.bits_per_pixel / 8;
        printf("len = %ld\n", len);
        pfb = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  //get address for back color
        if (NULL == pfb)
        {
                perror("mmap");
                return -1;
        }
        printf("pfb = %p.\n", pfb);

        draw_back(WIDTH, HEIGHT, WHITE);  //  
        draw_line(RED);

        close(fd);

        return 0;
}



void draw_back(unsigned int width, unsigned int height, unsigned int color)
{
    unsigned int x, y;

    for (y=0; y<height; y++)
    {
        for (x=0; x<width; x++)
        {
            *(pfb + y * WIDTH + x) = color;
        }
    }
}

void draw_line(unsigned int color)
{
    unsigned int x, y;

    for (x=50; x<600; x++)
    {
        *(pfb + 200 * WIDTH + x) = color;
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值