1 背景
项目实施过程中,采用zynq系列芯片,由于zynq自身PS侧仅仅提供两路串口,无法满足实际需求。这就需要从PL侧扩展出来多路串口出来。网上也有一些针对的使用步骤,但是都不够友好,缺少很多细节上的步骤,很难调试成功。本文详解一下实际实现的步骤,供大家参考学习使用。
本文针对uartlite的详细使用说明,axi_uartlite也有一定的缺点比如波特率无法软件设定,只能是vivado工程修改,这样就比较麻烦。uart16650就凸显其优势了,但是uart16650占用资源也多,有利有弊,还是要看实际工程项目的需要。关于uart16650参考下属资源:
深入理解zynquart16550的使用(含vivado工程、设备树、内核配置、步骤文档),PL实现9路uart16550_uart16550,uart16550和uartlite资源-CSDN下载
如果uart太多了,就会导致中断不够用。该怎么办呢?下述资源提出使用axi_intc 实现大于16路以上uartlite来解决这个问题。
zynq使用intc实现大于16路以上uartlite,内涵vivado工程,设备树,详细步骤说明文档_xilinxplintc资源-CSDN下载
2 vivado工程
2.1 BD设计
这里使用axi_uartlite IP添加8路串口,BD中涉及uartlite相关内容如下:

2.2 顶层设计
VIVADO工程在顶层文件中,将串口的收发管脚短接,方便环路测试
顶层环路相关代码如下:
wire uart0_rx_tx;
wire uart1_rx_tx;
wire uart2_rx_tx;
wire uart3_rx_tx;
wire uart4_rx_tx;
wire uart5_rx_tx;
wire uart6_rx_tx;
wire uart7_rx_tx;
wire uart8_rx_tx;
.uart_rtl_0_rxd(uart0_rx_tx),
.uart_rtl_0_txd(uart0_rx_tx),
.uart_rtl_1_rxd(uart1_rx_tx),
.uart_rtl_1_txd(uart1_rx_tx),
.uart_rtl_2_rxd(uart2_rx_tx),
.uart_rtl_2_txd(uart2_rx_tx),
.uart_rtl_3_rxd(uart3_rx_tx),
.uart_rtl_3_txd(uart3_rx_tx),
.uart_rtl_4_rxd(uart4_rx_tx),
.uart_rtl_4_txd(uart4_rx_tx),
.uart_rtl_5_rxd(uart5_rx_tx),
.uart_rtl_5_txd(uart5_rx_tx),
.uart_rtl_6_rxd(uart6_rx_tx),
.uart_rtl_6_txd(uart6_rx_tx),
.uart_rtl_7_rxd(uart7_rx_tx),
.uart_rtl_7_txd(uart7_rx_tx),
.uart_rtl_8_rxd(uart8_rx_tx),
.uart_rtl_8_txd(uart8_rx_tx)
2.3 资源下载
本文使用vivado工程,和设备树文件如下链接:
《一文精通zynquartlite的使用》vivado工程,设备树文件,PL使用uartlite例化9路串口,详细步骤文档资源-CSDN文库
3 设备树
在pl.dtsi文件中,自动生成如下设备树信息
axi_uartlite_0: serial@42c00000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 29 1>;
port-number = <0>;
reg = <0x42c00000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_1: serial@42c10000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 30 1>;
port-number = <2>;
reg = <0x42c10000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_2: serial@42c20000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 31 1>;
port-number = <3>;
reg = <0x42c20000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_3: serial@42c30000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 32 1>;
port-number = <4>;
reg = <0x42c30000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_4: serial@42c40000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 33 1>;
port-number = <5>;
reg = <0x42c40000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_5: serial@42c50000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 34 1>;
port-number = <6>;
reg = <0x42c50000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_6: serial@42c60000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 35 1>;
port-number = <7>;
reg = <0x42c60000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_7: serial@42c70000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 36 1>;
port-number = <8>;
reg = <0x42c70000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
axi_uartlite_8: serial@42c80000 {
clock-names = "s_axi_aclk";
clocks = <&clkc 15>;
compatible = "xlnx,axi-uartlite-2.0", "xlnx,xps-uartlite-1.00.a";
current-speed = <9600>;
device_type = "serial";
interrupt-names = "interrupt";
interrupt-parent = <&intc>;
interrupts = <0 52 1>;
port-number = <9>;
reg = <0x42c80000 0x10000>;
xlnx,baudrate = <0x2580>;
xlnx,data-bits = <0x8>;
xlnx,odd-parity = <0x0>;
xlnx,s-axi-aclk-freq-hz-d = "50.0";
xlnx,use-parity = <0x0>;
};
4 内核
4.1 uartlite内核配置项
打开uartlite内核驱动,我使用的内核版本中,没有说明uartlite最大支持多少路的配置,所以不用关注,如下图所示打开驱动配置即可。

这里看使用的内核版本号,高版本的内核版本需要配置一下使用的串口数量的上限如下图所示

5 上板调试
BD文件中例化9个uartlite串口,在顶层文件将收发管脚短接,所以使用何种开发板测试都比较方便。
5.1 启动log
Linux启动过程关键log如下,这里看
PS串口识别如下

PL串口识别如下

5.2 串口文件节点
/dev/下串口节点查看如下图:

5.3 自发自收测试
这里使用了一个串口应用uart_app,在我之前的博客有介绍该软件的使用(提供了该软件的源码和makfile),感兴趣的同学,可以翻翻之前的博客,这里就直接截图测试结果如下:


6 不踩坑必读
6.1 关于中断线
VIVADO工程必须连接axi_uartlite IP的中断线,不然驱动无法正确加载,/dev下无对应的串口节点。
6.2 串口数量大于16
如果使用更多了大于16路axi_uartlite IP,PL-PS中断线不够使用,该怎么办呢?留个问题,文中资源已经给出答案。

6.3 参数配置
axi_uartlite在Linux应用层无法配置串口参数,如波特率等,配置了也没有用,只能在VIVADO工程中配置,配置完后要重新更新bit流文件、设备树文件等相关烧录文件。如下图所示

7 资源下载
本文使用vivado工程,和设备树文件如下链接:
《一文精通zynquartlite的使用》vivado工程,设备树文件,PL使用uartlite例化9路串口,详细步骤文档资源-CSDN文库
本文针对uartlite的详细使用说明,axi_uartlite也有一定的缺点比如波特率无法软件设定,只能是vivado工程修改,这样就比较麻烦。uart16650就凸显其优势了,但是uart16650占用资源也多,有利有弊,还是要看实际工程项目的需要。关于uart16650参考下属资源:
深入理解zynquart16550的使用(含vivado工程、设备树、内核配置、步骤文档),PL实现9路uart16550_uart16550,uart16550和uartlite资源-CSDN下载
如果uart太多了,就会导致中断不够用。该怎么办呢?下述资源提出使用axi_intc 实现大于16路以上uartlite来解决这个问题。
zynq使用intc实现大于16路以上uartlite,内涵vivado工程,设备树,详细步骤说明文档_xilinxplintc资源-CSDN下载
本文详细描述了如何在Zynq项目中扩展串口,使用Vivado进行BD设计,包括添加AXI_UARTliteIP、顶层文件中的串口短接以及设备树配置。作者还提供了中断处理、内核配置和上板调试的关键步骤,以及注意事项,如中断线连接和波特率配置的限制。

4524

被折叠的 条评论
为什么被折叠?



