ZYNQ使用TCP烧录bin文件后DMA DONE 卡死

真是个棘手的问题啊,因为同样的代码,之前在Alinx的核心板上验证过是没有问题的,但是在自己设计的板子上就不行了。关键是不是一直不行,是有时候烧录进去能正常启动,有时候烧录进去就卡死。
出了这个问题,没有解决思路就开始网上搜,一下是在这过程中搜索到的有用的信息:
1.zynq-7015使用lwip-tcp远程对QSPI进行更新、QSPI FLASH启动
这个里面提供了一些检索的链接,有可能可以解决你的问题,总结起来就是网络调试助手有问题,文中还包含了一些其他链接,比如说的Flash有坏块之类的。很不幸这个没能解决我的问题!
2.江山易改本性难移之ZYNQ SDK FSBL加载启动代码详解
然后就是看了这篇文章,主要是研究一下出现这个DMA DONE之后卡在什么流程,具体可以读一下这个文章,写的不错,很清晰,也能定位到最终卡死在哪里,但是没有能力解决,很尴尬。
3.pbuf结构中的内容
研究这个内容主要是因为参考的正点原子的代码,而在tcp传输bin文件这里使用到pbuf,当时没看懂这里的代码,怕是代码有问题,所以看了一下,确定代码没有问题。在这期间也使用了Alinx的代码,发现出错的概率比正点原子小很多,但是Alinx的需要配合他们自己的软件上位机使用,而且没法看到当前烧录的进度。
4.ZYNQ控制程序重启与重定位
到这里就是基本解决了问题了,需要将烧录之后的代码自动重启,而不需要手动启动,但是这里还是有点问题,就是会出现烧录完成之后不会自动重启,而是需要手动断电重启。

正常启动打印信息

Xilinx First Stage Boot Loader
Release 2018.3  Aug  7 2024-14:54:55
Devcfg driver initialized				//Processor Configuration Access Port即处理器配置接口,连接软件和硬件的桥梁
Silicon Version 3.1      				//获取PS版本号
Boot mode is QSPI						//读取启动模式寄存器后确定启动方式是QSPI
Single Flash Information
FlashID=0xEF 0x40 0x19
WINBOND 256M Bits
QSPI is in single flash connection
QSPI is in 4-bit mode
QSPI Init Done
Flash Base Address: 0xFC000000
Reboot status register: 0x60400000
Multiboot Register: 0x0000C000
Image Start Address: 0x00000000
Partition Header Offset:0x00000C80
Partition Count: 3						//总的partition的数量,即共有3个段;分别为fsbl.elf、fpga.bit、app.elf
Partition Number: 1						//最开始的partition就是fsbl自身,当前已经在BootROM中运行了,所以不用管;这里的==1==就是指向fpga.bit这个段
Header Dump
Image Word Len: 0x000F6EC0				//fpga.bit的大小 3950KB
Data Word Len: 0x000F6EC0
Partition Word Len:0x000F6EC0
Load Addr: 0x00000000
Exec Addr: 0x00000000
Partition Start: 0x000075D0
Partition Attr: 0x00000020				//用来判断文件属性,例如FPGA.bit或者application.elf
Partition Checksum Offset: 0x00000000
Section Count: 0x00000001
Checksum: 0xFFD13B7E
Bitstream								//利用上面的partition attr识别出的文件属性
In FsblHookBeforeBitstreamDload function
PCAP:StatusReg = 0x40000A30
PCAP:device ready
PCAP:Clear done
Level Shifter Value = 0xA
Devcfg Status register = 0x40000A30
PCAP:Fabric is Initialized done
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: 0x00100001
PCAP DMA DEST ADDR 0xF800701C: 0xFFFFFFFF
PCAP DMA SRC LEN 0xF8007020: 0x000F6EC0
PCAP DMA DEST LEN 0xF8007024: 0x000F6EC0
PCAP ROM SHADOW CTRL 0xF8007028: 0xFFFFFFFF
PCAP MBOOT 0xF800702C: 0x0000C000
PCAP SW ID 0xF8007030: 0x00000000
PCAP UNLOCK 0xF8007034: 0x757BDF0D
PCAP MCTRL 0xF8007080: 0x30800100

DMA Done !

FPGA Done !
In FsblHookAfterBitstreamDload function
Partition Number: 2
Header Dump
Image Word Len: 0x0000E004
Data Word Len: 0x0000E004
Partition Word Len:0x0000E004
Load Addr: 0x00100000
Exec Addr: 0x00100000
Partition Start: 0x000FE490
Partition Attr: 0x00000010
Partition Checksum Offset: 0x00000000
Section Count: 0x00000001
Checksum: 0xFFCD78F2
Application
Handoff Address: 0x00100000
In FsblHookBeforeHandoff function
SUCCESSFUL_HANDOFF
FSBL Status = 0x1

异常启动打印信息

Xilinx First Stage Boot Loader
Release 2018.3  Aug  7 2024-14:06:41
Devcfg driver initialized
Silicon Version 3.1
Boot mode is QSPI
Single Flash Information
FlashID=0xEF 0x40 0x19
WINBOND 256M Bits
QSPI is in single flash connection
QSPI is in 4-bit mode
QSPI Init Done
Flash Base Address: 0xFC000000
Reboot status register: 0x60400000
Multiboot Register: 0x0000C000
Image Start Address: 0x00000000
Partition Header Offset:0x00000C80
Partition Count: 3
Partition Number: 1
Header Dump
Image Word Len: 0x000F6EC0
Data Word Len: 0x000F6EC0
Partition Word Len:0x000F6EC0
Load Addr: 0x00000000
Exec Addr: 0x00000000
Partition Start: 0x000075D0
Partition Attr: 0x00000020
Partition Checksum Offset: 0x00000000
Section Count: 0x00000001
Checksum: 0xFFD13B7E
Bitstream
In FsblHookBeforeBitstreamDload function
PCAP:StatusReg = 0x40000A30
PCAP:device ready
PCAP:Clear done
Level Shifter Value = 0xA
Devcfg Status register = 0x40000A30
PCAP:Fabric is Initialized done
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: 0x00007A30
PCAP DMA SRC ADDR 0xF8007018: 0x00100001
PCAP DMA DEST ADDR 0xF800701C: 0xFFFFFFFF
PCAP DMA SRC LEN 0xF8007020: 0x000F6EC0
PCAP DMA DEST LEN 0xF8007024: 0x000F6EC0
PCAP ROM SHADOW CTRL 0xF8007028: 0xFFFFFFFF
PCAP MBOOT 0xF800702C: 0x0000C000
PCAP SW ID 0xF8007030: 0x00000000
PCAP UNLOCK 0xF8007034: 0x757BDF0D
PCAP MCTRL 0xF8007080: 0x30800100

DMA Done !
...................................................................................................PCAP transfer timed out
PCAP_FPGA_DONE_FAIL
PCAP Bitstream Download Failed
PARTITION_MOVE_FAIL
▒SBL Status = 0xA00B
Xilinx First Stage Boot Loader
Release 2018.3  Aug  7 2024-14:06:41
Devcfg driver initialized
Silicon Version 3.1
Boot mode is QSPI
Single Flash Information
FlashID=0xEF 0x40 0x19
WINBOND 256M Bits
QSPI is in single flash connection
QSPI is in 4-bit mode
QSPI Init Done
Flash Base Address: 0xFC000000
Reboot status register: 0xF0480000
Multiboot Register: 0x0000C200
Image Start Address: 0x01000000
Bank Selection 1
BankSel 1 != Register Read 239
Bank Selection Failed
Move Image failed reading FsblLength
Get Header Start Address Failed
Partition Header Load Failed
▒SBL Status = 0xA00E

上面的启动信息是要在fsbl_debug.h中打开调试信息,如下所示:

#define DEBUG_GENERAL	0x00000001    /* general debug  messages */
#define DEBUG_INFO	0x00000002    /* More debug information */
#define FSBL_DEBUG_INFO     //定义这句
#if defined (FSBL_DEBUG_INFO)
#define fsbl_dbg_current_types ((DEBUG_INFO) | (DEBUG_GENERAL))

还有需要说明的是,出现DMA DONE卡死后,等好长时间会出现下面的错误信息,真的是很久。可以手动修改这个等待时间,具体修改是在pcap.c这个文件中的第802行,这里的MAX_COUNT就是我们要改的值,跳转后将这个值改成1000就可以了。

		if(!Count) {
			fsbl_printf(DEBUG_GENERAL,"PCAP transfer timed out \r\n");
			return XST_FAILURE;
		}
		if (Count > (MAX_COUNT-100)) {
			fsbl_printf(DEBUG_GENERAL,".");
		}

从错误打印信息来看,当启动失败后,会再找下一启动的地址,但是也失败了,因为我只有这一个启动代码。所以可以处理的方式是,在flash的另一个地址烧录一份备用代码,防止在升级之后成砖,这样系统会自动跳到备份代码启动,调试的时候也可以这么操作,省的一直烧录。
具体的烧录方式可以在SDK中执行,如下图,我将备份代码烧录到flash的0x800000这个地址去。
在这里插入图片描述

multiboot register

multiboot register寄存器的地址加1,则对应的flash的偏移地址增加32KB

使用PDA测试可以正常烧录

在这里插入图片描述

检查QSPI Flash的烧录程序

将原来的代码替换成alinx的还是不行

检查网络传输部分的代码

将原来的替换成alinx的就正常了,同时配套使用alinx的烧录工具。

err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
                               struct pbuf *p, err_t err)
{
	struct pbuf *q;
	char *pData;
	/* do not read the packet if we are not in ESTABLISHED state */
	if (!p) {
		tcp_close(tpcb);
		tcp_recv(tpcb, NULL);
		return ERR_OK;
	}

	/* indicate that the packet has been received */
	tcp_recved(tpcb, p->len);
/************************alinx*********************************/
#if 1
	pData = (char *) p->payload;

		int udp_len = p->len ;

		if (!(memcmp("update", p->payload + p->len - 6, 6)))
			{
				memcpy(&rxbuffer[total_bytes], pData, udp_len - 6);
				total_bytes += udp_len - 6 ;
				xil_printf("Received Size is %u Bytes\r\n", total_bytes) ;
				xil_printf("Initialization done, programming the memory\r\n") ;
				start_update_flag = 1 ;
			}
			else
			{
				memcpy(&rxbuffer[total_bytes], pData, udp_len);
				total_bytes += udp_len ;
			}

#endif

/* free the received pbuf */
	pbuf_free(p);

	return ERR_OK;

在这里插入图片描述
alinx开发的这个工具是自带后缀update关键字的,不需要额外发送!

最终定位的问题是在BSP中配置lwip,对照alinx的手册把lwip的一些参数值全部改大,接收就没有问题了。不知道什么原因,因为我接收端累加的字节数和实际bin文件大小一致,没有丢包!那是什么情况,接收到的数据出现错位吗?
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值