文章目录
前言
驱动端实现Linux模拟Framebuffer驱动;应用端采用GTK+实现多个应用程序通过接口/dev/fbXXX访问Framebuffer.基于该接口,可以在PC电脑Ubuntu系统实现基本的画点,画线等基本的绘图操作.
一、模拟Framebuffer驱动
1.总体功能
实现一个misc设备,通过文件属性接口接收应用层下达的创建Framebuffer参数创建Framebuffer设备.
2.驱动代码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#define FB_NUM 4
static struct fb_info *imulate_lcd[FB_NUM]={
NULL,NULL,NULL,NULL};
static int pcolor_format=1;
static int pbytes_per_pixel=4;
static int pbits_per_color=8;
static int pwidth=1280;
static int pheight=800;
static int pid=0;
static volatile int current_fb=-1;
static struct miscdevice misc={
.minor=255,
.name="simulate_fb",
};
static int simulate_mmap(struct fb_info *fbinfo, struct vm_area_struct *vma)
{
if(remap_pfn_range(vma, vma->vm_start, fbinfo->fix.smem_start >>PAGE_SHIFT,vma->vm_end-vma->vm_start, vma->vm_page_prot))
{
return -EAGAIN;
}
printk(KERN_INFO "simulate_mmap OK\n");
return 0;
}
static struct fb_ops simulate_fbops=
{
.owner = THIS_MODULE,
.fb_mmap = simulate_mmap
};
static ssize_t simulate_fb_create_show(struct device *dev, struct device_attribute *attr, char *buf)
{
printk(KERN_INFO "current_fd=%d\n", current_fb);
return sprintf(buf,"%d", current_fb);
}
static ssize_t simulate_fb_create_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
sscanf(buf,"%d %d %d %d %d %d",&pid, &pcolor_format,&pbytes_per_pixel,&pbits_per_color,&pwidth,&pheight);
printk(KERN_INFO "id=%d,color_format=%d,bytes_per_pixel=%d,bits_per_pixel=%d,widht=%d,height=%d\n",
pid,pcolor_format, pbytes_per_pixel, pbits_per_color,pwidth,pheight);
current_fb = -1;
if(pid >= FB_NUM || pid < 0 || imulate_lcd[pid] != NULL)
{
printk(KERN_INFO "FB num error.%d\n", pid);
return count;
}
imulate_lcd[pid] = framebuffer_alloc(sizeof(struct fb_info), NULL);
sprintf(imulate_lcd[pid]->fix.id,"rrfb%d", pid);
imulate_lcd[pid]->fix.smem_len = pwidth*pheight*pbytes_per_pixel;
imulate_lcd[pid]->fix.type = FB_TYPE_PACKED_PIXELS;
imulate_lcd[pid]->fix.visual = FB_VISUAL_TRUECOLOR;
imulate_lcd[pid]->fix.line_length = pwidth*pbytes_per_pixel;
imulate_lcd[pid]->var.xres = pwidth;
imulate_lcd[pid]->var.yres = pheight;
imulate_lcd[pid]->var.xres_virtual = pwidth;
imulate_lcd[pid]->var.yres_virtual = pheight;
imulate_lcd[pid]->var.bits_per_pixel = pbytes_per_pixel*8;
/*BGR*/
if(pcolor_format == 1)
{
imulate_lcd[pid]->var.blue.offset = 0;
imulate_lcd[pid]->var.blue.length = pbits_per_color;
imulate_lcd[pid]->var.green.offset = imulate_lcd[pid]->var.blue.offset+pbits_per_color;
imulate_lcd[pid]->var.green.length = pbits_per_color;
imulate_lcd[pid]->var.red.offset = imulate_lcd[pid]->var.green.offset+pbits_per_color;
imulate_lcd[pid]->var.<