framebuffer

一、基本概念

framebuffer: 帧缓存、帧缓存(显示设备)

Linux内核为显示提供的一套应用程序接口。(驱动内核支持)

分辨率:

像素点

显示屏:800 * 600(横向有800个像素点,纵向有600个像素点)

显卡(显存(保存像素点的值))

RGB

888(8个bitR,8个bit G,8个bit B)

PC ,4412(RGB888)

RGB565(S3C2440)

为了提高代码的书写效率(将RGB扩充到4字节)

二、解决显存空间不能直接被用户访问

根据显存的大小的多少,来申请空间

1、打开显示设备(/dev/fb0)

2、获取显示设备相关参数(分辨率、位深度......)

3、建立内存映射

4、写入RGB颜色值

5、解除映射

6、关闭显示设备

三、framebuffer常问话术

framebuff(是什么,具体原理、怎么做、)

是什么:Linux内核为显示提供的一套应用程序接口。(驱动内核支持)

具体原理:通过内存映射技术,向显存空间写入RGB值

1、打开显示设备(/dev/fb0)

2、获取显示设备相关参数(分辨率、位深度......)

3、建立内存映射

4、写入RGB颜色值

5、解除映射

6、关闭显示设备

点线面圆清屏:


#include<stdio.h>
#include "framebuffer.h"
#include <linux/fb.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<math.h>

void *pmem;
struct fb_var_screeninfo vinf;

int init_fb(char *devname)
{
	int fd = open(devname, O_RDWR);	
	if (-1 == fd)
	{
		perror("fail open fb");
		return -1;
	}
	
	int ret = ioctl(fd, FBIOGET_VSCREENINFO, &vinf);
	if (-1 ==ret)
	{
		perror("fail ioctl");
		return -1;
	}
	
	printf("xres = %d, yres = %d\n", vinf.xres, vinf.yres);
	printf("xres_virtual = %d, yres_virtual = %d\n", vinf.xres_virtual, vinf.yres_virtual);
	printf("bits_per_pixel : %d\n", vinf.bits_per_pixel);

	size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;
	pmem = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if ((void *)-1 == pmem)
	{
		perror("fail mmap");
		return -1;
	}
	return fd;
}

void draw_point(int x, int y, unsigned int col)
{
	if (x >= vinf.xres || y >= vinf.yres)
	{
		return ;
	}
	if (vinf.bits_per_pixel == RGB888_FMT)
	{
		unsigned int *p = pmem;
		*(p + y * vinf.xres_virtual + x) = col;
	}
	else if (vinf.bits_per_pixel == RGB565_FMT)
	{
		unsigned short *p  = pmem;	
		*(p + y * vinf.xres_virtual + x) = col;
	}
	return ;
}
void draw_line( int x1, int x2,int y, unsigned int col)
{
    for(int i = x1;i < x2;++i)
    {
        draw_point(i,y,col);
    }
}
void draw_pipe(int x, int y1, int y2, unsigned int col)
{
    for(int i = y1;i < y2;++i)
    {
        draw_point(x,i,col);
    }
}

void draw_slash(int x1, int y1, unsigned int col,int len)
{
    for(int i = 0;i < len;++i)
    {
        draw_point(x1 + i,y1 + i ,col);
    }
}

void uninit_fb(int fd)
{

	size_t len = vinf.xres_virtual * vinf.yres_virtual * vinf.bits_per_pixel/8;
	munmap(pmem, len);
	close(fd);
}

void draw_rectangle(int x,int y,int ab,int ac,unsigned int col)
{
    if(x >= vinf.xres || y >= vinf.yres) 
    {
        return;
    }
    unsigned int *p = (unsigned int *)pmem;
    for(int i = 0; i < ab;++i)
    {
        for(int j = 0;j < ac;++j)
        {
            *(p + (y + j)* vinf.xres_virtual + x + i)  = col;
        }
    }
    return;
}

void draw_circle(int x,int y,int rad,unsigned int col)
{
    int a,b;
    for(int i = 0;i < 360;++i)
    {
        a = x + rad * cos( i / 180.0 * 3.14);
        b = y + rad * sin( i / 180.0 * 3.14);
        draw_point(a,b,col);
    }
}

void clean_scren(unsigned int col)
{
    for(int i = 0; i < vinf.xres_virtual;++i)
    {
        for(int j = 0; j < vinf.yres_virtual; ++j)
        {
            draw_point(i,j,col);
        }
    }
}

声明:

#ifndef _FRAMEBUFFER_H
#define _FRAMEBUFFER_H

#define RGB888_FMT 32
#define RGB565_FMT 16

extern int init_fb(char *devname);
extern void draw_point(int x,int y, unsigned int col);
extern void uninit_fb(int fd);
void draw_line(int x1, int x2,int y, unsigned int col);
void draw_pipe(int x, int y1, int y2, unsigned int col);
void draw_slash(int x1,int y1, unsigned int col,int len);
void draw_rectangle(int x,int y,int ab,int ac,unsigned int col);
void draw_circle(int x,int y,int rad,unsigned int col);
void clean_scren(unsigned int col);
#endif

主函数:

#include<stdio.h>
#include "framebuffer.h"


int main(int argc, const char *argv[])
{

	int fb_fd = init_fb("/dev/fb0");
	if (-1 == fb_fd)
	{
		return -1;
	}


	draw_point(400, 300, 0x00ff0000);
    draw_line(350,450,300,0x00ff0000);	
    draw_pipe(400,250,350,0x00ff0000);
    draw_slash(400,300,0x00ff0000,350);
    draw_rectangle(300,300,100,100,0x00ff0000);
    draw_circle(300,300,100,0x00ff0000);
    clean_scren(0x00ffffff);
	uninit_fb(fb_fd);
	return 0;
}

gcc *.c -lm

ctrl + alt + f3进入原始终端

输入用户名密码,sudo ./a.out

  • 14
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值