ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示

目录

0 - 前言

1 - petalinux工程的建立与配置

2 - 将解码驱动配置到linux内核中

3 - petalinux配置linux内核

4 - 修改设备树

5 - 编译打包

6 - 文件修改

X - 附录 问题


0 - 前言

在前面的文章里(ZYNQ7000 #0 - petalinux的使用与工程建立),我们已经使用 petalinux 成功的配置了一个可以在板子上运行的linux系统环境。这篇文章中我们加上HDMI向外输出图像信号的功能。

我的开发板是黑金的AX7010,其附带的资料对于这方面讲解的不是很清楚,我也是通过翻找其教程中提到的 “使用Debian系统”附带的Debian根文件系统解决的在使用 startx 唤起 X 桌面环境后黑屏的问题。究其主要原因还是 需要对 X 桌面环境进行设置,要求其使用FrameBuffer进行绘制

AX7010这个开发板上虽然有HDMI-A的母头,但是其并没有板载HDMI芯片,而其对外输出HDMI信号的方式是利用PL端的IO对HDMI信号的时钟和数据进行模拟达到的。这里不过多的介绍关于其如何搭建PL端的方法,而重点关注如何在这样的环境中配置 X 桌面环境利用FrameBuffer进行图像绘制。

这里我们需要准备的是:

  • 开发宿主机:ubuntu 16.04.4 LTS
  • Petalinux:petalinux 2018.3
  • Petalinux配套的Linux源码:linux-xlnx-xlnx_rebase_v4.14_2018.3
  • Vivado工程生成的 .sdk 文件:linux_base.sdk                     (这个工程是黑金的例程)
  • Digilent提供的IP
    • 视频解码IP:RGB to DVI Video Encoder
    • 动态时钟IP:Dynamic Clock Generator
    • 视频解码IP RGB to DVI Video Encoder上用到的接口:TMDS
  • Digilent提供的视频解码驱动(encoder)和时钟驱动(clk):  (从黑金提供的2017版源码里找到的,可以从digilent的github上找到)
    • drivers/clk/clk-dglnt-dynclk.c
    • drivers/gpu/drm/xilinx/digilent_encoder.c

连接完后大致的框图如下:

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第1张图片

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第2张图片

1 - petalinux工程的建立与配置

petalinux工程的建立、从 .sdk 导入硬件工程配置、配置rootfs放置在SD卡 以及 配置使用外部linux源码的方法可以看这篇文章(ZYNQ7000 #0 - petalinux的使用与工程建立)

 

2 - 将解码驱动配置到linux内核中

如果你使用的是petalinux 2019.1或者更高的版本,因为其linux使用的内核为4.19,其内部有部分函数进行了修改,需要将digilent_encoder中的

drm_mode_connector_update_edid_property(connector, edid);

替换为

drm_connector_update_edid_property(connector, edid);

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第3张图片

具体参考 https://forums.gentoo.org/viewtopic-t-1088330-start-0.html

首先按照上述准备工作中的路径将 clk-fixed-factor.c 时钟驱动文件, digilent_encoder.c 视频解码驱动文件放置到Linux源码路径下。

  • 配置 clk-dglnt-dynclk

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/clk/Kconfig 将 clk-dglnt-dynclk.c 的配置项放入menuconfig中

config COMMON_CLK_DGLNT_DYNCLK
	tristate "Digilent axi_dynclk Driver"
	depends on ARCH_ZYNQ || MICROBLAZE
	help
	---help---
	  Support for the Digilent AXI Dynamic Clock core for Xilinx
	  FPGAs.

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第4张图片

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/clk/Makefile 使得 clk-dglnt-dynclk.c 在menuconfig配置好后在linux编译时能编译。

obj-$(CONFIG_COMMON_CLK_DGLNT_DYNCLK)	+= clk-dglnt-dynclk.o

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第5张图片

  • 配置 digilent_encoder

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/gpu/drm/xilinx/Kconfig,将 digilent_encoder.c 的配置项放入menuconfig中

config DRM_DIGILENT_ENCODER
	tristate "Digilent VGA/HDMI DRM Encoder Driver"
	depends on DRM_XILINX
	help
	  DRM slave encoder for Video-out on Digilent boards.

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第6张图片

打开 linux-xlnx-xlnx_rebase_v4.14_2018.3/drivers/gpu/drm/xilinx/Makefile,使得 digilent_encoder.c 在menuconfig配置好后在linux编译时能编译。

obj-$(CONFIG_DRM_DIGILENT_ENCODER) += digilent_encoder.o

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第7张图片

 

3 - petalinux配置linux内核

运行命令,配置内核

petalinux-config -c kernel

在 Device Drivers -> Graphics support,选择 Digilent VGA/HDMI DRM Encoder Driver 项按 y。

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第8张图片

在 Device Drivers → Common Clock Framework 选项中选择 Digilent axi_dynclk Driver 按 y

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第9张图片

保存退出

注意:这里不要修改默认的保存文件名 ( .config )

 

4 - 修改设备树

这里我是直接用的黑金写的设备树。

打开petalinux工程文件夹中 project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi,刚生成petalinux的工程文件夹中,这个dtsi文件是空的,将其修改为以下内容。

/include/ "system-conf.dtsi"

/ {
	model = "Zynq ALINX Development Board";
	compatible = "alinx,zynq", "xlnx,zynq-7000";
	aliases {
		ethernet0 = "&gem0";
		serial0 = "&uart1";
	};

	usb_phy0: usb_phy@0 {
		compatible = "ulpi-phy";
		#phy-cells = <0>;
		reg = <0xe0002000 0x1000>;
		view-port = <0x0170>;
		drv-vbus;
	};


};

&i2c0 {
	clock-frequency = <100000>;
};

&usb0 {
	dr_mode = "host";	
	usb-phy = <&usb_phy0>;
};

&sdhci0 {
	u-boot,dm-pre-reloc;
};

&uart1 {
	u-boot,dm-pre-reloc;
};


&flash0 {
	compatible = "micron,m25p80", "w25q256", "spi-flash";
};


&gem0 {
	phy-handle = <ðernet_phy>;
	ethernet_phy: ethernet-phy@1 {
		reg = <1>;
		device_type = "ethernet-phy";
	};
};



&amba_pl {

	hdmi_encoder_0:hdmi_encoder {
		compatible = "digilent,drm-encoder";
		digilent,edid-i2c = <&i2c0>;
	};

	xilinx_drm {
		compatible = "xlnx,drm";
		xlnx,vtc = <&v_tc_0>;
		xlnx,connector-type = "HDMIA";
		xlnx,encoder-slave = <&hdmi_encoder_0>;
		clocks = <&axi_dynclk_0>;
		dglnt,edid-i2c = <&i2c0>;
		planes {
			xlnx,pixel-format = "rgb888";
			plane0 {
				dmas = <&axi_vdma_0 0>;
				dma-names = "dma";
			};
		};
	};
};
&axi_dynclk_0 {
	compatible = "digilent,axi-dynclk";
	#clock-cells = <0>;
	clocks = <&clkc 15>;
};
&v_tc_0 {
	compatible = "xlnx,v-tc-5.01.a";
};

这里面最重要的部分是 amba_pl 下的 hdmi_encoder 和 xilinx_drm部分的设置

 

5 - 编译打包

用下面命令编译uboot、内核、根文件系统、设备树等

petalinux-build

用下面命令打包生成 BOOT.BIN 文件

petalinux-package --boot --fsbl ./images/linux/zynq_fsbl.elf --fpga --u-boot --force

将生成的 BOOT.BIN 及 image.ub 拷贝到 SD 卡的FAT分区,根文件系统已放置到EXT分区

 

6 - 文件修改

  • /etc/X11/xorg.conf.d 下的 99-fbdev.conf

这里我是之前建立ubuntu文件系统的时候就已经在该文件夹下加入了一个 40-libinput.conf(建立ubuntu文件系统参考这里https://blog.csdn.net/sements/article/details/88086468

这里只是为了让 X 界面系统启动的时候设定利用framebuffer进行绘制,所以有两种可选的方法。第一种在该目录(/etc/X11/xorg.conf.d   没有这个目录就创建即可)下已有的 40-libinput.conf 配置文件中加入语句。第二种就是新建一个 .conf 文件,这里叫它 99-fbdev.conf (前面的数字影响着 X 界面系统启动加载这些配置文件时的顺序),然后在这个文件中加入语句。

Section "Device"  
  Identifier "myfb"
  Driver "fbdev"
  Option "fbdev" "/dev/fb0"
EndSection
  • /etc/X11/xinit/xinitrc 文件

/etc/X11/xinit/xinitrc 文件是在调用语句 startx 后回加载的脚本,这里我面进行了一些操作:

1.载入变量 "export DISPLAY=:0.0",

2.关闭了 X 桌面系统的电源管理和屏幕保护

3.加载了我自己写的一个有界面的小程序

4. 唤起openbox-session

#!/bin/sh

# /etc/X11/xinit/xinitrc
#
# global xinitrc file, used by all X sessions started by xinit (startx)

# invoke global X session script
#. /etc/X11/Xsession

export DISPLAY=:0.0
echo "TURN OFF DPMS"
xset s off
xset dpms 0 0 0
xset -dpms

/home/sements/developArea/RailTranser-Studio/RailTranser-Studio/RailTranser-Studio &
#xeyes&

openbox-session 
  • /etc/rc.local

这个文件是一种比较老旧的 Linux 开机启动自定义命令的方法,这个文件里面我做了一些操作

1.唤起 eth0 ,并使用 dhclient 自动获取 ip 地址

2.使用 startx 命令唤起 X 桌面系统(其运行后就会加载 /etc/X11/xinit/xinitrc 文件脚本和 /etc/X11/xorg.conf.d 下的本机配置项)

#!/bin/bash

ifconfig eth0 up &
dhclient &

startx &

exit 0

为了使 rc.local 开机运行脚本,不要忘了给它加上可执行权限

 

X - 附录 问题

在没有正确的配置 X 使用 Framebuffer进行绘制时,使用 startx 开启图形界面时可能出现以下错误

  • Failed to launch bus: Failed to connect to session bus
  • 唤醒了 X 但是黑屏
  • AddScreen/ScreenInit failed for driver 0
  • 等等

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第10张图片

 

ZYNQ7000 #1 - PL端模拟HDMI信号输出环境下的Linux界面显示_第11张图片 救救穷学生,5毛买包托肥

你可能感兴趣的:(ZYNQ7000,Linux,嵌入式)