ZYNQ中PS端打印函数print、printf、xil_printf的差别

本文比较了C标准库的printf、Xilinx自定义的print和xil_printf在FPGA设计中的差异,指出xil_printf去除了浮点数功能以节省内存。通过实验,作者发现多次打印语句对内存影响不大,推荐根据需求选择合适的函数来控制内存消耗。

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

我们阐述下三种打印的差别
差别1:
1、printf 是调用C标准库,使用printf的时候需要加头文件 #include <stdio.h>
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链接过程是静态链接,静态链接的时候他进行链接的是一整个<stdio.h>,而且静态链接的特点在于他是直接把这个对象文件加入到了可执行文件当中,极大的浪费了内存空间。而另外两个函数是动态链接,其链接过程是动态的在可执行程序执行的时候进行链接的。

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

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

总之,需要打印字符串就使用print函数,需要打印浮点数就使用printf,需要打印整点数就使用xil_printf就没错了。可能的话最好所有打印都不要出现printf,只要有一个都会使内存增加不少。

<think>嗯,用户询问的是ZYNQ平台的FSBL例程中fsbl_printf()函数没有打印输出问题。这个问题在嵌入式开发中挺典型的,需要系统性地排查。 用户给出的四条引用其实提供了重要线索:引用[1]提到BOOT.bin文件生成时需要添加CORE0和CORE1的elf文件,暗示多核启动流程可能影响调试输出;引用[2]提到网络调试的复杂性,间接说明串口可能是更可靠的调试通道;引用[3]涉及自定义单板开发,暗示硬件差异可能导致外设配置变化;引用[4]提到双核通信,虽然不直接相关但说明用户可能在复杂环境下工作。 考虑从三个层面分析原因:最底层硬件连接层面,包括串口电平匹配问题(例如用户板卡可能是1.8V而调试器是3.3V)、接线错误(RX/TX反接)、时钟配置错误等;中间驱动层面,Xilinx FSBL默认使用UART0,但有用户反馈某些自定义板可能映射到UART1,此外DDR初始化失败会导致内存操作异常;顶层配置层面,最常见的DEBUG_MODE编译开关未开启,或者fsbl_debug.h中的宏定义被错误修改。 需要特别提醒用户注意:有些开发板默认串口用于Linux控制台输出,可能被后续系统阶段占用导致FSBL输出被覆盖,这种情况建议用户尝试在FSBL初始化后立即添加延时观察。另外有案例显示,某些JTAG调试器会抢占串口引脚功能,需要检查MIO复用配置。 用户可能是硬件工程师或FPGA开发人员,应该具备示波器测量能力,所以诊断建议里加入了信号测量步骤。考虑到自定义板卡的特殊性,还补充了Xilinx已知的DDR校准失败导致后续外设初始化异常的bug说明——这个细节在官方文档里藏得很深。 </think>在ZYNQ的FSBL例程中,`fsbl_printf()`函数未打印输出可能由以下原因导致,请按步骤排查: --- ### 一、硬件连接与配置问题 1. **串口引脚映射错误** FSBL默认使用**UART0**(MIO引脚48/49),检查原理图: * 确认开发板的调试串口是否连接到UART0 * 检查MIO配置(`ps7_init.tcl`或Vivado配置)是否启用UART0 * 若使用自定义板,可能需要修改`xparameters.h`中的`STDIO_BASEADDRESS`指向正确的UART控制器 2. **串口参数不匹配** * FSBL默认波特率通常为**115200**(见`fsbl_debug.h`中的`FSBL_BAUDRATE`宏) * 确认终软件(如Putty)的波特率、数据位(8)、停止位(1)、校验位(None)设置一致 --- ### 二、软件配置问题 1. **调试宏未启用** 在`fsbl_debug.h`中检查宏定义: ```c #define FSBL_DEBUG_INFO // 必须取消注释 #define FSBL_PRINT // 确保此宏启用 ``` 若未定义,编译时将跳过所有`fsbl_printf()`调用。 2. **DDR初始化失败**(关键!) FSBL需先初始化DDR才能使用堆栈: * `fsbl_printf()`依赖动态内存分配(通过`xil_printf()`实现) * 若DDR初始化失败(如时序配置错误),函数将静默失效 * 检查`ps7_init.c`中的DDR参数是否匹配板载颗粒型号 3. **代码执行流异常** * 在`fsbl_printf()`前添加**LED闪烁**或**GPIO翻转**代码,验证是否执行到该位置 * 若未执行,可能是BootROM加载FSBL失败(检查BOOT.bin生成步骤是否符合[^1]) --- ### 三、其他可能原因 1. **编译器优化导致删除** 某些优化等级(如`-O3`)可能移除"无效"输出: * 在`lscript.ld`中检查链接脚本是否保留`.rodata`段(存放格式字符串) * 临时降低优化等级(在BSP设置中添加`-O0`) 2. **多核干扰问题** 若启用AMP双核(如[^4]): * 确认未在CORE1初始化前操作共享外设 * 检查`Start_cpu1()`是否被错误注释(引用[^1]) --- ### 排查步骤建议 ```mermaid graph TD A[fsbl_printf未输出] --> B[检查硬件串口连接] B -->|正常| C[验证终软件参数] B -->|异常| D[调整MIO/UART映射] C -->|匹配| E[检查fsbl_debug.h宏定义] E -->|已启用| F[添加GPIO调试代码] F -->|无响应| G[检测DDR初始化状态] G -->|失败| H[修正ps7_init DDR参数] G -->|成功| I[检查编译器优化选项] ``` > **注意**:在自定义板卡开发中(如引用[^3]),**时钟配置错误**是常见陷阱,需确认`ps7_init.c`中的`CPU_FREQ_HZ`和`UART_CLK_FREQ_HZ`与板载晶振频率一致。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值