一,生成hex文件
逻辑工程的qsys编译好以后会生成sopcinfo文件,software里面首先generate bsp,然后编译software,编译完成后右键software->make targets build,选择mem_init_generate->build,然后就会生成hex文件
二,生成sof文件
重新编译整个逻辑工程,或者如果逻辑工程已经编译过了,仅仅更新nios,为了节省时间可以采用如下步骤:
1,在quartus里面processing->update memory initialization file
2,processing->start->start assemble
就能生成sof文件了
三,生成升级所用的bin文件
此处需要.sh文件,放到software目录下,内容为:
echo Generate application binary file.
sof2flash --input=".\..\..\qii\output_files\power.sof" --output="hw.flash" --epcs --verbose
objcopy -I srec -O binary hw.flash hw.bin
#bin2flash --input="hw.bin" --output="NiosEMIF.flash" --location=0x100000
bin2flash --input="hw.bin" --output="NiosEMIF.flash" --location=0x0
#sof2flash --input="..\..\prj\output_files\NiosEMIF.sof" --output="NiosEMIF.flash" --epcs --verbose
rm hw.flash
然后跟生成hex一样调用一下这个脚本,生成bin文件
四,通过上位机实现flash写入
升级代码如下:
void setImg(UpDateBag *UpDateData)
{
if( 1 ) //
{
soflength = UpDateData->length;
// reset
if(UpDateData->faddr == 0)
{
bufpoint = 0;
sofOffset = 0;
erase_cnt = 0;
erase_size = 0;
if (epcs_flash == NULL)
epcs_flash = alt_flash_open_dev(EPCS_FLASH_CONTROLLER_0_NAME);
}
dataBuffer = UpDateData->data;
bufpoint = bufpoint + UpDateData->flen;
if (UpDateData->flen > erase_size)
{
alt_erase_flash_block(epcs_flash, erase_cnt*FLASH_BLOCK_SIZE + APP1_IMAGE_BASE, FLASH_BLOCK_SIZE);
erase_size += FLASH_BLOCK_SIZE; erase_cnt++;
}
if ((bufpoint + sofOffset) >= soflength)
{
if(epcs_flash)
alt_write_flash_block(epcs_flash, APP1_IMAGE_BASE+sofOffset/FLASH_BLOCK_SIZE*FLASH_BLOCK_SIZE, APP1_IMAGE_BASE+sofOffset, dataBuffer, bufpoint);
erase_size -= bufpoint;
sofOffset += bufpoint;
bufpoint = 0;
}
else
{
if(bufpoint == 1024)
{
if(epcs_flash)
alt_write_flash_block(epcs_flash, APP1_IMAGE_BASE+sofOffset/FLASH_BLOCK_SIZE*FLASH_BLOCK_SIZE, APP1_IMAGE_BASE+sofOffset, dataBuffer, bufpoint);
erase_size -= bufpoint;
sofOffset += bufpoint;
bufpoint = 0;
}
}
}
if(sofOffset == soflength )
{
replyCmdBuf[PACKET_HEAD_LEN>>2] = LVDS_CMD_OK;
ReplyMessage(4);
usleep(20000);
#ifdef BOOT_MODE
rsu_factory_trigger_reconfig(RSU_CYCLONE4_0_BASE, (APP_IMAGE_BASE)>>2, 0x00);
#else
rsu_app_trigger_reconfig(RSU_CYCLONE4_0_BASE);
#endif
}
// if(sofOffset == soflength )
// {
// replyCmdBuf[PACKET_HEAD_LEN>>2] = LVDS_CMD_OK;
// ReplyMessage(4);
//
// usleep(20000);
//
IOWR(REMOTE_UPDATE_0_BASE, 0x4, 1);
//
// //Trigger reconfiguration
// IOWR(REMOTE_UPDATE_0_BASE, 0x6, 1);
// }
}
与之对应的升级模块为qsys里面添加 epcs_flash_controller,flash对应的几个引脚有的片子要求连上,有的片子不用连(只能是那几个引脚)
需要注意的是代码写入成功后的跳转模块,有的片子需要用rsu_cyslcone4模块跳转,有的需要用remote update模块实现跳转。
五,制作boot程序
boot升级那块跟应用程序一样,只不过main函数刚跑起来多一个app跳转功能,代码如下
void SwitchToApp(void)
{
rsu_factory_get_previous_reconfig_status(RSU_CYCLONE4_0_BASE,&condition_1,&condition_2,&boot_address_1,&boot_address_2);
if(condition_1 <= 1)
{
rsu_factory_trigger_reconfig(
RSU_CYCLONE4_0_BASE,//REMOTE_UPDATE_CONTROLLER_BASE, // alt_u32 rsu_base,
(APP_IMAGE_BASE)>>2,//( HW_APP1_IMAGE_BASE + HEADER_LENGTH ) >> 2, // alt_u32 boot_address_value, // MSB 22-bits of 24-bit address
0x00//hw1_header_g.res_wd_tmo // alt_u32 watch_dog_value // MSB 12-bits of 29-bit timeout count
);
}
}
固化boot程序需要做jic文件,就是在生成sof以后通过 quartus->file->convert programming files
做好jic文件以后通过bluster烧录固化进去
六 没有nios只有逻辑的情况下的jic
生成sof以后方式跟上面一样,只是没把hex加进sof而已。没有nios的情况如何远程升级我还没学会,学会再加。
展示一下两个sof做到同一个jic里