HardBirch

linux下的framebuffer的例子(转)

时间:10-01-27 栏目:系统技术篇 作者:鲁智森也有文化 评论:0 点击: 1,769 次

例子实现了直接写屏的功能,即把屏幕清空(变黑),程序的流程大致为:打开一个FrameBuffer设备;通过mmap调用把显卡的物理内存空间映射到用户空间;通过映射关系直接写内存。

头文件

////////////////////////////////////////
///////////// fbtools.h ////////////////
////////////////////////////////////////
#ifndef _FBTOOLS_H_
#define _FBTOOLS_H_

#include <linux/fb.h>

//a framebuffer device structure;

typedef struct fbdev

{
int fb;
unsigned long fb_mem_offset;
unsigned long fb_mem;
struct fb_fix_screeninfo fb_fix;
struct fb_var_screeninfo fb_var;
char dev[20];
} FBDEV, *PFBDEV;

//open & init a frame buffer

//to use this function,

//you must set FBDEV.dev="/dev/fb0"
//or "/dev/fbX"

//it's your frame buffer.
int fb_open(PFBDEV pFbdev);

//close a frame buffer
int fb_close(PFBDEV pFbdev);

//get display depth
int get_display_depth(PFBDEV pFbdev);

//full screen clear
void fb_memset(void *addr, int c, size_t len);

#endif

测试文件,其中深颜色的注释部分为在我机器上测得的结果

///////////////////////////////////////////
///////////////  fbtools.c  ///////////////

///////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/page.h>

#include "fbtools.h"

#define TRUE 1
#define FALSE 0
#define MAX(x,y) ((x)>(y)?(x):(y))
#define MIN(x,y) ((x)<(y)?(x):(y))

//open & init a frame buffer

int fb_open(PFBDEV pFbdev)

{
pFbdev->fb = open(pFbdev->dev, O_RDWR);// pFbdev->fb==3
if(pFbdev->fb < 0)
{
printf("Error opening %s: %m. Check kernel config
", pFbdev->dev);
return FALSE;
}

if (-1 == ioctl(pFbdev->fb,FBIOGET_VSCREENINFO,&(pFbdev->fb_var)))
{
printf("ioctl FBIOGET_VSCREENINFO
");
return FALSE;
}
if (-1 == ioctl(pFbdev->fb,FBIOGET_FSCREENINFO,&(pFbdev->fb_fix)))
{
printf("ioctl FBIOGET_FSCREENINFO
");
return FALSE;
}

//map physics address to virtual address
// pFbdev->fb_fix.smem_start=f0000000
pFbdev->fb_mem_offset = (unsigned long)(pFbdev->fb_fix.smem_start) & (~PAGE_MASK);
// pFbdev->fb_fix.smem_len=100 0000 pFbdev->fb_mem_offset=0
// pFbdev->fb_mem =0
pFbdev->fb_mem = (unsigned long int)mmap(NULL, pFbdev->fb_fix.smem_len +
pFbdev->fb_mem_offset,
PROT_READ | PROT_WRITE, MAP_SHARED, pFbdev->fb, 0);
if (-1L == (long) pFbdev->fb_mem)
{
printf("mmap error! mem:%d offset:%d
", pFbdev->fb_mem,
pFbdev->fb_mem_offset);
return FALSE;
}
return TRUE;
}

//close frame buffer
int fb_close(PFBDEV pFbdev)
{
close(pFbdev->fb);
pFbdev->fb=-1;
}

//get display depth
int get_display_depth(PFBDEV pFbdev);
{
if(pFbdev->fb<=0)
{
printf("fb device not open, open it first
");
return FALSE;
}
return pFbdev->fb_var.bits_per_pixel;
}
//full screen clear
void fb_memset (void *addr, int c, size_t len)
{
memset(addr, c, len);
}

 

 

//use by test
#define DEBUG
#ifdef DEBUG
main()
{
FBDEV fbdev;
memset(&fbdev, 0, sizeof(FBDEV));
strcpy(fbdev.dev, "/dev/fb0");
if(fb_open(&fbdev)==FALSE)
{
printf("open frame buffer error
");
return;
}
//注意,下面一行有bug
fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 0, fbdev.fb_fix.smem_len);
fb_close(&fbdev);
}
#endif

 

注意:如果对上述代码直接进行编译的话,是不能成功的,即会出现类似下面的编译错误
# gcc –o fbtools fbtools.c

fbtools.c: In function `main`
fbtools.c:89:warning:passing arg 1 of `fb_memset` makes pointer from integer without a cast

对有问题的fbtools.c中的第89行代码(即加粗的有注释的那一行)进行如下操作,修改为:


fb_memset((void *)(fbdev.fb_mem+fbdev.fb_mem_offset), 0, fbdev.fb_fix.smem_len);


或者


unsigned long temp;
temp= fbdev.fb_mem+fbdev.fb_mem_offset;
fb_memset((void *)temp, 0, fbdev.fb_fix.smem_len);


可以成功编译成功

 

 


 

 

问题:/dev目录下找不到 fb0设备

解决方法:对于RedHat系列linux机器,修改 /boot/grub/menu.lst 文件,并在 kernel 打头的一行添加 vga=0x0317

然后:

# mknod /dev/fb0 c 29 0
# mknod /dev/fb1 c 29 1

 


声明: 本文由( 鲁智森也有文化 )原创编译,转载请保留链接: linux下的framebuffer的例子(转)

linux下的framebuffer的例子(转):目前有

  1. 沙发
    do2jiang:

    #include &lt;stdio.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;string.h&gt;
    #include &lt;math.h&gt;
    #include &lt;stdint.h&gt;
    #include &lt;unistd.h&gt;
    #include &lt;fcntl.h&gt;
    #include &lt;sys/ioctl.h&gt;
    #include &lt;sys/mman.h&gt;
    #include &lt;asm/page.h&gt;
    #include &lt;linux/fb.h&gt;
    #define TRUE 1
    #define FALSE 0
    #define MIN(x,y) ((x)&gt;(y)?(y):(x)))
    #define MAX(x,y) ((x)&gt;(y)?(x):(y)))
    typedef struct fbdev{
    int fb;
    unsigned long fb_mem_offset;
    unsigned long fb_mem;
    struct fb_fix_screeninfo fb_fix;
    struct fb_var_screeninfo fb_var;
    char dev[20];
    } FBDEV, *PFBDEV;
    typedef struct point{
    int x;
    int y;
    int z;
    } POINT, *PPOINT;

    void draw_dot (PFBDEV pFbdev, POINT p, uint8_t r, uint8_t g, uint8_t b);
    void draw_line(PFBDEV pFbdev, POINT p1, POINT p2, uint8_t r, uint8_t g, uint8_t b);

    int fb_open(PFBDEV pFbdev)
    {
    pFbdev-&gt;fb = open(pFbdev-&gt;dev, O_RDWR);
    if(pFbdev-&gt;fb &lt; 0)
    {
    printf(&quot;Error opening %s: %m. Check kernel config/n&quot;, pFbdev-&gt;dev);
    return FALSE;
    }
    if (-1 == ioctl(pFbdev-&gt;fb,FBIOGET_VSCREENINFO,&amp;(pFbdev-&gt;fb_var)))
    {
    printf(&quot;ioctl FBIOGET_VSCREENINFO/n&quot;);
    return FALSE;
    }
    if (-1 == ioctl(pFbdev-&gt;fb,FBIOGET_FSCREENINFO,&amp;(pFbdev-&gt;fb_fix)))
    {
    printf(&quot;ioctl FBIOGET_FSCREEN

    2010-01-27 21:27 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐