SDK 2018.3 支持烧写没有DDR的单板的Flash。
但是SDK 2018.3烧写Flash需要一个FSBL。缺省的FSBL,发现没有定义DDR基地址,会直接退出,导致devcfg、QSPI等模块没有初始化,从而导致烧写Flash失败。
错误信息如下。
cmd /C program_flash -f C:prjmzed_ddrless.sdkApplicationootimageBOOT.bin -offset 0 -flash_type qspi_single -fsbl C:prjmzed_ddrless.sdkfsbl_ddrless_not_xipDebugfsbl_ddrless_not_xip.elf -blank_check -verify -cable type xilinx_tcf url TCP:127.0.0.1:3121 ****** Xilinx Program Flash ****** Program Flash v2018.2 (64-bit) **** SW Build 2258646 on Thu Jun 14 20:03:12 MDT 2018 ** Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. Connected to hw_server @ TCP:127.0.0.1:3121 Available targets and devices: Target 0 : jsn1 Target 1 : jsn-DLC10-000016c46e9801 Device 0: jsn-DLC10-000016c46e9801-4ba00477-0 Retrieving Flash info... Initialization done, programming the memory ===== mrd->addr=0xF800025C, data=0x00000000 ===== BOOT_MODE REG = 0x00000000 Downloading FSBL... Running FSBL... Finished running FSBL. ===== mrd->addr=0xF8000110, data=0x000FA220 ===== READ: ARM_PLL_CFG (0xF8000110) = 0x000FA220 ===== mrd->addr=0xF8000100, data=0x00028008 ===== READ: ARM_PLL_CTRL (0xF8000100) = 0x00028008 ===== mrd->addr=0xF8000120, data=0x1F000200 ===== READ: ARM_CLK_CTRL (0xF8000120) = 0x1F000200 ===== mrd->addr=0xF8000118, data=0x001452C0 ===== READ: IO_PLL_CFG (0xF8000118) = 0x001452C0 ===== mrd->addr=0xF8000108, data=0x0001E008 ===== READ: IO_PLL_CTRL (0xF8000108) = 0x0001E008 Info: Remapping 256KB of on-chip-memory RAM memory to 0xFFFC0000. ===== mrd->addr=0xF8000008, data=0x00000000 ===== ===== mwr->addr=0xF8000008, data=0x0000DF0D ===== MASKWRITE: addr=0xF8000008, mask=0x0000FFFF, newData=0x0000DF0D ===== mwr->addr=0xF8000910, data=0x000001FF ===== ===== mrd->addr=0xF8000004, data=0x00000000 ===== ===== mwr->addr=0xF8000004, data=0x0000767B ===== MASKWRITE: addr=0xF8000004, mask=0x0000FFFF, newData=0x0000767B Problem in running uboot Flash programming initialization failed. ERROR: Flash Operation Failed
执行下列步骤,可以实现烧写没有DDR的单板的Flash。
1. 为了便于调试,建议在工程设置中,或者在文件fsbl_debug.h中,定义宏FSBL_DEBUG_INFO。
2. 确保工程中没有定义XPAR_PS7_DDR_0_S_AXI_BASEADDR。如果有定义,可以在fsbl.h中添加下列行,去掉XPAR_PS7_DDR_0_S_AXI_BASEADDR的定义。示例如下:
#undef XPAR_PS7_DDR_0_S_AXI_BASEADDR
3. 将ps7_init.c从hardware platform工程,复制到FSBL工程;再屏蔽其中的DDR初始化代码。示例如下:
// DDR init //ret = ps7_config (ps7_ddr_init_data); //if (ret != PS7_INIT_SUCCESS) return ret;
4. 修改FSBL的main.c,使其在没有DDR基地址情况下,只是不执行DDR相关操作,继续初始化devcfg、QSPI等模块。使用这种FSBL,烧写Flash成功。参考代码如下:
int main(void) { u32 BootModeRegister = 0; u32 HandoffAddress = 0; u32 Status = XST_SUCCESS; u32 RegVal; /* * PCW initialization for MIO,PLL,CLK and DDR */ Status = ps7_init(); if (Status != FSBL_PS7_INIT_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"PS7_INIT_FAIL : %s ", getPS7MessageInfo(Status)); OutputStatus(PS7_INIT_FAIL); /* * Calling FsblHookFallback instead of Fallback * since, devcfg driver is not yet initialized */ FsblHookFallback(); } /* * Unlock SLCR for SLCR register write */ SlcrUnlock(); /* If Performance measurement is required * then read the Global Timer value , Please note that the * time taken for mio, clock and ddr initialisation * done in the ps7_init function is not accounted in the FSBL * */ #ifdef FSBL_PERF XTime tCur = 0; FsblGetGlobalTime(&tCur); #endif /* * Flush the Caches */ Xil_DCacheFlush(); /* * Disable Data Cache */ Xil_DCacheDisable(); /* * Register the Exception handlers */ RegisterHandlers(); /* * Print the FSBL Banner */ fsbl_printf(DEBUG_GENERAL," Xilinx First Stage Boot Loader "); fsbl_printf(DEBUG_GENERAL,"Release %d.%d %s-%s ", SDK_RELEASE_YEAR, SDK_RELEASE_QUARTER, __DATE__,__TIME__); #ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR /* * DDR Read/write test */ Status = DDRInitCheck(); if (Status == XST_FAILURE) { fsbl_printf(DEBUG_GENERAL,"DDR_INIT_FAIL "); /* Error Handling here */ OutputStatus(DDR_INIT_FAIL); /* * Calling FsblHookFallback instead of Fallback * since, devcfg driver is not yet initialized */ FsblHookFallback(); } #endif // XPAR_PS7_DDR_0_S_AXI_BASEADDR /* * PCAP initialization */ Status = InitPcap(); if (Status == XST_FAILURE) { fsbl_printf(DEBUG_GENERAL,"PCAP_INIT_FAIL "); OutputStatus(PCAP_INIT_FAIL); /* * Calling FsblHookFallback instead of Fallback * since, devcfg driver is not yet initialized */ FsblHookFallback(); } fsbl_printf(DEBUG_INFO,"Devcfg driver initialized "); /* * Get the Silicon Version */ GetSiliconVersion(); #ifdef XPAR_XWDTPS_0_BASEADDR /* * Check if WDT Reset has occurred or not */ CheckWDTReset(); /* * Initialize the Watchdog Timer so that it is ready to use */ Status = InitWatchDog(); if (Status == XST_FAILURE) { fsbl_printf(DEBUG_GENERAL,"WATCHDOG_INIT_FAIL "); OutputStatus(WDT_INIT_FAIL); FsblFallback(); } fsbl_printf(DEBUG_INFO,"Watchdog driver initialized "); #endif /* * Get PCAP controller settings */ PcapCtrlRegVal = XDcfg_GetControlRegister(DcfgInstPtr); /* * Check for AES source key */ if (PcapCtrlRegVal & XDCFG_CTRL_PCFG_AES_FUSE_MASK) { /* * For E-Fuse AES encryption Watch dog Timer disabled and * User not allowed to do system reset */ #ifdef XPAR_XWDTPS_0_BASEADDR fsbl_printf(DEBUG_INFO,"Watchdog Timer Disabled "); XWdtPs_Stop(&Watchdog); #endif fsbl_printf(DEBUG_INFO,"User not allowed to do " "any system resets "); } /* * Store FSBL run state in Reboot Status Register */ MarkFSBLIn(); /* * Read bootmode register */ BootModeRegister = Xil_In32(BOOT_MODE_REG); BootModeRegister &= BOOT_MODES_MASK; /* * QSPI BOOT MODE */ #ifdef XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR #ifdef MMC_SUPPORT /* * To support MMC boot * QSPI boot mode detection ignored */ if (BootModeRegister == QSPI_MODE) { BootModeRegister = MMC_MODE; } #endif if (BootModeRegister == QSPI_MODE) { fsbl_printf(DEBUG_GENERAL,"Boot mode is QSPI "); InitQspi(); MoveImage = QspiAccess; fsbl_printf(DEBUG_INFO,"QSPI Init Done "); } else #endif // XPAR_PS7_QSPI_LINEAR_0_S_AXI_BASEADDR /* * NAND BOOT MODE */ #ifdef XPAR_PS7_NAND_0_BASEADDR if (BootModeRegister == NAND_FLASH_MODE) { /* * Boot ROM always initialize the nand at lower speed * This is the chance to put it to an optimum speed for your nand * device */ fsbl_printf(DEBUG_GENERAL,"Boot mode is NAND "); Status = InitNand(); if (Status != XST_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"NAND_INIT_FAIL "); /* * Error Handling here */ OutputStatus(NAND_INIT_FAIL); FsblFallback(); } MoveImage = NandAccess; fsbl_printf(DEBUG_INFO,"NAND Init Done "); } else #endif /* * NOR BOOT MODE */ if (BootModeRegister == NOR_FLASH_MODE) { fsbl_printf(DEBUG_GENERAL,"Boot mode is NOR "); /* * Boot ROM always initialize the nor at lower speed * This is the chance to put it to an optimum speed for your nor * device */ InitNor(); fsbl_printf(DEBUG_INFO,"NOR Init Done "); MoveImage = NorAccess; } else /* * SD BOOT MODE */ #if defined(XPAR_PS7_SD_0_S_AXI_BASEADDR) || defined(XPAR_XSDPS_0_BASEADDR) if (BootModeRegister == SD_MODE) { fsbl_printf(DEBUG_GENERAL,"Boot mode is SD "); /* * SD initialization returns file open error or success */ Status = InitSD("BOOT.BIN"); if (Status != XST_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"SD_INIT_FAIL "); OutputStatus(SD_INIT_FAIL); FsblFallback(); } MoveImage = SDAccess; fsbl_printf(DEBUG_INFO,"SD Init Done "); } else if (BootModeRegister == MMC_MODE) { fsbl_printf(DEBUG_GENERAL,"Booting Device is MMC "); /* * MMC initialization returns file open error or success */ Status = InitSD("BOOT.BIN"); if (Status != XST_SUCCESS) { fsbl_printf(DEBUG_GENERAL,"MMC_INIT_FAIL "); OutputStatus(SD_INIT_FAIL); FsblFallback(); } MoveImage = SDAccess; fsbl_printf(DEBUG_INFO,"MMC Init Done "); } else #endif // defined(XPAR_PS7_SD_0_S_AXI_BASEADDR) || defined(XPAR_XSDPS_0_BASEADDR) /* * JTAG BOOT MODE */ if (BootModeRegister == JTAG_MODE) { fsbl_printf(DEBUG_GENERAL,"Boot mode is JTAG "); RegVal = Xil_In32(XPS_DEV_CFG_APB_BASEADDR + XDCFG_INT_STS_OFFSET); /** If bitstream was loaded in jtag boot mode prior to running FSBL */ if(RegVal & XDCFG_IXR_PCFG_DONE_MASK) { #ifdef PS7_POST_CONFIG ps7_post_config(); /* * Unlock SLCR for SLCR register write */ SlcrUnlock(); #endif } /* * Stop the Watchdog before JTAG handoff */ #ifdef XPAR_XWDTPS_0_BASEADDR XWdtPs_Stop(&Watchdog); #endif /* * Clear our mark in reboot status register */ ClearFSBLIn(); /* * SLCR lock */ SlcrLock(); FsblHandoffJtagExit(); } else { fsbl_printf(DEBUG_GENERAL,"ILLEGAL_BOOT_MODE "); OutputStatus(ILLEGAL_BOOT_MODE); /* * fallback starts, no return */ FsblFallback(); } fsbl_printf(DEBUG_INFO,"Flash Base Address: 0x%08lx ", FlashReadBaseAddress); /* * Check for valid flash address */ if ((FlashReadBaseAddress != XPS_QSPI_LINEAR_BASEADDR) && (FlashReadBaseAddress != XPS_NAND_BASEADDR) && (FlashReadBaseAddress != XPS_NOR_BASEADDR) && (FlashReadBaseAddress != XPS_SDIO0_BASEADDR)) { fsbl_printf(DEBUG_GENERAL,"INVALID_FLASH_ADDRESS "); OutputStatus(INVALID_FLASH_ADDRESS); FsblFallback(); } /* * NOR and QSPI (parallel) are linear boot devices */ if ((FlashReadBaseAddress == XPS_NOR_BASEADDR)) { fsbl_printf(DEBUG_INFO, "Linear Boot Device "); LinearBootDeviceFlag = 1; } #ifdef XPAR_XWDTPS_0_BASEADDR /* * Prevent WDT reset */ XWdtPs_RestartWdt(&Watchdog); #endif #ifdef XPAR_PS7_DDR_0_S_AXI_BASEADDR /* * This used only in case of E-Fuse encryption * For image search */ SystemInitFlag = 1; /* * Load boot image */ HandoffAddress = LoadBootImage(); fsbl_printf(DEBUG_INFO,"Handoff Address: 0x%08lx ",HandoffAddress); /* * For Performance measurement */ #ifdef FSBL_PERF XTime tEnd = 0; fsbl_printf(DEBUG_GENERAL,"Total Execution time is "); FsblMeasurePerfTime(tCur,tEnd); #endif /* * FSBL handoff to valid handoff address or * exit in JTAG */ FsblHandoff(HandoffAddress); #else OutputStatus(NO_DDR); FsblFallback(); #endif return Status; }