tag 标签: framebuffer

相关博文
  • 热度 12
    2015-7-11 11:30
    1301 次阅读|
    0 个评论
    在 SylixOS 和嵌入式 Linux 的界面编程上 Qt 是目前最主流的选择,面对复杂多样的嵌入式应用, Qt 不见得在任何场合都合适。在很多领域需要轻量级的 GUI ,比如 emwin 、 rttgui 等单片机上使用的 GUI 。还有很多对现实效率要求非常高,而显示界面比较有规律的场合,不需要 GUI 就可以完成。因此需要了解下 framebuffer 的编程,以方便满足一下稀奇古怪的需求。 Framebuffer 可以简单的理解成一块被映射到 LCD 显示器的内存区域。向这块内存写入什么数据,就会在 LCD 上显示什么界面。 Framebuffer 的概念不仅仅存在于 SylixOS 、 Linux 等这类操作系统中,在具备 LCD 控制器的单片机或其他 CPU 上概念和操作方法基本都一样。如果你是裸奔,只需要拿到 framebuffer 的指针,进行操作即可。但在 SylixOS 、 Linux 这种高级操作系统下,还是需要以流程才能够拿到 framebuffer 的指针。 1、 打开 framebuffer 设备 2、 获取 framebuffer 的一些参数,毕竟需要考虑程序的适应性,所以里面的参数应该能根据不同的 LCD 显示进行调整 3、为 framebuffer 分配内存,获取内存操作的地址指针 4、通过指针想内存写入数据,实现显示 为了便于使用,这里粘贴出完整的源码只需要拷贝、粘贴就可以使用了 int  main (VOID) {     INT                  ix;     INT                  iFbFd;     LW_GM_SCRINFO        scrInfo;     LW_GM_VARINFO        varInfo;     INT                  iError;     VOID                *pvFrameBuffer;     /*  打开fb设备          */     iFbFd = open("/dev/fb0", O_RDWR, 0666);                    if (iFbFd 0) {   return  0;  }     /*  打开失败,则返回     */     /*  获取fb的大小等参数  */     iError = ioctl(iFbFd, LW_GM_GET_SCRINFO, scrInfo);     if (iError 0) {  close(iFbFd);  return  0;  } /* 参数获取失败返回*/     /*  获取fb行列信息等    */     iError = ioctl(iFbFd, LW_GM_GET_VARINFO, varInfo);        if (iError 0) { close(iFbFd);  return  0;  }  /*打开失败,则返回 */     /* 为framebuffer分配内存 并初始化  */     pvFrameBuffer = mmap(LW_NULL, scrInfo.GMSI_stMemSize,     PROT_READ | PROT_WRITE, MAP_SHARED, iFbFd, 0);     if (pvFrameBuffer == MAP_FAILED)  /*  内存分配失败失败,则返回  */     {  close(iFbFd); return  0;  }     lib_memset(pvFrameBuffer,0xFF,scrInfo.GMSI_stMemSize);  /*屏幕全白 */     lib_memset(pvFrameBuffer,0x00,scrInfo.GMSI_stMemSize/2);/*屏幕半黑 */     /* 绘制一条红色直线,这里调用了绘制点的函数  */     for(ix = 0;ix varInfo.GMVI_ulXRes;ix++) {      __lcdDrawPixel(pvFrameBuffer, scrInfo, varInfo,ix,50,0x00FF0000);     }     sleep(30);                         //延时30s后,程序退出     /* 程序退出时,删除占用的相关资源 */     munmap(pvFrameBuffer, scrInfo.GMSI_stMemSize);     close(iFbFd);     return  0; } 绘制点的函数如下,理论上只有能够绘制一个点,就能够绘制任意界面,为了方便其他绘制调用,这里将绘制点的函数进行了封装。如果您使用的是 ucos 这类操作系统,这个函数稍微修改下就可以使用。 VOID  __lcdDrawPixel (VOID             *pvFrameBuffer,                       LW_GM_SCRINFO  *scrInfo,                       LW_GM_VARINFO  *varInfo,                       int              x,                       int              y,                       unsigned        colidx) {     /*  判断给出的绘制点坐标是否在LCD显示区域内  */     if ((x 0) || (x = varInfo-GMVI_ulXResVirtual) ||         (y 0) || (y = varInfo-GMVI_ulYResVirtual)) {         return;     }    /*判断framebuffer一个像素对应的内存大小,这里只有2Byte和4Byte两种 */      switch (varInfo-GMVI_ulBitsPerPixel) {     case 16:     {         UINT16  *pusFrameBuffer;         pusFrameBuffer = (UINT16 *)((UINT8 *)pvFrameBuffer +                                  y * scrInfo-GMSI_stMemSizePerLine);         pusFrameBuffer = ((colidx 0xFF0000) 16 3 11) |                                 ((colidx 0x00FF00)   8 2   5) |                                 ((colidx 0x0000FF)   0 3   0);     }         break;     case 24:     case 32:     {         UINT32  *puiFrameBuffer;         puiFrameBuffer = (UINT32 *)((UINT8 *)pvFrameBuffer +                              y * scrInfo-GMSI_stMemSizePerLine);         puiFrameBuffer = colidx;     }         break;     } }
相关资源