Linux framebuffer的框架非常简单, 对于应用程序就是操作一块内存(俗称帧缓存), 当然也有可能是双缓存, 一般用于高帧率场景, 一块帧在填充数据时, 另一块在显示, 接着对调过来,
    那通过设置哪里告知驱动层读取哪块帧数据呢? 答案是用vinfo.xoffset, vinfo.yoffset
    需要注意的是, 无论用write()、还是mmap()后直接操作内存都只是填充内存而已, 并不代表能够立马显示, 这得看驱动, 如果驱动实现了自刷新(不断从帧缓存拿数据刷到LCD上), 那填充数据到帧缓存就会立马显示出来,
    如果驱动没有实现,那应用程序需要主动的调用 ioctl(fp, FBIOPAN_DISPLAY, &vinfo);, 告知驱动可以刷数据了, 如果这都没显示出来, 估计驱动没实现FBIOPAN_DISPLAY功能。
    示例代码:(驱动实现自刷新, 应用依次显示黄、蓝、红,最后画线)

    1. #include <unistd.h>
    2. #include <stdio.h>
    3. #include <fcntl.h>
    4. #include <linux/fb.h>
    5. #include <sys/mman.h>
    6. #include <stdlib.h>
    7. #include <string.h>
    8. #define RED 0xF800
    9. #define YELLOW 0xFFE0
    10. #define BLUE 0x001F
    11. #define WHITE 0xFFFF
    12. #define BLACK 0x0000
    13. void fill_color16(short *fb_addr, short bit_map, int psize)
    14. {
    15. int i;
    16. for(i=0; i<psize; i++) {
    17. *fb_addr = bit_map;
    18. fb_addr++;
    19. }
    20. }
    21. int main ()
    22. {
    23. int fp=0;
    24. struct fb_var_screeninfo vinfo;
    25. struct fb_fix_screeninfo finfo;
    26. long screensize=0;
    27. char *fbp = NULL, *test_fbp=NULL;
    28. int x = 0, y = 0;
    29. long location = 0;
    30. int i;
    31. int num = 5;
    32. int pix_size=0;
    33. fp = open("/dev/graphics/fb0", O_RDWR);
    34. if(fp < 0) {
    35. printf("Error : Can not open framebuffer device/n");
    36. exit(1);
    37. }
    38. if(ioctl(fp, FBIOGET_FSCREENINFO, &finfo)){
    39. printf("Error reading fixed information/n");
    40. exit(2);
    41. }
    42. if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){
    43. printf("Error reading variable information/n");
    44. exit(3);
    45. }
    46. screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
    47. printf("The phy mem = 0x%x, total size = %d(byte)\n", finfo.smem_start, finfo.smem_len);
    48. printf("xres = %d, yres = %d, bits_per_pixel = %d\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
    49. printf("So the screensize = %d(byte), using %d frame\n", screensize, finfo.smem_len/screensize);
    50. printf("vinfo.xoffset = %d, vinfo.yoffset = %d\n", vinfo.xoffset, vinfo.yoffset);
    51. printf("vinfo.vmode is :%d\n", vinfo.vmode);
    52. printf("finfo.ypanstep is :%d\n", finfo.ypanstep);
    53. printf("vinfo.red.offset=0x%x\n", vinfo.red.offset);
    54. printf("vinfo.red.length=0x%x\n", vinfo.red.length);
    55. printf("vinfo.green.offset=0x%x\n", vinfo.green.offset);
    56. printf("vinfo.green.length=0x%x\n", vinfo.green.length);
    57. printf("vinfo.blue.offset=0x%x\n", vinfo.blue.offset);
    58. printf("vinfo.blue.length=0x%x\n", vinfo.blue.length);
    59. printf("vinfo.transp.offset=0x%x\n", vinfo.transp.offset);
    60. printf("vinfo.transp.length=0x%x\n", vinfo.transp.length);
    61. fbp =(char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fp,0);
    62. if ((int)fbp == -1)
    63. {
    64. printf ("Error: failed to map framebuffer device to memory./n");
    65. exit (4);
    66. }
    67. printf("Get virt mem = %p\n", fbp);
    68. pix_size = vinfo.xres * vinfo.yres;
    69. /* using first frame, for FBIOPAN_DISPLAY
    70. * 当刷新需要调用FBIOPAN_DISPLAY, 要告知驱动刷哪块帧, 用到下面两个参数
    71. * 如果使用第二帧buffer -> vinfo.xoffset = 0; vinfo.yoffset = vinfo.yres;
    72. */
    73. vinfo.xoffset = 0;
    74. vinfo.yoffset = 0;
    75. /* show color loop */
    76. while(num--) {
    77. printf("\ndrawing YELLOW......\n");
    78. fill_color16((short *)fbp, YELLOW, pix_size);
    79. //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
    80. sleep(3);
    81. printf("\ndrawing BLUE......\n");
    82. fill_color16((short *)fbp, BLUE, pix_size);
    83. //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
    84. sleep(3);
    85. printf("\ndrawing RED......\n");
    86. fill_color16((short *)fbp, RED, pix_size);
    87. //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
    88. sleep(3);
    89. }
    90. #if 1
    91. /*这是你想画的点的位置坐标,(0,0)点在屏幕左上角*/
    92. x = 10;
    93. y = 10;
    94. location = x * (vinfo.bits_per_pixel / 8) + y * finfo.line_length;
    95. test_fbp = fbp + location;
    96. printf("draw line.......\n");
    97. for(i = 0; i < (vinfo.xres - x); i++)
    98. *test_fbp++ = i+30;
    99. //ioctl(fp, FBIOPAN_DISPLAY, &vinfo);
    100. #endif
    101. munmap(fbp, screensize); /*解除映射*/
    102. close (fp);
    103. return 0;
    104. }

    当然用read()/write(), 也可以, 就是效率非常低, 太多系统调用导致系统在用户态和kernel态切换, 而且每次还传输一个字节, 但作为例子可以参考一下:

    #include <unistd.h>  
    #include <stdio.h>  
    #include <fcntl.h>  
    #include <linux/fb.h>  
    #include <sys/mman.h>  
    #include <stdlib.h>  
    #include <string.h>
    
    #define RED    0xF800
    #define YELLOW    0xFFE0
    #define BLUE     0x001F
    #define WHITE    0xFFFF 
    #define BLACK    0x0000
    
    
    
    int main ()   
    {  
        int fp=0;  
        struct fb_var_screeninfo vinfo;  
        int i;
        int pix_size=0;
        unsigned char color1, color2;
    
        fp = open("/dev/graphics/fb0", O_RDWR);  
    
        if(fp < 0) {  
            printf("Error : Can not open framebuffer device/n");  
            exit(1);  
        }  
    
        if(ioctl(fp, FBIOGET_VSCREENINFO, &vinfo)){  
            printf("Error reading variable information/n");  
            exit(3);  
        }  
    
    
        pix_size = vinfo.xres * vinfo.yres;
        color1 = 0;
        color2 = 0xf8;
        for(i=0; i<pix_size; i++) {
            write(fp, &color1, 1);
            write(fp, &color2, 1);        
        }
    
        close (fp);
        return 0;
    }