实验环境:
Vivado 2018.3、xc7z015clg485-2、小梅哥FPGA开发板、BOOT.bin(这个文件包含了bitstream文件,工程.elf,和FSBL.elf)、正点原子领航者《41_qspi_update_tcp》例程。
问题描述:
学习了《小梅哥——ZYNQ程序固化》和《正点原子(领航者)——第四十二章 基于TCP协议的远程更新QSPI Flash实验》我想通过tcp对小梅哥的开发板进行远程更新,但是更新完无法启动。
步骤如下:
2024.05.14:
1、移植了正点原子的例程,适配自己的程序,例程就是通过tcp把BOOT.bin文件发送到PS端,存在了一个16M的数组里面。“update”进行更新,例程的程序还包含了擦除FLASH,写入FLASH,将读和写FLASH的数据进行校验,这都没问题。在JTAG模式下,烧写程序,进行验证。
2、烧完程序后断电,将启动模式改为QSPI FLASH模式。发现任何打印都没有,而且正常情况下我的PL端D3(蓝色)是亮的,现在灯没亮。
2024.05.15:
3、分析了正常固化程序的“Console”信息。也没看出啥来。
2024.05.16:
3、怀疑可能是卡在了启动过程中。
4、查看手册UG585看了一下启动:
5、搜索文章发现可以通过FSBL的方式进行调试:
在xxxxxfsbl/src/fsbl_debug.h中添加#define FSBL_DEBUG_INFO,打开FSBL中所有的调试信息,启动过程中会打印各种调试信息,看看启动具体卡在哪里。
调试过程:左图为远程更新的;右图为正常固化程序的。
6、搜索打印发现DMA Done!在FSBL/src/pcap.c中:
/*
* Poll for the DMA done
*/
Status = XDcfgPollDone(XDCFG_IXR_DMA_DONE_MASK, MAX_COUNT);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_DMA_DONE_FAIL \r\n");
return XST_FAILURE;
}
fsbl_printf(DEBUG_INFO,"DMA Done ! \n\r");
/*
* Poll for FPGA Done
*/
Status = XDcfgPollDone(XDCFG_IXR_PCFG_DONE_MASK, MAX_COUNT);
if (Status != XST_SUCCESS) {
fsbl_printf(DEBUG_INFO,"PCAP_FPGA_DONE_FAIL\r\n");
return XST_FAILURE;
}
fsbl_printf(DEBUG_INFO,"FPGA Done ! \n\r");
/*
* Check for errors
*/
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"Errors in PCAP \r\n");
return XST_FAILURE;
}
也就是程序卡在了
Status = XDcfgPollDone(XDCFG_IXR_PCFG_DONE_MASK, MAX_COUNT);
但是这个也没有“PCAP_FPGA_DONE_FAIL”打印。
7、那也就是卡在了函数XDcfgPollDone内部。XDcfgPollDone
/******************************************************************************/
/**
*
* This function Polls for the DMA done or FPGA done.
*
* @param none
*
* @return
* - XST_SUCCESS if polling for DMA/FPGA done is successful
* - XST_FAILURE if polling for DMA/FPGA done fails
*
* @note none
*
****************************************************************************/
int XDcfgPollDone(u32 MaskValue, u32 MaxCount)
{
int Count = MaxCount;
u32 IntrStsReg = 0;
/*
* poll for the DMA done
*/
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
while ((IntrStsReg & MaskValue) !=
MaskValue) {
IntrStsReg = XDcfg_IntrGetStatus(DcfgInstPtr);
Count -=1;
if (IntrStsReg & FSBL_XDCFG_IXR_ERROR_FLAGS_MASK) {
fsbl_printf(DEBUG_INFO,"FATAL errors in PCAP %lx\r\n",
IntrStsReg);
PcapDumpRegisters();
return XST_FAILURE;
}
if(!Count) {
fsbl_printf(DEBUG_GENERAL,"PCAP transfer timed out \r\n");
return XST_FAILURE;
}
if (Count > (MAX_COUNT-100)) {
fsbl_printf(DEBUG_GENERAL,".");
}
}
fsbl_printf(DEBUG_GENERAL,"\n\r");
XDcfg_IntrClear(DcfgInstPtr, IntrStsReg & MaskValue);
return XST_SUCCESS;
}
看5中的图片,打印了一堆"..................",那也就是说读寄存器计数超次数了。
8、查了一下XDCFG_IXR_PCFG_DONE_MASK看看:
搜索发现跟PCAP有关系,然后搜索到了一篇文章跟我这个情况一样:
Zynq FSBL 在“DMA 完成”后卡住了! (xilinx.com)
但是答复没有效果。不过我有个想法是可以尝试一下SD启动模式,把这个BOOT.bin文件拷到SD卡里,然后试试。
9、又搜到另一个文章:Zynq MPSoC 更换GD25Q128/MX25L128/W25Q128等低容量SPI FLASH无法启动分析与解决_gd25q128烧录-CSDN博客
尝试通过xsct对BootROM Error Codes查询,查询寄存器CSU_BR_ERROR的[15:0],寄存器地址为0x00FFD80528。
这个寄存器访问不到。而且这个文章是因为QSPI的启动模式的问题。所以问题不在这
10、打开这个:
前半部分是JTAG模式下打印信息,后边是QSPI模式下打印信息。尝试跟9这个链接去做,做不到一样的,因为我这个是2018.3这个版本还是xilinx SDK,他那个是新版的,是vitis。遂感觉这个方式不行;查询寄存器值的方式不行。
DESKTOP-OS9OCBQ 15:53:21
Info: ARM Cortex-A9 MPCore #0 (target 2) Stopped at 0xffffff28 (Suspended)
Info: ARM Cortex-A9 MPCore #1 (target 3) Stopped at 0xffffff34 (Suspended)
initializing
0% 0MB 0.0MB/s ??:?? ETA
35% 1MB 2.3MB/s ??:?? ETA
64% 2MB 2.1MB/s ??:?? ETA
90% 3MB 2.0MB/s ??:?? ETA
100% 3MB 2.0MB/s 00:01
Downloading Program -- C:/Users/jlny/Desktop/ads1605_tcp_ddr3_V4.5/ad9238_udp_ddr3.sdk/ad_ddr3_tcp/Debug/ad_ddr3_tcp.elf
section, .text: 0x00100000 - 0x00125983
section, .init: 0x00125984 - 0x0012599b
section, .fini: 0x0012599c - 0x001259b3
section, .rodata: 0x001259b8 - 0x00126d13
section, .data: 0x00126d18 - 0x00127ad7
section, .eh_frame: 0x00127ad8 - 0x00127adb
section, .mmu_tbl: 0x00128000 - 0x0012bfff
section, .ARM.exidx: 0x0012c000 - 0x0012c007
section, .init_array: 0x0012c008 - 0x0012c00b
section, .fini_array: 0x0012c00c - 0x0012c00f
section, .bss: 0x00200000 - 0x0300812f
section, .heap: 0x03008130 - 0x0300a12f
section, .stack: 0x0300a130 - 0x0300d92f
0% 0MB 0.0MB/s ??:?? ETA
90% 0MB 0.3MB/s ??:?? ETA
100% 0MB 0.3MB/s 00:00
Setting PC to Program Start Address 0x00100000
Successfully downloaded C:/Users/jlny/Desktop/ads1605_tcp_ddr3_V4.5/ad9238_udp_ddr3.sdk/ad_ddr3_tcp/Debug/ad_ddr3_tcp.elf
Info: ARM Cortex-A9 MPCore #0 (target 2) Running
Info: tcfchan#5 closed
xsct% connect
attempting to launch hw_server
****** Xilinx hw_server v2018.3
**** Build date : Dec 7 2018-00:40:27
** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
INFO: hw_server application started
INFO: Use Ctrl-C to exit hw_server application
****** Xilinx hw_server v2018.3
**** Build date : Dec 7 2018-00:40:27
** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved.
INFO: hw_server application started
INFO: Use Ctrl-C to exit hw_server application
INFO: To connect to this hw_server instance use url: TCP:127.0.0.1:3121
tcfchan#6
xsct% targets
1 APU
2* ARM Cortex-A9 MPCore #0 (Running)
3 ARM Cortex-A9 MPCore #1 (Running)
4 xc7z015
xsct% targets -set -filter {name =~ "Cortex-A9 #0"}
xsct% no targets found with "name =~ "Cortex-A9 #0"". available targets:
1 APU
2* ARM Cortex-A9 MPCore #0 (Running)
3 ARM Cortex-A9 MPCore #1 (Running)
4 xc7z015
targets -set -filter {name =~ "Cortex-A9 MPCore #0"}
xsct% no targets found with "name =~ "Cortex-A9 MPCore #0"". available targets:
1 APU
2* ARM Cortex-A9 MPCore #0 (Running)
3 ARM Cortex-A9 MPCore #1 (Running)
4 xc7z015
targets -set -filter {name =~ "ARM Cortex-A9 MPCore #0"}
xsct% rst -processor
Info: ARM Cortex-A9 MPCore #0 (target 2) Stopped at 0x0 (Vector Catch)
xsct% mrd -force 0x00FFD80528
xsct% Memory read error at 0xFFD80528. AP transaction timeout
Info: ARM Cortex-A9 MPCore #0 (target 2) Running
xsct% targets -set -filter {name =~ "*A9 MPCore #1"}
no targets found with "name =~ "*A9 MPCore #1"". available targets:
5 whole scan chain (incomplete IR length definition)
xsct% rst -processor
xsct% unsupported reset
targets -set -filter {name =~ "ARM Cortex-A9 MPCore #1"}
xsct% no targets found with "name =~ "ARM Cortex-A9 MPCore #1"". available targets:
5 whole scan chain (incomplete IR length definition)
targets -set -filter {name =~ "ARM Cortex-A9 MPCore #1"}
xsct% no targets found with "name =~ "ARM Cortex-A9 MPCore #1"". available targets:
5 whole scan chain (incomplete IR length definition)
11、问题查找卡到了第10步,然后11想尝试一下SD卡启动模式。把BOOT.bin通过读卡器拷贝到SD里,切换到SD卡启动,确实好使,但是不是我想要的啊!!!!!
2024.05.20:
12、搜了一下黑金的资料,其中有zynq7015远程更新QSPI FLASH的内容,发现我的lscript.ld文件和它们的不一样。我的没有ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000。
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x3FF00000
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}
试了一下改为这样,也不行,可能还是什么地方没有弄好。
13、尝试了使用黑金的程序,不知道为啥效果还不如正点原子的呢(忘了开启#define FSBL_DEBUG_INFO)。唉,感觉这两个程序都差不多。
14、还有个发现是DNA Done之后长时间,会进行报错,稍微等一会看看打印。
15、搜了文章,讲解FSBL过程的:
Xilinx FSBL 代码简析_partition header load failed-CSDN博客
ZYNQ 中FSBL - 皮皮祥 - 博客园 (cnblogs.com)
江山易改本性难移之ZYNQ SDK FSBL加载启动代码详解_zynq fsbl-CSDN博客
按照这个对我的打印信息进行分析。
Xilinx First Stage Boot Loader //前边完成了ps7初始化,清DCACHE,关CACHE,寄存器处理
Release 2018.3 May 20 2024-13:18:37
Devcfg driver initialized
Silicon Version 3.1
Boot mode is QSPI
Single Flash Information //flash信息
FlashID=0xEF 0x40 0x18
WINBOND 128M Bits
QSPI is in single flash connection
QSPI is in 4-bit mode
QSPI Init Done
Flash Base Address: 0xFC000000
Reboot status register: 0x60400000 //LoadBootImage()
Multiboot Register: 0x0000C000
Image Start Address: 0x00000000
Partition Header Offset:0x00000C80
Partition Count: 3 //FSBL+BIT+APP
Partition Number: 1 //BIT
Header Dump
Image Word Len: 0x000D6468//877672x4/1024 = 3428.40625 的确跟我生成的bit文件(3429KB)一样
Data Word Len: 0x000D6468
Partition Word Len:0x000D6468
Load Addr: 0x00000000
Exec Addr: 0x00000000
Partition Start: 0x000075D0
Partition Attr: 0x00000020
Partition Checksum Offset: 0x00000000
Section Count: 0x00000001
Checksum: 0xFFD75A86
Bitstream //Partition是bitstream
In FsblHookBeforeBitstreamDload function //从这开始与这个博主不一样了
PCAP:StatusReg = 0x40000A30
PCAP:device ready
PCAP:Clear done //ClearPcapStatus(),清除PCAP状态寄存器
Level Shifter Value = 0xA
Devcfg Status register = 0x40000A30
PCAP:Fabric is Initialized done //FabricInit()对结构编程以供使用
PCAP register dump:
PCAP CTRL 0xF8007000: 0x4C00E07F
PCAP LOCK 0xF8007004: 0x0000001A
PCAP CONFIG 0xF8007008: 0x00000508
PCAP ISR 0xF800700C: 0x0802000B
PCAP IMR 0xF8007010: 0xFFFFFFFF
PCAP STATUS 0xF8007014: 0x00000A30
PCAP DMA SRC ADDR 0xF8007018: 0xFC01D741
PCAP DMA DEST ADDR 0xF800701C: 0xFFFFFFFF
PCAP DMA SRC LEN 0xF8007020: 0x000D6468
PCAP DMA DEST LEN 0xF8007024: 0x000D6468
PCAP ROM SHADOW CTRL 0xF8007028: 0xFFFFFFFF
PCAP MBOOT 0xF800702C: 0x0000C000
PCAP SW ID 0xF8007030: 0x00000000
PCAP UNLOCK 0xF8007034: 0x757BDF0D
PCAP MCTRL 0xF8007080: 0x30800100 //打印PCAP寄存器状态
...................................................................................................
DMA Done ! //循环等待DMA完成
//然后卡死在下边一堆“.”
...................................................................................................
PCAP transfer timed out //超时10 0000 0000
PCAP_FPGA_DONE_FAIL //FPGA失败
PCAP Bitstream Download Failed //比特流文件下载失败
PARTITION_MOVE_FAIL //分区失败
FSBL Status = 0xA00B //错误代码
?
这个0xA00B就是#define PARTITION_MOVE_FAIL 0xA00B /**<Partition move fail>*/。
2024.05.22:
16、放了一天,拼命搜索正点原子论坛,结果发现了一样的:
Zynq7020通过TCP协议远程更新QSPI FLASH实验-OpenEdv-开源电子网
原来这个网络助手有附加码,我TM。。。。我再试试。
17、再有就是需要对比一下源数据——>网络助手发送的数据——>实际收到的数据。等我对完,再来更新。
2024.05.24:
18、找了半天有毛病,我的这版NetAssist网络调试助手发不出去东西,所以我才用的XNET,后来在正点原子领航者FPGA里面找了一版NetAssist网络调试助手(V5.0.2.5免费版),试了一下,可以远程升级啦,再就是远程升级之后重新启动,我再找找怎么重新启动。
ZYNQ软件复位重启、程序跳转的实现方法(Multiboot)_zynq multiboot-CSDN博客
重启方式亲测可用。