一、常见跳转方式
1,一般FPGA只要上电,就会自动从外部flash的0地址加载程序。
2,而我们所谓的在线式升级就是在flash0地址放一个程序(boot/golden image),然后在后面再放一个程序(app/update image)
3,所谓的跳转就是运行golden image的时候,跳转去运行update image。
4,一般操作都是告诉fpga下次启动需要加载的flash地址,然后拉reset即可。
如xilinx 7020跳转:
如altera的c4跳转:
二、xc7a50t+microblaze跳转
1,有两种方式可是实现multiboot跳转,一种是通过TCL指令直接把IPROG跳转指令固化到固件(bitstream)里,一种是加入ICAPE2原语,通过写代码实时打IPROG跳转指令。
文档见《xapp1247-multiboot-spi》
2,第一种方式做出来的golden image无法实时修改跳转地址、无法决定跳转时机,所有东西都是做固件前就决定好写死的,用起来不方便,因此我们用第二种
3,第二种方式用原语ICAPE2给跳转指令,不像我们上面列的那种给某个寄存器写跳转地址然后拉reset,ICAPE2接收的是带帧头帧尾的IPROG指令码流.
4,ICAPE2接口如下
5,通过ICAP发送IPROG指令实现Multiboot的步骤如下(示例):
6,把ICAP封装成axi接口开放给microblaze配置的ip是axi_hwicap
7,axi_hwicap配置如下
8,嵌入式驱动drv_hwicap.c
#include "drv_hwicap.h"
#include "xstatus.h"
#include "xhwicap.h"
#include "xhwicap_i.h"
uint32_t CMD_RECONFIG[10] =
{
/* 0 */ 0xFFFFFFFF,
/* 1 */ 0xAA995566,
/* 2 */ 0x20000000,
/* 3 */ 0x30020001,
/* 4 */ 0x00000000, //地址
/* 5 */ 0x30008001,
/* 6 */ 0x0000000F,
/* 7 */ 0x20000000,
};
XHwIcap hwicap0;
int mb_hwicap_init(void)
{
XStatus ret = XST_FAILURE;
XHwIcap_Config *cfg;
u32 ConfigRegData = 0;
int Status = 0;
cfg = XHwIcap_LookupConfig(DEVID_HWICAP0);
ret = XHwIcap_CfgInitialize(&hwicap0, cfg, cfg->BaseAddress); //XST_SUCCESS
if(ret != XST_SUCCESS)
{
return -1;
}
ret = XHwIcap_SelfTest(&hwicap0);
if(ret != XST_SUCCESS)
{
return -2;
}
Status = XHwIcap_GetConfigReg(&hwicap0, XHI_IDCODE, &ConfigRegData);
return 0;
}
//执行重新配置
int hwicap_reconfig(int app_addr)
{
int ret = 0;
uint8_t CMD_NUM = sizeof(CMD_RECONFIG) / sizeof(CMD_RECONFIG[0]); //计算数组的长度
CMD_RECONFIG[4] = app_addr; //跳转地址
usleep(3000000);
ret = XHwIcap_DeviceWrite(&hwicap0, CMD_RECONFIG, CMD_NUM); //依次打码流指令
if(ret == 0)
{
return 0; //跳转OK
}
return -1; //跳转异常
}
9,STARTUPE2原语。给HWICAP提供EOS信号
三、icap2详解
1、概念缩写
2,
四、axi_hwicap详解
1,结构
2,Register Address Map
五、相关文档
《pg134-axi-hwicap》
《ug470_7Series_Config》
《ug953-vivado-7series-libraries-en-us_原语》
《xapp1247-multiboot-spi(1)》
六、结束语
看到这里,聪明的你肯定已经想放弃了。
我也很无语,明明一个地址一个使能就能跳转的事情,我也不知道为啥傻逼Xilinx搞这么复杂搞出个ICAP。
不要想着投机取巧,没有简便方法,我这个方法就是正解。
接受把,孩子