作者:Longley Zhang,AMD工程师;来源:AMD开发者社区
就地执行(eXecute In Place,下面简称XIP),即芯片内执行,是指应用程序可以直接在非易失存储器或闪存中取指然后译码、执行,不必再把代码读到系统RAM中。它是使用共享内存的扩展,以减少所需的总内存量。AMD的软核处理器Microblaze可以通过AXI Quad SPI IP实现XIP的功能。AMD提供参考设计XAPP1176(见Ref 1,Ref 2),介绍使用 Vivado 通过 AXI Quad SPI 进行就地执行(XIP)。用户可以通过这个参考设计了解Microblaze实现XIP功能的基本概念和设计思路。然而这篇文档使用的Vivado版本是2013.2,这个版本已经很旧了,文档里面提到的一些工具(如:IMPACT) 以及命令(XMCSUTIL)在新版本的Vivado都已经不支持了,并且XAPP1176里提供的bootloader比较复杂。
本博客提供了基于2023.2 Vivado的参考工程,展示如何使用Microblaze 地执行(XIP)程序,并提供一个简单的bootloader。
下面是工程创建流程和程序运行步骤:
1. 修改2023.2 AC701 Petalinux BSP里自带的Vivado工程,使能AXI Quad SPI IP里的XIP模式。
或者创建一个基于AC701的Vivado工程运行,然后运行附件的tcl文件。
2. 构建Vivado工程,生成bit文件并导出包含bitstream的xsa文件。
3. 在Vitis里,基于导出的xsa文件创建platform工程,创建两个工程,一个是bootloader,另外一个是XIP的用户程序。
这个bootloader只是一个运行在BRAM里的简单程序,作用是把PC跳转到XIP程序的起始位置。
XIP程序可以是任何用户程序,用户需要在linker script里把.text等只读的section放到QSPI flash的地址段,把.data/.bss等读写的section放到BRAM。
如果.data section里有已经初始化的变量,用户需要在用户程序里把.data section复制到BRAM里。
4. 分别右键点击bootloader工程和XIP工程里的src文件夹,导入附件的工程文件。(在本博客的工程里,bootloader工程文件在bootloader_ar的文件夹里,XIP工程文件在dhry_0文件夹里。)
5. 在XSCT里运行mb-objcopy把xip工程的elf文件转换成bin文件(下面命令把dhry_0.elf转换成dhry_0.b)。
mb-objcopy -O binary -R .vectors.reset -R .vectors.sw_exception -R .vectors.interrupt -R .vectors.debug_sw_break -R .vectors.hw_exception dhry_0.elf dhry_0.b
6. 在Vitis里,通过菜单Vitis -> Program Device把bootloader.elf更新到bit文件里,生成新的download.bit。
7. 在Vivado里,通过菜单Tools -> Generate Write Memory Configuration File把download.bit和XIP工程的bin文件合并成一个mcs文件(这里相当于XAPP1176里的Merging Two MCS Files)。
8. 把生成的mcs文件烧写到AC701的QSIP flash里,连接UART线,把AC701设置为QSPI flash启动模式并上电启动。这样就能看到串口的打印输出了,输出内容是DHRYSTONE测试的结果。
Ref 1: https://docs.amd.com/v/u/en-US/xapp1176-xip-axi-quad-spi-ipi