软件版本:VIVADO2017.4 操作系统:WIN10 64bit 硬件平台:适用米联客 ZYNQ系列开发板 米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!! 29.1 概述在之前的应用中,ZYNQ将BOOT.bin文件烧写至QSPI Flash基本都是通过USB Cable连接PC,通过JTAG接口连接开发板,在SDK软件中使用“Program Flash”功能进行现场在线烧写。这种常规方法存在两个缺点。 1、速度慢。Flash的擦除(Erase)、写入(Program)、校验(Verify)3个过程所费的时间总和通常都需要若干分钟。 2、无法脱离JTAG口。对于某些产品而言,当产品量产上市后,进入维护升级阶段,若需修改、更新Flash中的bin文件,则需对产品进行拆解才可进行。 本例程实现了一种基于TCP协议的Flash bin文件更新方法。一方面,在较大程度上提高了bin文件的烧写速度(4MB大小bin文件可缩短至20秒左右);另一方面,提供了一种远程更新Flash的方法,可脱离JTAG接口,同时避免固件升级时对产品进行拆解。 29.2 基本原理首先,在ZYNQ的ARM中基于LWIP库建立一个TCP Server,板卡通过网线与电脑连接。在电脑中通过网络调试助手以TCP Client模式与ZYNQ中的TCP Server建立TCP连接。然后,通过网络调试助手将BOOT.bin文件以二进制形式发送至TCP Server,并存储在ZYNQ所连接的DDR中。最后,当TCP Server接收完bin文件所有的数据后,网络调试助手发送烧写启动命令,将bin文件的数据按顺序一一连续写入QSPI Flash中,随后再全部读出与所接收的bin文件进行一一比对检验。断电重启板卡,便可验证bin文件的更新。 29.3 Bin文件在SDK中所生成的BOOT.bin文件为普通二进制文件,通过UltraEdit或Binary Viewer软件可打开并查看bin文件的内容。将bin文件中所有的数据按顺序一一连续写入QSPI Flash中,即可完成bin文件的烧写,也就是说Flash中的数据与bin文件中的数据完全是一一对应的。由此可见,烧写bin文件的原理并不复杂,不存在类似编码、解码的过程,且与SDK中的“Program Flash”的所完成的功能相同。使用Binary Viewer软件打开查看bin文件的效果如下图所示。 29.4 QSPI FlashFlash在写入数据之前必须先进行擦除(Erase),擦除过程以扇区(Sector)为单位。然后以页(Page)为单位,依次将数据写入Flash中连续的各页。 以米联ZYNQ开发板所使用的QSPI Flash:S25FL256S为例。Sector的大小为64KB,Page的大小为256B。另外,还存在两个重要参数:单位Sector擦除时间和单位Page写入时间,这决定了Flash的烧写速度。S25FL256S所对应的单位Sector擦除时间为130ms,单位Page写入时间250μs。如下图最右侧的两栏所示。具体可参考芯片datasheet。 以4MB大小的BOOT.bin文件为例,写入之前需要擦除4096/64 = 64个Sector,最短需耗时64×130ms = 8.32s。接着,需要写入4096×1024/256 = 16384个Page,最短需耗时16384×250μs = 4.096s。加上ARM中应用程序的软件开销,QSPI Flash的擦除、写入时间总和不超过15s。若需读出进行校验,则再额外增加读出时间、比对时间。QSPI Flash的读出速度很快,读出整个bin文件耗时小于1s,ARM中应用程序的比对时间通常也很短,1至2s即可完成。因此,对于4MB大小的bin文件,QSPI Flash的擦除(Erase)、写入(Program)、校验(Verify)3个过程所耗费的时间总和可以控制在20s以内。 29.5 驱动程序驱动程序请参考提供例程的SDK工程的源文件。 main函数的完成的功能如下:
29.5.1 建立TCP Server基于LWIP库在ARM中建立一个TCP Server,IP地址为192.168.1.10,端口号为5010。 29.5.2 lwip库设置本例程使用RAW API,即函数调用不依赖操作系统。传输效率也比SOCKET API高,(具体可参考xapp1026)。将use_axieth_on_zynq和use_emaclite_on_zynq设为0。如下图所示。 修改lwip_memory_options设置,将mem_size,memp_n_pbuf,mem_n_tcp_pcb,memp_n_tcp_seg这4个参数值设大,这样会提高TCP传输效率。如下图所示。 修改pbuf_options设置,将pbuf_pool_size设大,增加可用的pbuf数量,这样同样会提高TCP传输效率。如下图所示。 修改tcp_options设置,将tcp_snd_buf,tcp_wnd参数设大,这样同样会提高TCP传输效率。如下图所示。 修改temac_adapter_options设置,将n_rx_descriptors和n_tx_descriptors参数设大。这样可以提高zynq内部emac dma的数据搬移效率,同样能提高TCP传输效率。如下图所示。 MZ7X工业级开发板板载网口芯片是RTL8211FDI,由于默认的驱动不支持RTL8211FDI 的寄存器配置,所以无法支持自动适应速度 (通过自己修改库可以实现自动适应但是工作量大,考虑到投入时间和产出比,这里就不修改了)。所以需要手动修改 LWIP 库让网口芯片工作于1000Mbps。 29.5.3 程序解析TCP Server建立由tcp_transmission.c文件中的tcp_recv_init和connect_accept_callback函数完成。
29.5.4 接收保存BOOT.bin文件接收BOOT.bin文件通过tcp_transmission.c中的tcp_recv_callback函数完成,该函数为TCP Server接收数据包的回调函数,每当接收到TCP Client的数据包时该函数都会被调用。该函数将TCP Server所接收到的bin文件的各数据包依次拷贝至DDR中首地址为FILE_BASE_ADDR的区域中,FILE_BASE_ADDR为宏定义。 #define FILE_BASE_ADDR 0x10000000 可根据具体要求定义其地址,注意要与lscript.ld中的DDR区域分开,不能重合。 29.5.5 烧写QSPI Flash烧写QSPI Flash由qspi_g128_flash.c文件中的update_flash、FlashErase、FlashWrite、FlashRead等函数完成,可支持Micron、Spansion等多个厂商,128Mb以上多种容量的QSPI Flash。qspi_g128_flash.c是根据SDK中QSPI接口的example:xqspips_g128_flash_example.c修改而成。 当接收完整个bin文件后,在网络调试助手中输入“start update”,含空格一共12个字符。tcp_recv_callback函数接收到该命令之后便调用update_flash函数启动bin文件至QSPI Flash的烧写。该函数需要1个读缓存和1个写缓存,分别存放从flash中读出的bin文件数据和需要写入flash中的bin文件数据。读缓存和写缓存的地址分别由READ_BASE_ADDR和WRITE_BASE_ADDR宏定义指定。可根据具体要求定义其地址,同样需要注意要与lscript.ld中的DDR区域分开,不能重合。 #define READ_BASE_ADDR 0x11000000 #define WRITE_BASE_ADDR 0x12000000 update_flash函数:
FlashErase、FlashWrite、FlashRead函数均源自于SDK中QSPI接口的example code。可参考相应的example具体分析函数功能。 29.5.6 TCP调试信息输出例程中设计了一个tcp_printf函数,用于向网络调试助手输出字符串调试信息。该函数暂时只支持字符串以“\n”结尾。 在本例程中使用该函数存在一个问题,即在Flash烧写开始直至结束前所有通过tcp_printf输出的调试信息,将无法及时发送,在烧写结束后应用程序回到main函数中包含xemacif_input(netif)函数的while循环中时,同时全部通过TCP发送至网络调试助手。 笔者尝试过几种方法均未能解决这个问题,例如通过tcp_nagle_disable()函数关闭nagle算法功能。笔者认为,一方面,可能跟LWIP库TCP部分函数的设计原理有关,另一方面,由于flash烧写部分应用程序将长时间占用ARM,使得xemacif_input(netif)函数长时间无法被调用,而ZYNQ中的LWIP协议栈所有的数据接收都需要依靠应用程序调用xemacif_input()函数而实现。因此在这段时间中,可能由于长时间无法调用该函数而对TCP部分函数的运行造成某些影响,使数据发送产生阻塞或者延迟。由于LWIP中TCP部分库函数结构较复杂,笔者对于TCP协议研究也不多,限于时间和精力未作深究。 29.6 网络调试助手操作方法29.6.1 发送bin文件在SDK中下载程序至ZYNQ中。打开网络调试助手,选择TCP Client方式,输入ARM中定义的TCP Server的IP地址和端口号,然后点击连接按键,建立TCP连接。SDK串口终端打印信息如下图所示。 在网络调试助手发送区设置里选择“启用文件数据源”,选择需要发送的BOOT.bin文件,然后点击发送。如下图所示。 29.6.2 发送启动Flash烧写命令然后输入烧写启动命令“start update”,不要选择“按十六进制发送”,本例程中需要以ASCII码形式发送,含空格一共12个字符(不要在末尾加回车),千万不要输错,否则需要全部重新再来一遍。如下图所示。 启动烧写后,SDK串口终端打印信息如下图所示。当提示“verify done!”表示整个烧写过程成功完成。 网络调试助手接收tcp_printf函数的输出的信息如下图所示。 29.7 Bin文件更新验证烧写完成后,此时可断电重启验证更新的BOOT.bin文件。本例程作为演示,烧入的bin文件为hello world工程。重启开发板,SDK串口终端打印信息如下图所示,代表bin文件更新成功。 29.8 待改进之处
|
XILINX 官网|站点统计|Archiver|手机版|米联客品牌主页|UISRC工程师开源站 ( 苏ICP备19046771号-2 )
GMT+8, 2025-4-2 15:29 , Processed in 0.222837 second(s), 87 queries .