⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 一个linux下的framebuffer的例子.htm

📁 本人收集的framebuffer资料
💻 HTM
📖 第 1 页 / 共 2 页
字号:
            border=0><FONT color=#ff6600>减小字体</FONT></A> <A title=增大字体 
            style="CURSOR: hand; POSITION: relative" 
            onclick='if(newasp_fontsize<64){NewaspContentLabel.style.fontSize=(++newasp_fontsize)+"pt";NewaspContentLabel.style.lineHeight=(++newasp_lineheight)+"pt";}'><IMG 
            height=15 src="一个linux下的framebuffer的例子.files/2.gif" width=15 
            border=0><FONT color=#ff6600>增大字体</FONT></A> </P>
            <DIV class=ContentFont id=NewaspContentLabel 
            style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><FONT 
            id=font_word 
            style="FONT-SIZE: 14px; FONT-FAMILY: 宋体, Verdana, Arial, Helvetica, sans-serif"><SPAN 
            class=content>摘要:<BR><BR>通过一个一个framebuffer例子,复习了内存分配的应用。其中的framebuffer例子为网上流行的(确实有bug的),在编译运行的过程中又重新温习了好多差不多已经被遗忘的知识点,写出来和大家分享!<BR>---------------------------------------------------------------------------------------------------------------------<BR>声明:<BR>&nbsp; 
            &nbsp; 此文为原创,欢迎转载,转载请保留如下信息<BR>&nbsp; &nbsp; 作者:聂飞(afreez)<BR>&nbsp; 
            &nbsp; 联系方式:<A href="mailto:afreez@sina.com"><FONT 
            color=#000000>afreez@sina.com</FONT></A> (欢迎与作者交流)<BR>&nbsp; &nbsp; 
            初次发布时间:2006-06-08<BR>&nbsp; &nbsp; 
            不经本人同意,不得用语商业或赢利性质目的,否则,作者有权追究相关责任!<BR>-----------------------------------------------------------------------------<BR><BR>例子实现了直接写屏的功能,即把屏幕清空(变黑),程序的流程大致为:打开一个FrameBuffer设备;通过mmap调用把显卡的物理内存空间映射到用户空间;通过映射关系直接写内存。<BR><BR><BR><BR>头文件<BR><BR>fbtools.h<BR><BR>#ifndef 
            _FBTOOLS_H_<BR><BR>#define _FBTOOLS_H_<BR><BR><BR><BR>#include 
            &lt;linux/fb.h&gt;<BR><BR><BR><BR>//a framebuffer device 
            structure;<BR><BR>typedef struct fbdev{<BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; int fb;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            unsigned long fb_mem_offset;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; unsigned long fb_mem;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; struct fb_fix_screeninfo fb_fix;<BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; struct fb_var_screeninfo fb_var;<BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; char dev[20];<BR><BR>} FBDEV, 
            *PFBDEV;<BR><BR><BR><BR>//open &amp; init a frame buffer<BR><BR>//to 
            use this function,<BR><BR>//you must set 
            FBDEV.dev="/dev/fb0"<BR><BR>//or "/dev/fbX"<BR><BR>//it's your frame 
            buffer.<BR><BR>int fb_open(PFBDEV pFbdev);<BR><BR><BR><BR>//close a 
            frame buffer<BR><BR>int fb_close(PFBDEV 
            pFbdev);<BR><BR><BR><BR>//get display depth<BR><BR>int 
            get_display_depth(PFBDEV pFbdev);<BR><BR><BR><BR><BR><BR>//full 
            screen clear<BR><BR>void fb_memset(void *addr, int c, size_t 
            len);<BR><BR><BR><BR>#endif<BR><BR><BR><BR>测试文件,其中深颜色的注释部分为在我机器上测得的结果<BR><BR>fbtools.c<BR><BR>代码:<BR><BR><BR><BR>#include 
            &lt;stdio.h&gt;<BR><BR>#include &lt;stdlib.h&gt;<BR><BR>#include 
            &lt;fcntl.h&gt;<BR><BR>#include &lt;unistd.h&gt;<BR><BR>#include 
            &lt;string.h&gt;<BR><BR>#include &lt;sys/ioctl.h&gt;<BR><BR>#include 
            &lt;sys/mman.h&gt;<BR><BR>#include 
            &lt;asm/page.h&gt;<BR><BR><BR><BR>#include 
            "fbtools.h"<BR><BR><BR><BR>#define TRUE &nbsp; &nbsp; &nbsp; 
            1<BR><BR>#define FALSE &nbsp; &nbsp; &nbsp; 0<BR><BR>#define 
            MAX(x,y) &nbsp; &nbsp; ((x)&gt;(y)?(x):(y))<BR><BR>#define MIN(x,y) 
            &nbsp; &nbsp; ((x)&lt;(y)?(x):(y))<BR><BR><BR><BR>//open &amp; init 
            a frame buffer<BR><BR>int fb_open(PFBDEV 
            pFbdev)<BR><BR>{<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            pFbdev-&gt;fb = open(pFbdev-&gt;dev, O_RDWR);// 
            pFbdev-&gt;fb==3<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            if(pFbdev-&gt;fb &lt; 0)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; printf("Error opening %s: %m. Check kernel config\n", 
            pFbdev-&gt;dev);<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; return FALSE;<BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if 
            (-1 == 
            ioctl(pFbdev-&gt;fb,FBIOGET_VSCREENINFO,&amp;(pFbdev-&gt;fb_var)))<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("ioctl 
            FBIOGET_VSCREENINFO\n");<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return FALSE;<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; if (-1 == 
            ioctl(pFbdev-&gt;fb,FBIOGET_FSCREENINFO,&amp;(pFbdev-&gt;fb_fix)))<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("ioctl 
            FBIOGET_FSCREENINFO\n");<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return FALSE;<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //map physics address to 
            virtual address<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 
            pFbdev-&gt;fb_fix.smem_start=f0000000<BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; pFbdev-&gt;fb_mem_offset = (unsigned 
            long)(pFbdev-&gt;fb_fix.smem_start) &amp; (~PAGE_MASK);<BR><BR>// 
            pFbdev-&gt;fb_fix.smem_len=100 0000 
            pFbdev-&gt;fb_mem_offset=0<BR><BR>// pFbdev-&gt;fb_mem 
            =0<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pFbdev-&gt;fb_mem = 
            (unsigned long int)mmap(NULL, pFbdev-&gt;fb_fix.smem_len 
            +<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            pFbdev-&gt;fb_mem_offset,<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PROT_READ | PROT_WRITE, 
            MAP_SHARED, pFbdev-&gt;fb, 0);<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; if (-1L == (long) pFbdev-&gt;fb_mem)<BR><BR>&nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("mmap error! mem:%d 
            offset:%d\n", pFbdev-&gt;fb_mem,<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            pFbdev-&gt;fb_mem_offset);<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return FALSE;<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 
            TRUE;<BR><BR>}<BR><BR><BR><BR>//close frame buffer<BR><BR>int 
            fb_close(PFBDEV pFbdev)<BR><BR>{<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; close(pFbdev-&gt;fb);<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; pFbdev-&gt;fb=-1;<BR><BR>}<BR><BR><BR><BR>//get display 
            depth<BR><BR>int get_display_depth(PFBDEV 
            pFbdev);<BR><BR>{<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            if(pFbdev-&gt;fb&lt;=0)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; printf("fb device not open, open it 
            first\n");<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; return FALSE;<BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 
            pFbdev-&gt;fb_var.bits_per_pixel;<BR><BR>}<BR><BR><BR><BR>//full 
            screen clear<BR><BR>void fb_memset (void *addr, int c, size_t 
            len)<BR><BR>{<BR><BR>&nbsp; memset(addr, c, 
            len);<BR><BR>}<BR><BR><BR><BR>//use by test<BR><BR>#define 
            DEBUG<BR><BR>#ifdef DEBUG<BR><BR>main()<BR><BR>{<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; FBDEV fbdev;<BR><BR>&nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; memset(&amp;fbdev, 0, sizeof(FBDEV));<BR><BR>&nbsp; 
            &nbsp; &nbsp; &nbsp; &nbsp; strcpy(fbdev.dev, 
            "/dev/fb0");<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            if(fb_open(&amp;fbdev)==FALSE)<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; printf("open frame buffer 
            error\n");<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; &nbsp; &nbsp; return;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            &nbsp; }<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            //注意,下面一行有bug<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            fb_memset(fbdev.fb_mem + fbdev.fb_mem_offset, 0, 
            fbdev.fb_fix.smem_len);<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; 
            <BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
            fb_close(&amp;fbdev);<BR><BR>}<BR><BR>#endif<BR><BR>编译<BR><BR>如果对上述代码直接进行编译的话,是不能成功的,即会出现类似下面的编译错误<BR><BR>#gcc 
            –o fbtools fbtools.c<BR><BR>fbtools.c: In function 
            `main`<BR><BR>fbtools.c:89:warning:passing arg 1 of `fb_memset` 
            makes pointer from integer without a 
            cast<BR><BR><BR><BR>对有问题的fbtools.c中的第89行代码(即加粗的有注释的那一行)进行如下操作<BR><BR>修改为:<BR><BR>fb_memset((void 
            *)(fbdev.fb_mem+fbdev.fb_mem_offset), 0, 
            fbdev.fb_fix.smem_len);<BR><BR>或者<BR><BR>unsigned long 
            temp;<BR><BR>temp= 
            fbdev.fb_mem+fbdev.fb_mem_offset;<BR><BR>fb_memset((void *)temp, 0, 
            fbdev.fb_fix.smem_len);<BR><BR><BR><BR>可以成功编译成功<BR><BR><BR><BR>而修改为:<BR><BR>fb_memset((&amp;)(fbdev.fb_mem+fbdev.fb_mem_offset), 
            0, fbdev.fb_fix.smem_len);<BR><BR>或者<BR><BR>unsigned long 
            temp;<BR><BR>temp= 
            fbdev.fb_mem+fbdev.fb_mem_offset;<BR><BR>fb_memset((&amp;)temp, 0, 
            fbdev.fb_fix.smem_len);<BR><BR><BR><BR>会输出:段错误<BR><BR><BR><BR>分析<BR><BR>函数原形为:void 
            fb_memset (void *addr, int c, size_t 
            len)<BR><BR>而fbtools.c:89调用时传递的参数为:<BR><BR>fb_memset(fbdev.fb_mem+fbdev.fb_mem_offset, 
            0, 
            fbdev.fb_fix.smem_len);<BR><BR>fbdev.fb_mem和fbdev.fb_mem_offset都是unsigned 
            long类型的变量,它们的计算结果保存在一个临时的栈空间,传递调用时,其临时的地址是不能够传递到被调用的函数的,所以编译是同不过的。具体的可以参考内存分配的相关知识,记得《effective 
            c++》一书里讲的很详细,可以参考。<BR><BR>至于修改后的:<BR><BR>fb_memset((&amp;)temp, 0, 
            fbdev.fb_fix.smem_len);<BR><BR>编译出现段错误,也是很好理解的,因为(&amp;)temp不等于(void 
            *)temp,也不等于<BR><BR>(void 
            *)(fbdev.fb_mem+fbdev.fb_mem_offset),具体原因读者可以对照《effective 
            c++》思考。</SPAN> </FONT></DIV>
            <DIV></DIV></TD></TR>
        <TR>
          <TD 
          style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px" 
          align=right bgColor=#f7f7f7 height=25>[
            <SCRIPT language=JavaScript 
            src="一个linux下的framebuffer的例子.files/Hits.htm"></SCRIPT>
            ] [<A href="javascript:history.go(-1)">返回上一页</A>] [<A 
            href="javascript:window.print()">打 印</A>] [<A 
            href="http://www.fixdown.com/wz/user/favorite.asp?action=add&amp;topic=一个linux下的framebuffer的例子">收 
            藏</A>]</TD></TR>
        <TR>
          <TD 
          style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
            <DIV>上一篇文章:<A 
            href="http://www.fixdown.com/wz/article/14/21/2006/57424.htm">MySQL使用tips</A></DIV>
            <DIV>下一篇文章:<A 
            href="http://www.fixdown.com/wz/article/23/25/2006/57426.htm">为 
            Linux 手动下载和安装 Java Runtime Environment (JRE) 
        的说明</A></DIV></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=0 cellPadding=0 width=575 border=0>
        <TBODY>
        <TR>
          <TD class=titlebg1>∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [<A 
            href="http://www.fixdown.com/wz/article/comment.asp?ArticleID=57425" 
            target=_blank>更多评论</A>...]</TD></TR>
        <TR vAlign=top>
          <TD></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><!-- 页面底部开始 -->
<TABLE class=tableborder height=34 cellSpacing=0 cellPadding=0 width=778 
align=center border=0>
  <TBODY>
  <TR>
    <TD height=5></TD></TR>
  <TR>
    <TD class=linebar height=8></TD></TR>
  <TR>
    <TD height=5></TD></TR>
  <TR>
    <TD class=tablebody align=middle height=16><A class=navmenu 
      href="http://www.fixdown.com/wz/link/" target=_blank>友情连接</A> - <A 
      class=navmenu 
      href="http://www.fixdown.com/wz/support/sitemap.asp">网站地图</A> -</TD></TR>
  <TR>
    <TD height=1></TD></TR></TBODY></TABLE>
<SCRIPT language=javascript 
src="一个linux下的framebuffer的例子.files/Std_StranJF.Js"></SCRIPT>
<!-- 页面底部结束 -->
<SCRIPT src="一个linux下的framebuffer的例子.files/count.htm" 
type=text/javascript></SCRIPT>
<SPAN class=spanclass id=span_ad_01></SPAN>
<SCRIPT>ad_01.innerHTML=span_ad_01.innerHTML;span_ad_01.innerHTML="";</SCRIPT>
</BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -