ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil

ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil,第1张

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

ZYNQ开发系列——SDK输出串口选择以及打印函数print、printf、xil_printf的差别
  • 前言
  • 两个串口到底是谁在打印?
  • print 和 printf 和 xil_printf


前言

在最初的helloworld工程中,我们实现了通过串口每个1秒钟打印一次Hello World。


#include "platform.h"
#include "xil_printf.h"


int main()
{
    init_platform();

    while(1)
    {
    	print("Hello World\n\r");
    	sleep(1);
    }

    cleanup_platform();
    return 0;
}

这里我们就来搞清楚以下几个问题,从简单到复杂问题依次为:
1、 我们有两个串口,那怎么区分是从哪个串口打印的
2、 为什么是print函数,一般C标准打印函数是printf呢
3、 如果我两个串口都想打印东西怎么弄
4、 串口的波特率如何修改,最大能支持多少
后面2点放到另一篇文章讲。


两个串口到底是谁在打印?

一开始我们就定义了两个串口,在xparameter.h中的描述如下#

二、使用步骤

/* Definitions for driver UARTPS */
#define XPAR_XUARTPS_NUM_INSTANCES 2

/* Definitions for peripheral PS7_UART_0 */
#define XPAR_PS7_UART_0_DEVICE_ID 0
#define XPAR_PS7_UART_0_BASEADDR 0xE0000000
#define XPAR_PS7_UART_0_HIGHADDR 0xE0000FFF
#define XPAR_PS7_UART_0_UART_CLK_FREQ_HZ 100000000
#define XPAR_PS7_UART_0_HAS_MODEM 0


/* Definitions for peripheral PS7_UART_1 */
#define XPAR_PS7_UART_1_DEVICE_ID 1
#define XPAR_PS7_UART_1_BASEADDR 0xE0001000
#define XPAR_PS7_UART_1_HIGHADDR 0xE0001FFF
#define XPAR_PS7_UART_1_UART_CLK_FREQ_HZ 100000000
#define XPAR_PS7_UART_1_HAS_MODEM 0


那怎么知道以及设置是要从UART_0打印还是UART_1打印呢?
我们进入print.c文件,找到outbyte函数,里面内容为
XUartPs_SendByte(STDOUT_BASEADDRESS, c);
这个STDOUT_BASEADDRESS的定义为:

#define STDIN_BASEADDRESS 0xE0000000
#define STDOUT_BASEADDRESS 0xE0000000

这个就正好和XPAR_PS7_UART_0_BASEADDR吻合了,也即是说,我们当前使用的哪个串口,与这两个宏定义设置有关。



因此我们如果想换成UART_1打印,只要将STDOUT_BASEADDRESS 改成0xE0001000即可,同时STDIN_BASEADDRESS这个也应同步修改。


还有一种方式是,直接在mss文件中修改

而且这里修改会同步对xparameter.h处的STDIN_BASEADDRESS和STDOUT_BASEADDRESS进行修改。


因此如果我们要修改要打印的串口,我觉得最好还是通过第二种方式修改(修改mss文件中的配置),因为第一种方式修改后会和mss中显示的stdin和stdout不一致。


print 和 printf 和 xil_printf

参考 https://www.youtube.com/watch?v=f2pPIRHc0bM

我们阐述下三种打印的差别
差别1:
1、printf 是调用C标准库,使用printf的时候需要加头文件 #include
2、print 和 xil_printf是使用xilinx自己的库 #include “xil_printf.h”
差别2:
1、 print只能打印字符串
2、 xil_printf和printf,可以带参量打印,但是xil_printf不支持打印浮点数

xilinx的SDK工具支持标准的c库,比如我们最日常使用的printf函数,就是标准c库里的一个重要函数。


但是标准c库所谓的标准性,或者所谓的通用性带来的问题就是它必须面对所有的情况,而一些情况在fpga设计中是普通情况下是极少碰到的,比如正常情况下,浮点处理是很少用的。


如此之后,这个函数必然会变得体态臃肿。


比如这里的printf函数。


不知道大家有没有这样的经验,使用printf函数,你的程序最后编译出来变的很大~其实xil_printf和printf的功能是一样的,只是xil_printf除去了浮点的所有功能,如此之后,一下子程序就变得很小了。



如果用专业一点的术语描述,就是使用printf链接过程是静态链接,静态链接的时候他进行链接的是一整个,而且静态链接的特点在于他是直接把这个对象文件加入到了可执行文件当中,极大的浪费了内存空间。


而另外两个函数是动态链接,其链接过程是动态的在可执行程序执行的时候进行链接的。


既然提到使用print 和 printf 和 xil_printf的内存问题,那么,我们就来做个实验看看,到底怎么节省内存法。



(1)printf打印字符串

#include 
void main(void){
	printf("helloworld\n");
}



(2)print打印字符串

void main(void){
	print("helloworld\n");
}



(3)xil_printf打印字符串

#include "xil_printf.h"
void main(void){
	xil_printf("helloworld\n");
}



这三个实验结论:使用print打印字符串最节省内存

(4) printf打印带参数语句

#include 
void main(void){
	printf("helloworld,%d\n",1);
}



(5) xil_printf打印带参数语句

#include "xil_printf.h"
void main(void){
	xil_printf("helloworld,%d\n",1);
}



结论:除非是打印浮点数,打印整点使用xil_printf节省内存

(6)多个xil_printf打印带参数语句

#include "xil_printf.h"
void main(void){
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
	xil_printf("helloworld,%d\n\r",1);
}



(7) 多个printf打印带参数语句

#include 
void main(void){
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);
	printf("helloworld,%d\n\r",1);

}



结论:无论是printf 还是xil_printf 多个打印语句不会显著增加内存

总之,需要打印字符串就使用print函数,需要打印浮点数就使用printf,需要打印整点数就使用xil_printf就没错了。


可能的话最好所有打印都不要出现printf,只要有一个都会使内存增加不少。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/579136.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存