本帖最后由 qinyunti 于 2023-4-11 10:22 编辑

前言
基于framebuffer快速对hdmi输出进行测试,以下都是直接串口终端登录开发板,使用开发板自己的编译工具链进行编译,无需交叉编译非常方便。
代码
新建fb.c
vi fb.c
输入如下内容
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <linux/fb.h>
  6. #include <sys/mman.h>
  7. #include <sys/ioctl.h>
  8. #include <stdint.h>
  9. int main(int argc, char *argv[])
  10. {
  11.     int fbfd = 0;
  12.     struct fb_var_screeninfo vinfo;
  13.     unsigned long screensize = 0;
  14.     unsigned long location = 0;
  15.     char *fbp = 0;
  16.     int x = 0, y = 0;
  17.     int seg_len = 0;
  18.     int tmp_seg_len = 0;
  19.     int seg_num = 0;
  20.     uint32_t rgb = 0;
  21.     uint32_t r = 0, g = 0, b = 0;
  22.     // Open the file for reading and writing
  23.     fbfd = open("/dev/fb0", O_RDWR);
  24.     if (!fbfd) {
  25.         printf("Error: cannot open framebuffer device.\n");
  26.         exit(1);
  27.     }
  28.     printf("The framebuffer device was opened successfully.\n");
  29.     // Get variable screen information
  30.     if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
  31.         printf("Error reading variable information.\n");
  32.         exit(1);
  33.     }
  34.     printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
  35.     //if (vinfo.bits_per_pixel != 16) {
  36.     //  printf("Error: not supported bits_per_pixel, it only supports 16 bit color\n");
  37.     //  exit(1);
  38.     //}
  39.     // Figure out the size of the screen in bytes
  40.     screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel/8;
  41.     // Map the device to memory
  42.     fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
  43.         fbfd, 0);
  44.     if ((int)fbp == -1) {
  45.         printf("Error: failed to map framebuffer device to memory.\n");
  46.         exit(4);
  47.     }
  48.     printf("The framebuffer device was mapped to memory successfully.\n");
  49.     seg_len = vinfo.yres/6;
  50. #if 1
  51.     seg_len = vinfo.yres/6;
  52.     for (seg_num = 0; seg_num < 6; seg_num++) {
  53.         if (seg_num == 5)
  54.             tmp_seg_len = vinfo.yres - seg_len*5;
  55.         else
  56.             tmp_seg_len = seg_len;
  57.       
  58.         for (y = 0; y < tmp_seg_len; y++) {
  59.             for (x = 0; x < vinfo.xres; x++) {
  60.                 location = seg_num*seg_len*vinfo.xres*vinfo.bits_per_pixel/8 + (y*vinfo.xres+ x)*vinfo.bits_per_pixel/8;
  61.                 switch (seg_num) {
  62.                     case 0:
  63.                     r = 0xff;
  64.                     g = (0xff/seg_len)*y;
  65.                     b = 0;
  66.                     break;
  67.                     case 1:
  68.                     r = (0xff/seg_len)*(seg_len-y);
  69.                     g = 0xff;
  70.                     b = 0;
  71.                     break;
  72.                     case 2:
  73.                     r = 0;
  74.                     g = 0xff;
  75.                     b = (0xff/seg_len)*y;
  76.                     break;
  77.                     case 3:
  78.                     r = 0;
  79.                     g = (0xff/seg_len)*(seg_len-y);
  80.                     b = 0xff;
  81.                     break;
  82.                     case 4:
  83.                     r =  (0xff/seg_len)*y;  
  84.                     g = 0;
  85.                     b = 0xff;
  86.                     break;
  87.                     case 5:
  88.                     r = 0xff;
  89.                     b = (0xff/seg_len)*(seg_len-y);
  90.                     g = 0;
  91.                     break;
  92.                     default:
  93.                     printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__);
  94.                     break;
  95.                 }
  96.                 if(vinfo.bits_per_pixel == 16)
  97.                 {
  98.                     r = (r*0x1f)/0xff;
  99.                     g = (g*0x3f)/0xff;
  100.                     b = (b*0x1f)/0xff;
  101.                     rgb = (r << 11) | (g << 5) | b;
  102.                     *((uint16_t*)(fbp + location)) = rgb;
  103.                 }
  104.                 else
  105.                 {
  106.                     rgb = (r << 16) | (g << 8) | b;
  107.                     *((uint32_t*)(fbp + location)) = rgb;
  108.                 }
  109.             }
  110.         }
  111.     }
  112.    
  113.     sleep(2);
  114.    
  115.     seg_len = vinfo.yres/6;
  116.     for (seg_num = 0; seg_num < 6; seg_num++) {
  117.         if (seg_num == 5)
  118.             tmp_seg_len = vinfo.yres - seg_len*5;
  119.         else
  120.             tmp_seg_len = seg_len;
  121.         for (y = 0; y < tmp_seg_len; y++) {
  122.             for (x = 0; x < vinfo.xres; x++) {
  123.                 location = seg_num*seg_len*vinfo.xres*vinfo.bits_per_pixel/8 + (y*vinfo.xres+ x)*vinfo.bits_per_pixel/8;
  124.                 switch (seg_num) {
  125.                     case 0://grey
  126.                     r = 100;
  127.                     g = 100;
  128.                     b = 100;
  129.                     break;
  130.                     case 1: //black
  131.                     r = 0x00;
  132.                     g = 0x00;
  133.                     b = 0x00;
  134.                     break;
  135.                     case 2://white
  136.                     r = 0xff;
  137.                     g = 0xff;
  138.                     b = 0xff;
  139.                     break;
  140.                     case 3://red
  141.                     r = 0xff;
  142.                     g = 0;
  143.                     b = 0;
  144.                     break;
  145.                     case 4: //green
  146.                     r =  0;   
  147.                     g = 0xff;
  148.                     b = 0;
  149.                     break;
  150.                     case 5: //blue
  151.                     r = 0;
  152.                     g = 0;
  153.                     b = 0xff;
  154.                     break;
  155.                     default:
  156.                     printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__);
  157.                     break;  
  158.                 }
  159.                 if(vinfo.bits_per_pixel == 16)
  160.                 {
  161.                     r = (r*0x1f)/0xff;
  162.                     g = (g*0x3f)/0xff;
  163.                     b = (b*0x1f)/0xff;
  164.                     rgb = (r << 11) | (g << 5) | b;
  165.                     *((uint16_t*)(fbp + location)) = rgb;
  166.                 }
  167.                 else
  168.                 {
  169.                     rgb = (r << 16) | (g << 8) | b;
  170.                     *((uint32_t*)(fbp + location)) = rgb;
  171.                 }
  172.             }
  173.         }
  174.     }
  175. #endif
  176. #if 1
  177.     sleep(2);
  178.     seg_len = vinfo.xres/6;
  179.     for (seg_num = 0; seg_num < 6; seg_num++) {
  180.         if (seg_num == 5)
  181.             tmp_seg_len = vinfo.xres - seg_len*5;
  182.         else
  183.             tmp_seg_len = seg_len;
  184.         for (x = 0; x < tmp_seg_len; x++) {
  185.             for (y = 0; y < vinfo.yres; y++) {
  186.                 location = y*vinfo.xres*vinfo.bits_per_pixel/8 + (seg_num*seg_len + x)*vinfo.bits_per_pixel/8;
  187.                
  188.                 switch (seg_num) {
  189.                     case 0:
  190.                     r = 0xff;
  191.                     g = (0xff/seg_len)*x;
  192.                     b = 0;
  193.                     break;
  194.                     case 1:
  195.                     r = (0xff/seg_len)*(seg_len-x);
  196.                     g = 0xff;
  197.                     b = 0;
  198.                     break;
  199.                     case 2:
  200.                     r = 0;
  201.                     g = 0xff;
  202.                     b = (0xff/seg_len)*x;
  203.                     break;
  204.                     case 3:
  205.                     r = 0;
  206.                     g = (0xff/seg_len)*(seg_len-x);
  207.                     b = 0xff;
  208.                     break;
  209.                     case 4:
  210.                     r =  (0xff/seg_len)*x;  
  211.                     g = 0;
  212.                     b = 0xff;
  213.                     break;
  214.                     case 5:
  215.                     r = 0xff;
  216.                     g = 0;
  217.                     b = (0xff/seg_len)*(seg_len-x);
  218.                     break;
  219.                     default:
  220.                     printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__);
  221.                     break;
  222.                 }
  223.                 if(vinfo.bits_per_pixel == 16)
  224.                 {
  225.                     r = (r*0x1f)/0xff;
  226.                     g = (g*0x3f)/0xff;
  227.                     b = (b*0x1f)/0xff;
  228.                     rgb = (r << 11) | (g << 5) | b;
  229.                     *((uint16_t*)(fbp + location)) = rgb;
  230.                 }
  231.                 else
  232.                 {
  233.                     rgb = (r << 16) | (g << 8) | b;
  234.                     *((uint32_t*)(fbp + location)) = rgb;
  235.                 }
  236.             }
  237.         }
  238.     }
  239.     sleep(2);
  240.     seg_len = vinfo.xres/6;
  241.     /* white black gray red green blue */
  242.     for (seg_num = 0; seg_num < 6; seg_num++) {
  243.         if (seg_num == 5)
  244.             tmp_seg_len = vinfo.xres - seg_len*5;
  245.         else
  246.             tmp_seg_len = seg_len;
  247.         for (x = 0; x < tmp_seg_len; x++) {
  248.             for (y = 0; y < vinfo.yres; y++) {
  249.                 location = y*vinfo.xres*vinfo.bits_per_pixel/8 + (seg_num*seg_len + x)*vinfo.bits_per_pixel/8;
  250.                
  251.                 switch (seg_num) {
  252.                     case 0://grey
  253.                     r = 100;
  254.                     g = 100;
  255.                     b = 100;
  256.                     break;
  257.                     case 1://black
  258.                     r = 0;
  259.                     g = 0;
  260.                     b = 0;
  261.                     break;
  262.                     case 2: //white
  263.                     r = 0xff;
  264.                     g = 0xff;
  265.                     b = 0xff;
  266.                     break;
  267.                     case 3://red
  268.                     r = 0xff;
  269.                     g = 0;
  270.                     b = 0;
  271.                     break;
  272.                     case 4: //green
  273.                     r =  0;   
  274.                     g = 0xff;
  275.                     b = 0;
  276.                     break;
  277.                     case 5: //blue
  278.                     r = 0;
  279.                     g = 0;
  280.                     b = 0xff;
  281.                     break;
  282.                     default:
  283.                     printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__);
  284.                     break;
  285.                 }
  286.                
  287.                 if(vinfo.bits_per_pixel == 16)
  288.                 {
  289.                     r = (r*0x1f)/0xff;
  290.                     g = (g*0x3f)/0xff;
  291.                     b = (b*0x1f)/0xff;
  292.                     rgb = (r << 11) | (g << 5) | b;
  293.                     *((uint16_t*)(fbp + location)) = rgb;
  294.                 }
  295.                 else
  296.                 {
  297.                     rgb = (r << 16) | (g << 8) | b;
  298.                     *((uint32_t*)(fbp + location)) = rgb;
  299.                 }
  300.             }
  301.         }
  302.     }
  303. #endif
  304.     munmap(fbp, screensize);
  305.     close(fbfd);
  306.     return 0;
  307. }
编译
gcc -o3 fb.c -o fb
运行
先登录桌面wetson,桌面终端中输入init 1,关闭图形桌面
(串口终端中输入init 5可恢复桌面)
./fb
image.png
效果如下
image.png