我们先试试基本开发,现在先测试一下模块sd卡记录。先把模块基本加电测试,然后完成简单的ps端vivado项目,需要配置ddr,uart,sd卡,qspi flash。编译项目,导出硬件。
首先,需要测试helloword串口能够输入输出。
然后,开始测试sd卡,按照以下程序替代helloword.c
'''#include "xil_printf.h"
#include "xdevcfg.h"
#include "xparameters.h"
#include "platform.h"
#include "ff.h"
int SD_Init(void);
int Sd_Test_Write(void);
int Sd_Test_Read(void);
int main()
{
init_platform();
print("Hello World\n\r");
print("zynq_sd_card_fatfs-test \r\n");
SD_Init();
Sd_Test_Write();
Sd_Test_Read();
while(1)
{
;
}
cleanup_platform();
return 0;
}
static FATFS fatfs;
#define _MAX_SS 100
int SD_Init(void)
{
FRESULT rc;
BYTE work[_MAX_SS]; // 格式化所需的工作区,大小至少为一个扇区
// 1. 尝试挂载现有文件系统
rc = f_mount(&fatfs, "1:", 0);
// 2. 如果挂载失败(例如卡未格式化),则尝试格式化
if (rc == FR_NO_FILESYSTEM) {
xil_printf("No filesystem found. Formatting...\r\n");
// 参数说明:
// "": 路径,表示默认驱动器(0)
// FM_FAT: 格式化为FAT文件系统
// 0: 使用默认的分配单元(簇)大小
// work, sizeof(work): 提供的工作缓冲区及其大小
rc = f_mkfs("1:", FM_FAT, 0, work, sizeof(work));
if (rc) {
xil_printf("ERROR: Formatting failed with error %d\r\n", rc);
return XST_FAILURE;
}
xil_printf("Formatting successful. Remounting...\r\n");
// 3. 格式化后,重新尝试挂载
rc = f_mount(&fatfs, "1:", 0);
}
// 4. 检查最终挂载结果
if (rc) {
xil_printf("ERROR: f_mount returned %d\r\n", rc);
return XST_FAILURE;
}
xil_printf("SD Card filesystem mounted successfully.\r\n");
return XST_SUCCESS;
}
int Sd_Test_Write()
{
FIL fil;
FRESULT rc;
UINT br;
const char src_str1[] = "bsp test sd card write and read line1 string. if you see this message,sd_card fatfs test ok!\r\n";
rc = f_open(&fil,"1:/test.txt",FA_WRITE|FA_CREATE_NEW);
if(rc)
{
xil_printf("ERROR : f_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_write(&fil,src_str1,sizeof(src_str1),&br);rc = f_sync(&fil);
rc = f_close(&fil);
}
int Sd_Test_Read()
{
FIL fil;
FRESULT rc;
UINT br;
const char src_str[4096]={0};
rc = f_open(&fil,"1:/test.txt",FA_READ);
if(rc)
{
xil_printf("ERROR : f_open returned %d\r\n",rc);
return XST_FAILURE;
}
rc = f_lseek(&fil, 0);
rc = f_read(&fil,src_str,4096,&br);
xil_printf(src_str);
rc = f_close(&fil);
}'''
编译软件,加载运行。编译的时候会出现头文件问题,库问题。需要在设置里面增加链接相应库,增加库查找目录,才能编译通过。
运行程序,按照预期执行,就是测试通过,否则回到vivado查找问题,或者看硬件。
2,形成加载的boot.bin
使用vitis软件,把flsb.elf,bit硬件流,
刚刚编译的elf文件放在一起。
生成以下bif文件:
'''
the_ROM_image:
{
// 第一部分: FSBL - 必须位于 0x0
bootloader\] fsbl.elf // 第二部分: 硬件比特流文件 // 大小: 4,045,676 字节, FSBL 之后,对齐到 0x70000 \[offset = 0x70000\] design_1_wrapper.bit // 第三部分: 应用程序 // 大小: 432,408 字节, 比特流之后,对齐到 0xAF0000 \[offset = 0xAF0000\] testfile.elf }''' 要注意按照文件字节大小,修改offset。 我将为您详细讲解从生成BOOT.BIN到烧写QSPI Flash的全过程,包括必要的配置和注意事项。 ### 3. 生成BOOT.BIN文件 #### 1.1 准备BIF文件 见上面 #### 1.2 使用bootgen生成BOOT.BIN # 基本命令 bootgen -image boot.bif -arch zynq -o BOOT.BIN -w # 详细参数说明: # -image: 指定BIF文件 # -arch: 指定架构(zynq, zynqmp, microblaze等) # -o: 输出文件名 # -w: 覆盖已存在的输出文件 # -log: 生成日志文件(可选) # 示例:生成带日志的BOOT.BIN bootgen -image boot.bif -arch zynq -o BOOT.BIN -w -log bootgen.log ### 4. 烧写前准备工作 #### 4.1 硬件连接检查 1. **JTAG连接**:确保JTAG下载器正确连接 2. **电源检查**:确保开发板供电正常 3. **启动模式配置**:将开发板设置为JTAG启动模式 * Zynq-7000: MIO\[5:0\] = 6'b001010 * Zynq UltraScale+: MODE\[3:0\] = 4'b0101 #### 4.2 Vivado硬件管理器设置 # 在Vivado TCL控制台中操作 # 1. 打开硬件管理器 open_hw_manager # 2. 连接到目标 connect_hw_server open_hw_target # 3. 检查设备是否识别 current_hw_device [get_hw_devices xc7z*] # 4. 刷新设备 refresh_hw_device [lindex [get_hw_devices] 0] ### 5. 烧写QSPI Flash的完整流程 #### 5.1 使用XSCT命令烧写(推荐) # 创建烧写脚本 flash_program.tcl # 1. 连接目标 connect # 2. 选择目标处理器 targets -set -filter {name =~ "ARM*#0"} # 3. 停止当前运行的程序 stop # 4. 初始化DDR(如果需要) # 5. 烧写BOOT.BIN到QSPI Flash # 方法A:使用通用Flash编程 dow BOOT.BIN # 或者使用方法B:指定Flash类型和地址 flash write_bank 0 BOOT.BIN 0 #### 5.2 完整的烧写脚本示例 # flash_program.tcl #!/bin/tclsh # 设置变量 set BOOT_BIN "BOOT.BIN" set FLASH_OFFSET 0x0 set FLASH_TYPE "qspi-x4-single" # 连接硬件 connect after 1000 # 选择目标 targets -set -filter {name =~ "Cortex-A9*#0"} after 500 # 复位并停止 rst after 1000 stop # 初始化PS(如果需要在烧写前运行FSBL) # source ps_init.tcl # 配置Flash参数 flash config -freq 100000000 # 执行烧写 puts "正在擦除Flash..." flash erase_sector 0 0 127 puts "擦除完成" puts "正在烧写BOOT.BIN..." flash write $BOOT_BIN $FLASH_OFFSET $FLASH_TYPE puts "烧写完成" # 验证烧写 puts "正在验证..." flash verify $BOOT_BIN $FLASH_OFFSET $FLASH_TYPE puts "验证成功!" # 断开连接 disconnect puts "Flash烧写完成,请将启动模式切换为QSPI启动" #### 5.3 执行烧写 # 运行XSCT执行TCL脚本 xsct flash_program.tcl # 或者交互式执行 xsct # 然后逐行输入TCL命令 ### 6. 使用Vivado GUI烧写(备选) #### 6.1 GUI操作步骤 1. 打开Vivado → Open Hardware Manager 2. 连接目标设备 3. 右键点击FPGA设备 → Add Configuration Memory Device 4. 选择正确的Flash型号(如n25q128-3.3v-spi-x1_x2_x4) 5. 指定BOOT.BIN文件路径 6. 点击Program ### 7. 验证和启动测试 #### 7.1 验证烧写结果 # 在XSCT中读取Flash内容验证 # 读取前256字节 mrd 0xFC000000 64 # 或者 flash read_bank 0 0x100000 256 #### 7.2 切换启动模式 1. **硬件配置**: * Zynq-7000: 将MIO\[5:0\]设为6'b001001(主QSPI) * Zynq UltraScale+: 将MODE\[3:0\]设为4'b0010(QSPI 32位) 2. **重新上电** 或**系统复位** ### 8. 注意事项和故障排除 #### 8.1 重要注意事项 1. **启动顺序必须正确**:FSBL → Bitstream → Application 2. **Bit文件大小**:确保bit文件是完整配置文件,不是局部bit文件 3. **Flash型号匹配**:确认实际Flash型号与烧写时选择的型号一致 4. **电压匹配**:Flash电压(3.3V/1.8V)需与硬件设计一致 5. **时钟频率**:初次烧写建议使用较低频率(如50MHz) #### 8.2 常见问题解决 # 1. 如果连接失败 # 检查JTAG连接,尝试: connect_hw_server -url TCP:localhost:3121 # 或重启hw_server # Linux: hw_server & # Windows: 从Vivado启动Program and Debug # 2. 如果Flash识别失败 # 检查电源和接线 # 尝试更低频率 flash config -freq 25000000 # 3. 如果烧写验证失败 # 检查电源稳定性 # 尝试分段烧写 flash write_bank 0 fsbl.elf 0 flash write_bank 0 system.bit 0x80000 flash write_bank 0 application.elf 0x100000 #### 6.3 调试命令 # 查看目标状态 targets # 查看处理器状态 reg # 查看内存 mrd 0xF8000258 1 # 读取启动模式寄存器 # 检查Flash ID flash probe 0 ### 9. 自动化脚本示例 #!/bin/bash # generate_and_program.sh # 生成BOOT.BIN echo "生成BOOT.BIN..." bootgen -image boot.bif -arch zynq -o BOOT.BIN -w # 检查文件是否存在 if [ ! -f "BOOT.BIN" ]; then echo "错误:BOOT.BIN生成失败!" exit 1 fi # 烧写到Flash echo "开始烧写QSPI Flash..." xsct << EOF connect targets -set -filter {name =~ "ARM*#0"} stop flash write_bank 0 BOOT.BIN 0 verify_bank 0 BOOT.BIN 0 disconnect EOF if [ $? -eq 0 ]; then echo "烧写成功!" echo "请将启动模式切换为QSPI模式并重新上电" else echo "烧写失败!" fi ### 总结 1. 确保启动镜像顺序正确 2. 烧写前确认硬件连接和启动模式 3. 首次烧写建议使用较低频率 4. 烧写后必须验证 5. 切换启动模式后重新上电 按照这个流程,您应该能成功将BOOT.BIN烧写到QSPI Flash并启动系统。完成了,sd卡测试。