CubieBoard中文论坛

 找回密码
 立即注册
搜索
热搜: unable
查看: 10230|回复: 2

CubieAIO-S500 linux系统的异显设置

[复制链接]
发表于 2017-12-27 11:55:58 | 显示全部楼层 |阅读模式
本帖最后由 Reachy 于 2017-12-28 18:06 编辑

CubieAIO-S500的显示可以支持异屏同显,异屏异显

一,异屏同显
CubieAIO-S500 Linux系统默认工作在该模式,LCD作为主设备,HDMI 作为从设备;LCD 输出 1024*600 图像,且主设备的显示图像镜像到 HDMI时,将会进行 scale 处理,导致 HDMI 上显示的画面模糊,没有达到显示器1080p和720p的效果,不过显示还可以。
二,异屏异显
系统默认工作在异屏同显模式,可通过如下命令切换到异屏异显:
  1. # echo 0 > /sys/class/graphics/fb0/mirror_to_hdmi
复制代码
在异屏异显模式,LCD 作为主设备(/dev/fb0),HDMI 作为从设备(/dev/fb1);用户可通过/dev/fb1接口往从设备的 framebuffer 中写入显示内容,最终写入的内容将显示在 HDMI 上,可参考下面的测试程序:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <termios.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <fcntl.h>
  9. #include <signal.h>
  10. #include <sys/ipc.h>
  11. #include <sys/shm.h>
  12. #include <sys/msg.h>
  13. #include <sys/sem.h>
  14. #include <sys/mman.h>
  15. #include <linux/fb.h>
  16. #define DEV_FB         "/dev/fb1"

  17. #define PRINT_INT(e) printf("%s = %d\n", #e, e)
  18. #define PRINT_STR(e) printf("%s = %s\n", #e, e)
  19. #define PRINT_P(e) printf("%s %d %s = %p\n", __func__, __LINE__, #e, e);
  20. #define NUM_OF_COLORS 8
  21. #define COLOR_BAR_BORDER_WIDTH 32

  22. // Arguments r,g,b range from 0x00 - 0xFF
  23. #define MAKE_565_PIXEL(r,g,b)                     \
  24. (((r & 0xF8) << 8) |                                  \
  25. ((g & 0xFC) << 3) |                                  \
  26. ((b & 0xF8) >> 3))

  27. #define RED_565_PIXEL                   MAKE_565_PIXEL(255,0,0)
  28. #define GREEN_565_PIXEL                 MAKE_565_PIXEL(0,255,0)
  29. #define BLUE_565_PIXEL                  MAKE_565_PIXEL(0,0,255)
  30. #define WHITE_565_PIXEL                 MAKE_565_PIXEL(255,255,255)
  31. #define BLACK_565_PIXEL                 MAKE_565_PIXEL(0,0,0)
  32. #define CYAN_565_PIXEL                  MAKE_565_PIXEL(0,255,255)
  33. #define MAGENTA_565_PIXEL               MAKE_565_PIXEL(255,0,255)
  34. #define YELLOW_565_PIXEL                MAKE_565_PIXEL(255,255,0)

  35. // Arguments t,r,g,b range from 0x00 - 0xFF
  36. #define MAKE_8888_PIXEL(t,r,g,b)             \
  37. (((t & 0xFF) << 24) |                                  \
  38. ((r & 0xFF) << 16) |                                  \
  39. ((g & 0xFF) << 8)  |                                  \
  40. ((b & 0xFF) << 0))

  41. #define RED_8888_PIXEL                               MAKE_8888_PIXEL(0xFF,255,0,0)
  42. #define GREEN_8888_PIXEL                MAKE_8888_PIXEL(0xFF,0,255,0)
  43. #define BLUE_8888_PIXEL                 MAKE_8888_PIXEL(0xFF,0,0,255)
  44. #define WHITE_8888_PIXEL                MAKE_8888_PIXEL(0xFF,255,255,255)
  45. #define BLACK_8888_PIXEL                MAKE_8888_PIXEL(0xFF,0,0,0)
  46. #define CYAN_8888_PIXEL                 MAKE_8888_PIXEL(0xFF,0,255,255)
  47. #define MAGENTA_8888_PIXEL              MAKE_8888_PIXEL(0xFF,255,0,255)
  48. #define YELLOW_8888_PIXEL               MAKE_8888_PIXEL(0xFF,255,255,0)

  49. struct fb_fix_screeninfo fbx;
  50. struct fb_var_screeninfo fbv;
  51. int *fbp, fd;
  52. long int screensize = 0;

  53. static short color565Array[] =
  54. {
  55.     RED_565_PIXEL,
  56.     GREEN_565_PIXEL,
  57.     BLUE_565_PIXEL,
  58.     CYAN_565_PIXEL,
  59.     MAGENTA_565_PIXEL,
  60.     YELLOW_565_PIXEL,
  61.     BLACK_565_PIXEL,
  62.     WHITE_565_PIXEL,
  63. };

  64. static int color8888Array[] =
  65. {
  66.     RED_8888_PIXEL,
  67.     GREEN_8888_PIXEL,
  68.     BLUE_8888_PIXEL,
  69.     BLACK_8888_PIXEL,
  70.     WHITE_8888_PIXEL,
  71.     CYAN_8888_PIXEL,
  72.     MAGENTA_8888_PIXEL,
  73.     YELLOW_8888_PIXEL,
  74. };

  75. /*
  76. *void writecolor8888bars(int fd, int width, int height)
  77. *{
  78. *    int x, y, count, i, j;
  79. *    x = width * 2;
  80. *    //y = height / NUM_OF_COLORS;
  81. *    y = height;
  82. *    printf("x : %d, y %d\n", x, y);
  83. *    for(count = 0; count < NUM_OF_COLORS; count++)
  84. *    {
  85. *        for(i = 0; i < y; i++)
  86. *        {
  87. *            for(j = 0; j < x; j++)
  88. *            {        
  89. *                write(fd, &color8888Array[count], 4);               
  90. *            }
  91. *        }
  92. *    }
  93. *}
  94. */
  95. void writeColor8888Bars(int stride, int width, int height)
  96. {
  97.     int row,col;
  98.     int *framePtr = fbp;
  99.     int colorIndex;

  100.     printf("writeColor8888Bars:\n");
  101.     for (row = 0; row < 8; row++) printf("color[%d]: %x\n",row,color8888Array[row]);

  102.     for (row = 0; row < height; row++)
  103.     {
  104.         framePtr = (int *) (*fbp + (row * stride));

  105.         for (col = 0; col < width; col++, framePtr++)
  106.         {
  107.             if (row < COLOR_BAR_BORDER_WIDTH)
  108.             {
  109.                 colorIndex = 0;         // red top border
  110.             }
  111.             else if (row >= (height - COLOR_BAR_BORDER_WIDTH))
  112.             {
  113.                 colorIndex = 7;         // yellow bottom border
  114.             }
  115.             else
  116.             {
  117.                 colorIndex = (col * NUM_OF_COLORS) / width;
  118.             }
  119.             *framePtr = color8888Array[colorIndex];
  120.             //*((unsigned int*)(fbp + 300)) = color8888Array[1];
  121.         }
  122.     }
  123. }

  124. int main(int argc, char **argv)
  125. {
  126. int x, y;
  127.     fd = open(DEV_FB, O_RDWR);
  128. printf("open %s  fd = %d\n", DEV_FB);        
  129.         ioctl(fd, FBIOGET_VSCREENINFO, &fbv);
  130.         
  131.         ioctl(fd, FBIOGET_FSCREENINFO, &fbx);

  132.         printf("smem_len : %u \n", fbx.smem_len);
  133.         printf("line_length : %u \n", fbx.line_length);

  134.         printf("xres : %u \n", fbv.xres);
  135.         printf("yres : %u \n", fbv.yres);
  136.         printf("bits_per_pixel : %u \n", fbv.bits_per_pixel);
  137.     // Map the device to memory
  138.     screensize = fbx.line_length * fbv.yres_virtual;
  139.     printf("screensize=%d\n", (int)screensize);
  140.     fbp = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
  141.             fd, 0);
  142.     if ((int)fbp == -1)
  143.     {
  144.         printf("Error: failed to map framebuffer device to memory.\n");
  145.         exit(4);
  146.     }
  147.     printf("The framebuffer device was mapped to memory successfully at %x.\n",(unsigned int)fbp);
  148.     // blank screen
  149.     printf("Blanking screen\n");
  150.     memset (fbp, 0x00, screensize);

  151.         int i, j, count, m, n;
  152. //        int num = 0;
  153.         int num = 0xffffffff;
  154.     unsigned char t = 0xff;
  155.         unsigned char r = 0xff;
  156.         unsigned char g = 0x0;
  157.         unsigned char b = 0x0;
  158.         num = (t << 24) | (r << 16) | (g << 8) | b;
  159.     /*
  160.      *for(i = 0; i < y; i++)
  161.      *{
  162.      *    for(j = 0; j < x; j++)
  163.      *    {        
  164.      *        write(fd, &num, 4);               
  165.      *    }
  166.      *}
  167.      */
  168.     m = fbv.yres / NUM_OF_COLORS;
  169.     y = 0;
  170.     count = 1;
  171.     for(count = 0; count < NUM_OF_COLORS; count++)
  172.     {
  173.         for(; y < m * (count + 1); y++)
  174.         {
  175.             for(x = 0; x < fbv.xres; x++)
  176.             {
  177.                 write(fd, &color8888Array[count], 4);               
  178.             }
  179.         }
  180.     }
  181.     //*((unsigned int*)(fbp + x + 30)) = color8888Array[0];

  182.     munmap(fbp, screensize);
  183.         close(fd);

  184.         return 0;
  185. }
复制代码
显示效果如下:


三,主从显示设备设置
系统默认情况下, LCD 做为主显示设备; 可通过下面的方法, 将 HDMI设置为主显示设备, LCD设置为从显示设备。但是 uboot 和 kernel 的 dts相关配置需要同步修改,否则出现花屏
需要修改dts
uboot dts 文件存放位置: u-boot/arch/arm/dts/cubieaio_s500.dts
kernel dts 文件存放位置:kernel/arch/arm/boot/dts/cubieaio_s500_linux.dts
将 LCD 设置为主显示设备,如下所示:
  1. framebuffer {
  2.     compatible = "actions,framebuffer";
  3.     def_display = "<span style="background-color: Red;">HDMI</span>";
  4. };
复制代码
注意要同步修改uboot和kernel的相关配置:

然后编译所需文件
$ sudo make u-boot
$ sudo make kernel
编译后文件:
u-boot-dtb.img: u-boot/arch/arm/dts/cubieaio_s500.dts
kernel.dtb: kernel/arch/arm/boot/dts/cubieaio_s500_linux.dts
将编译生成的u-boot-dtb.imgkernel.dtb复制到CubieAIO-S500的/home/linaro目录下,通过以下命令更新:
  1. //更新uboot镜像:
  2. # sudo dd if=/home/linaro/u-boot-dtb.img of=/dev/mmcblk0 bs=512 seek=6144
  3. //更新kernel的dtb文件
  4. # sudo cp -f /home/linaro/kernel.dtb /media/linaro/misc
  5. //同步文件并重启系统
  6. # sudo sync && reboot
复制代码
如果不在乎编译时间,也可以直接重新编译成固件,然后烧入板子上
$ sudo make firmware
固件烧入参考固件烧入文档

HDMI设置为主显,LCD为副显,异屏同显OK,异屏异显,暂时还没有实现,后续再补上......


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

 楼主| 发表于 2017-12-27 11:57:45 | 显示全部楼层
占楼先
回复 支持 反对

使用道具 举报

发表于 2018-1-5 04:28:00 | 显示全部楼层
有图有真相,有干货,顶一下!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|粤ICP备13051116号|cubie.cc---深刻的嵌入式技术讨论社区

GMT+8, 2024-4-18 19:44 , Processed in 0.029031 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2012 Comsenz Inc. | Style by Coxxs

返回顶部