让ZYNQ的两个串口UART0和1都可以愉快的printf

序章

在日常使用串口通信的时候,我们更倾向于使用printf来进行各种信息的输出,尤其是当我们需要使用明文传输时,例如驱动一个串口屏,使用printf函数可以大大简化代码的工作量,避免我们使用非常底层的串口发送函数。

在Xilinx SDK中可以使用两种printf函数,一种是包含stdio.h后可以使用的printf,另一种是包含xil_printf.h后可以使用的xil_printf,如果你尝试执行这两个函数,你会发现他们都重定向到了UART 0。当然,ZYNQ 7010具有两个硬件UART外设,如果你两个都启用了,他会默认映射到UART 0,如果你只启用了UART 1,那么自然会默认映射到UART 1。

image-20220714140638557

image-20220714140614122

而我们更希望能够同时使用printf函数到两个不同的UART,这时就需要对UART 1也进行printf重定向。

在stdio库中的printf不知道连接到哪里去了,看着不是很好欺负

image-20220714141106956

但是xil_printf这个就(拜托,你很弱哎)

image-20220714141233916

观察后,发现这里似乎是xilinx自己写的串口标准格式化程序。那么我们只需要找到他与底层串口发送连接的函数

image-20220714141608875

发现了野生的outbyte函数,点进去一看果不其然,这里直接连接到了XUartPS的底层函数

image-20220714141640773

接下来要做的就很简单了,新建一个outbyte函数,clone一份xil_printf函数,就可以达成目标。

最后还有一个值得注意的地方就是串口的基地址,在outbyte函数中进行修改即可

image-20220714141920684

image-20220714142049219

image-20220714142107596

完成了?

三板斧干下来,已经可以愉快的喷射了(printf)

image-20220714142317062

偶遇BUG

但是万万没想到啊,这玩意还带bug的,居然能把UART1的%d里头的东西打印到UART0里去,一定是什么东西没有替换干净!

image-20220714145120227

经过仔细观察发现,他的单个字符和数字是分开的两种不同函数,这个也可以理解,因为数字是需要格式化的,那么肯定需要单独的一块代码来处理他的格式化

image-20220714145620747

同样的代理,我们只需要找到outnum等一系列函数,将他们中包含outchar的所有都替换掉就可以将这个bug解决了。跟这个函数类似的还有一个outs函数和padding函数,也需要进行替换的

image-20220714151047572

于是,在经过修改大量函数名的操作后,终于解决了bug

image-20220714150959057

发表评论