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不一致。
参考 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除去了浮点的所有功能,如此之后,一下子程序就变得很小了。
而另外两个函数是动态链接,其链接过程是动态的在可执行程序执行的时候进行链接的。 既然提到使用print 和 printf 和 xil_printf的内存问题,那么,我们就来做个实验看看,到底怎么节省内存法。 (4) printf打印带参数语句 (6)多个xil_printf打印带参数语句 总之,需要打印字符串就使用print函数,需要打印浮点数就使用printf,需要打印整点数就使用xil_printf就没错了。 可能的话最好所有打印都不要出现printf,只要有一个都会使内存增加不少。 欢迎分享,转载请注明来源:内存溢出
如果用专业一点的术语描述,就是使用printf链接过程是静态链接,静态链接的时候他进行链接的是一整个
(1)printf打印字符串#include
(2)print打印字符串void main(void){
print("helloworld\n");
}
(3)xil_printf打印字符串#include "xil_printf.h"
void main(void){
xil_printf("helloworld\n");
}
这三个实验结论:使用print打印字符串最节省内存#include
(5) xil_printf打印带参数语句#include "xil_printf.h"
void main(void){
xil_printf("helloworld,%d\n",1);
}
结论:除非是打印浮点数,打印整点使用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
结论:无论是printf 还是xil_printf 多个打印语句不会显著增加内存
评论列表(0条)