CubieAIO-S500 linux系统的异显设置
本帖最后由 Reachy 于 2017-12-28 18:06 编辑CubieAIO-S500的显示可以支持异屏同显,异屏异显
一,异屏同显
CubieAIO-S500 Linux系统默认工作在该模式,LCD作为主设备,HDMI 作为从设备;LCD 输出 1024*600 图像,且主设备的显示图像镜像到 HDMI时,将会进行 scale 处理,导致 HDMI 上显示的画面模糊,没有达到显示器1080p和720p的效果,不过显示还可以。
二,异屏异显
系统默认工作在异屏同显模式,可通过如下命令切换到异屏异显:# echo 0 > /sys/class/graphics/fb0/mirror_to_hdmi在异屏异显模式,LCD 作为主设备(/dev/fb0),HDMI 作为从设备(/dev/fb1);用户可通过/dev/fb1接口往从设备的 framebuffer 中写入显示内容,最终写入的内容将显示在 HDMI 上,可参考下面的测试程序:#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/mman.h>
#include <linux/fb.h>
#define DEV_FB "/dev/fb1"
#define PRINT_INT(e) printf("%s = %d\n", #e, e)
#define PRINT_STR(e) printf("%s = %s\n", #e, e)
#define PRINT_P(e) printf("%s %d %s = %p\n", __func__, __LINE__, #e, e);
#define NUM_OF_COLORS 8
#define COLOR_BAR_BORDER_WIDTH 32
// Arguments r,g,b range from 0x00 - 0xFF
#define MAKE_565_PIXEL(r,g,b) \
(((r & 0xF8) << 8) | \
((g & 0xFC) << 3) | \
((b & 0xF8) >> 3))
#define RED_565_PIXEL MAKE_565_PIXEL(255,0,0)
#define GREEN_565_PIXEL MAKE_565_PIXEL(0,255,0)
#define BLUE_565_PIXEL MAKE_565_PIXEL(0,0,255)
#define WHITE_565_PIXEL MAKE_565_PIXEL(255,255,255)
#define BLACK_565_PIXEL MAKE_565_PIXEL(0,0,0)
#define CYAN_565_PIXEL MAKE_565_PIXEL(0,255,255)
#define MAGENTA_565_PIXEL MAKE_565_PIXEL(255,0,255)
#define YELLOW_565_PIXEL MAKE_565_PIXEL(255,255,0)
// Arguments t,r,g,b range from 0x00 - 0xFF
#define MAKE_8888_PIXEL(t,r,g,b) \
(((t & 0xFF) << 24) | \
((r & 0xFF) << 16) | \
((g & 0xFF) << 8)| \
((b & 0xFF) << 0))
#define RED_8888_PIXEL MAKE_8888_PIXEL(0xFF,255,0,0)
#define GREEN_8888_PIXEL MAKE_8888_PIXEL(0xFF,0,255,0)
#define BLUE_8888_PIXEL MAKE_8888_PIXEL(0xFF,0,0,255)
#define WHITE_8888_PIXEL MAKE_8888_PIXEL(0xFF,255,255,255)
#define BLACK_8888_PIXEL MAKE_8888_PIXEL(0xFF,0,0,0)
#define CYAN_8888_PIXEL MAKE_8888_PIXEL(0xFF,0,255,255)
#define MAGENTA_8888_PIXEL MAKE_8888_PIXEL(0xFF,255,0,255)
#define YELLOW_8888_PIXEL MAKE_8888_PIXEL(0xFF,255,255,0)
struct fb_fix_screeninfo fbx;
struct fb_var_screeninfo fbv;
int *fbp, fd;
long int screensize = 0;
static short color565Array[] =
{
RED_565_PIXEL,
GREEN_565_PIXEL,
BLUE_565_PIXEL,
CYAN_565_PIXEL,
MAGENTA_565_PIXEL,
YELLOW_565_PIXEL,
BLACK_565_PIXEL,
WHITE_565_PIXEL,
};
static int color8888Array[] =
{
RED_8888_PIXEL,
GREEN_8888_PIXEL,
BLUE_8888_PIXEL,
BLACK_8888_PIXEL,
WHITE_8888_PIXEL,
CYAN_8888_PIXEL,
MAGENTA_8888_PIXEL,
YELLOW_8888_PIXEL,
};
/*
*void writecolor8888bars(int fd, int width, int height)
*{
* int x, y, count, i, j;
* x = width * 2;
* //y = height / NUM_OF_COLORS;
* y = height;
* printf("x : %d, y %d\n", x, y);
* for(count = 0; count < NUM_OF_COLORS; count++)
* {
* for(i = 0; i < y; i++)
* {
* for(j = 0; j < x; j++)
* {
* write(fd, &color8888Array, 4);
* }
* }
* }
*}
*/
void writeColor8888Bars(int stride, int width, int height)
{
int row,col;
int *framePtr = fbp;
int colorIndex;
printf("writeColor8888Bars:\n");
for (row = 0; row < 8; row++) printf("color[%d]: %x\n",row,color8888Array);
for (row = 0; row < height; row++)
{
framePtr = (int *) (*fbp + (row * stride));
for (col = 0; col < width; col++, framePtr++)
{
if (row < COLOR_BAR_BORDER_WIDTH)
{
colorIndex = 0; // red top border
}
else if (row >= (height - COLOR_BAR_BORDER_WIDTH))
{
colorIndex = 7; // yellow bottom border
}
else
{
colorIndex = (col * NUM_OF_COLORS) / width;
}
*framePtr = color8888Array;
//*((unsigned int*)(fbp + 300)) = color8888Array;
}
}
}
int main(int argc, char **argv)
{
int x, y;
fd = open(DEV_FB, O_RDWR);
printf("open %sfd = %d\n", DEV_FB);
ioctl(fd, FBIOGET_VSCREENINFO, &fbv);
ioctl(fd, FBIOGET_FSCREENINFO, &fbx);
printf("smem_len : %u \n", fbx.smem_len);
printf("line_length : %u \n", fbx.line_length);
printf("xres : %u \n", fbv.xres);
printf("yres : %u \n", fbv.yres);
printf("bits_per_pixel : %u \n", fbv.bits_per_pixel);
// Map the device to memory
screensize = fbx.line_length * fbv.yres_virtual;
printf("screensize=%d\n", (int)screensize);
fbp = (int *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, 0);
if ((int)fbp == -1)
{
printf("Error: failed to map framebuffer device to memory.\n");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully at %x.\n",(unsigned int)fbp);
// blank screen
printf("Blanking screen\n");
memset (fbp, 0x00, screensize);
int i, j, count, m, n;
// int num = 0;
int num = 0xffffffff;
unsigned char t = 0xff;
unsigned char r = 0xff;
unsigned char g = 0x0;
unsigned char b = 0x0;
num = (t << 24) | (r << 16) | (g << 8) | b;
/*
*for(i = 0; i < y; i++)
*{
* for(j = 0; j < x; j++)
* {
* write(fd, &num, 4);
* }
*}
*/
m = fbv.yres / NUM_OF_COLORS;
y = 0;
count = 1;
for(count = 0; count < NUM_OF_COLORS; count++)
{
for(; y < m * (count + 1); y++)
{
for(x = 0; x < fbv.xres; x++)
{
write(fd, &color8888Array, 4);
}
}
}
//*((unsigned int*)(fbp + x + 30)) = color8888Array;
munmap(fbp, screensize);
close(fd);
return 0;
}显示效果如下:
三,主从显示设备设置
系统默认情况下, 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 设置为主显示设备,如下所示:framebuffer {
compatible = "actions,framebuffer";
def_display = "<span style="background-color: Red;">HDMI</span>";
};注意要同步修改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.img和kernel.dtb复制到CubieAIO-S500的/home/linaro目录下,通过以下命令更新://更新uboot镜像:
# sudo dd if=/home/linaro/u-boot-dtb.img of=/dev/mmcblk0 bs=512 seek=6144
//更新kernel的dtb文件
# sudo cp -f /home/linaro/kernel.dtb /media/linaro/misc
//同步文件并重启系统
# sudo sync && reboot如果不在乎编译时间,也可以直接重新编译成固件,然后烧入板子上
$ sudo make firmware
固件烧入参考固件烧入文档
HDMI设置为主显,LCD为副显,异屏同显OK,异屏异显,暂时还没有实现,后续再补上......
占楼先:) 有图有真相,有干货,顶一下!
页:
[1]