一文精通zynq uartlite的使用

本文详细描述了如何在Zynq项目中扩展串口,使用Vivado进行BD设计,包括添加AXI_UARTliteIP、顶层文件中的串口短接以及设备树配置。作者还提供了中断处理、内核配置和上板调试的关键步骤,以及注意事项,如中断线连接和波特率配置的限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 背景

项目实施过程中,采用zynq系列芯片,由于zynq自身PS侧仅仅提供两路串口,无法满足实际需求。这就需要从PL侧扩展出来多路串口出来。网上也有一些针对的使用步骤,但是都不够友好,缺少很多细节上的步骤,很难调试成功。本文详解一下实际实现的步骤,供大家参考学习使用。

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路串口,详细步骤文档资源-优快云文库

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路串口,详细步骤文档资源-优快云文库

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大牛攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值