I'm using MCUXpresso IDE to create a sample Hello World (VCP) application. I can run it from MCUXpresso fine and debug in RAM and have verified the application runs okay. I even can run it from Hyperflash and have it persistent, but our project will be using QSPI NOR flash and I'm trying to configure for this mode (which I know I have to use the Kinetis flashloader and NOT MCUXpresso).
I have set my project to start at 0x60002000 per the linker configuration for the application start point and got the MfgTool to successfully program a resulting boot_image.sd into the FlexSPI on the modified i.MXRT1052-EVKB board. However, my application didn't run, and subsequent attempts to program the QSPI with the MfgTool fails.
My end goal is currently NOT to run using XIP. Due to hardware issues on the first revision, our dead-bugged NOR flash device is a x1 configuration and will not be able to do XIP, so I want to use the ROM bootloader to load the image to RAM (our product will have SDRAM as well but running from TCM is preferred). However, whenever I try to configure an image to run from RAM (anything but 0x60002000 for an address) the 'elftosb' tool crashes.
The project settings that I had when I got the MfgTool to work were:
XIP_EXTERNAL_FLASH=0
XIP_BOOT_HEADER_ENABLE=1
XIP_BOOT_HEADER_DCD_ENABLE=0
Under Project Settings -> Memory, I have:
BOARD_FLASH 0x60002000 with a size of 0x3FFE000 and a driver of MIMXRT1050-EVK_IS25WP064A.cfx
SRAM_DTC 0x20000000 with a size of 0x20000
SRAM_ITC 0x0 with a size of 0x2000
SRAM_OC 0x20200000 with a size of 0x40000
BOARD_SDRAM 0x80000000 with a size of 0x2000000
Again, since I'm trying to mimic what our final product will be to have our application image in FlexSPI NOR (x1) (but using the EVKB's QSPI device), I'm trying to flash and load a program that resides in QSPI but will ultimately execute from RAM.
However, after the first successful programming (but failure to launch the code--maybe I used the padded version instead of the non-padded .bin file by mistake) I can no longer get ANY image to load on FlexSPI using the serial bootloader and MfgTool.
Also, every time I try and specify to NOT use XIP (various means, most are likely wrong--I'm trying to figure this out), the 'elftosb' tool, when creating the first .bin iMX boot image .bin file, always crashes.
Any thoughts on getting a FlexSPI NOR flash to work with MfgTool, built from MCUXpresso, without using XIP?
Thanks for any insight. I've been drilling through the rest of the community comments and code and haven't found exactly what I'm looking for yet...
Cheers,
Scott Thompson, TC Helicon
Solved! Go to Solution.
Hello Scott,
if you are using I.MXRT1050 SDK 2.3.1 or above version, you don't need to convert .bin file to be .sb file. please write .bin file to QSPI NOR FLASH by MFG tools.
Then configure board boots from port connected to QSPI NOR Flsh, and power it on!
Try it , please!
Have a nice day!
Best Regards,
Weidong
hello, i had requirement to store data as well program in same QSPI flash with imx rt 1050 i followed above process with different method that is through linker scrips to relocate all flexspi code to ITC ram . hope this would help
Dropbox - BEL2_flexspi_nor_polling_transfer.7z - Simplify your life
You can also try this tool, with this tool, You can flash bare image into various boot devices easily and don't need to care about headers (ivt, boot data...)
It's working! Sort-of.
The trick was to ensure the code was copied to 0x2000 in ITC, since the ROM image starts at 0x60002000. Specifying OCRAM as a destination always fails. I have to modify the boot configuration as given above, but the SRAM_OC_BASE is 0x0 and the size is 0x20000.
I'm able to get non-XiP working in QSPI x1 mode and x4 mode. I'm posting the configuration code here for anyone who needs it.
#define QSPI_USE_1PAD 0/*******************************************************************************
* Code
******************************************************************************/
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__GNUC__)
__attribute__((section(".boot_hdr.conf")))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.conf"
#endifconst flexspi_nor_config_t flexspi_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 3u,
.csSetupTime = 3u,
.columnAddressWidth = 0,
.deviceModeCfgEnable = 0,
.waitTimeCfgCommands = 0,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
.controllerMiscOption = 0u,
.deviceType = kFlexSpiDeviceType_SerialNOR,
#if defined(QSPI_USE_1PAD) && (QSPI_USE_1PAD == 1)
.sflashPadType = kSerialFlash_1Pad,
#else
.sflashPadType = kSerialFlash_4Pads,
#endif
.serialClkFreq = kFlexSpiSerialClk_50MHz,
.lutCustomSeqEnable = 0,
.sflashA1Size = 8u * 1024u * 1024u,
.dataValidTime = {16u, 16u},
.busyOffset = 0,
.busyBitPolarity = 0,
.lookupTable =
{
#if defined(QSPI_USE_1PAD) && (QSPI_USE_1PAD == 1)
[4 * NOR_CMD_LUT_SEQ_IDX_READ] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ+1] = FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00),
#else
[4 * NOR_CMD_LUT_SEQ_IDX_READ] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x6B, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ+1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x08, READ_SDR, FLEXSPI_4PAD, 0x04),
#endif[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01),[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x00),[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD7, RADDR_SDR, FLEXSPI_1PAD, 0x18),#if defined(QSPI_USE_1PAD) && (QSPI_USE_1PAD == 1)
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM+1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00),
#else
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM+1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_4PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00),
#endif[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xC7, STOP, FLEXSPI_1PAD, 0x00),[4 * NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 0x08, STOP, FLEXSPI_1PAD, 0x00),
},
},
.pageSize = 256U,
.sectorSize = 4096u,
.ipcmdSerialClkFreq = 0,
.isUniformBlockSize = 0,
.serialNorType = 0,
.blockSize = 32768u
};
Hi Scott,
Did you manage to flash XIP code to qspi using MFGTOOL. Even I am using MCUXpresso. My task is to work with emWin GUI which should have the xip driver included . I am using i.MXRT1050 EVKB board.
Thanks & Regards,
Anjali
Hello Anjali,
Yes, I was able to be successful in both flashing and booting XiP code as well as non-XiP code using MfgTool. In fact, I cannot use the USB debug interface to load code using MCUXpresso even though I have updated the firmware for QSPI in it.
Using the MfgTool required modification of a couple of the .xml files so that it could properly load the code to the right memory location (0x60000000 instead of 0x60020000 IIRC). Plus I had to add a command to the section that I was duplicating to actually erase the flash, which is why it always failed on subsequent tries when using the instructions given by the application notes, etc.
Also, as noted above, in order to properly achieve non-XiP code execution, I had to modify the image vector table (IVT) to have the pointers remapped to ITCM.
Remember, I'm not able to use MCUXpresso to load QSPI code nor debug from QSPI. I have to load to RAM and run from there when using MCUXpresso. The MfgTool is what I use to create a permanent image to the QSPI flash using the IVT builder code in MCUXpresso.
Good luck!
--Scott
Well, can get the SPI to get flashed but still cannot get non-XiP code to run.
Here's what I've done so far:
I modified the fsl_flexspi_nor_boot.c file to be more inline with non-XiP configuration as given in the i.MXRT1051 datasheet (see below). The reason I'm putting into SRAM_OC is from the datasheet it shows that the ROM loader puts the non-XiP code to this region.
#define BOOT_FLASH (0x60000000)
#define SRAM_OC_BASE (0x20200000)
#define SRAM_OC_SIZE (0x40000)#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__GNUC__)
__attribute__((section(".boot_hdr.ivt")))
#elif defined(__ICCARM__)
#pragma location=".boot_hdr.ivt"
#endif
/*************************************
* IVT Data
*************************************/
const ivt image_vector_table = {
IVT_HEADER, /* IVT Header */
IMAGE_ENTRY_ADDRESS, /* Image Entry Function (SRAM_OC @ 0x20201400)*/
IVT_RSVD, /* Reserved = 0 */
0, /* Address where DCD information is stored */
(uint32_t)BOOT_DATA_ADDRESS - BOOT_FLASH + SRAM_OC_BASE, /* Address where BOOT Data Structure is stored */
(uint32_t)((uint32_t)&image_vector_table - BOOT_FLASH + SRAM_OC_BASE), /* Pointer to IVT Self (absolute address */
0, /* Address where CSF file is stored */
IVT_RSVD /* Reserved = 0 */
};#if defined(__CC_ARM) || defined(__GNUC__)
__attribute__((section(".boot_hdr.boot_data")))
#elif defined(__ICCARM__)
#pragma location=".boot_hdr.boot_data"
#endif
/*************************************
* Boot Data
*************************************/
const BOOT_DATA_T boot_data = {
FLASH_BASE - BOOT_FLASH + SRAM_OC_BASE, /* boot start location */
FLASH_SIZE - FLASH_SIZE + SRAM_OC_SIZE, /* size */
PLUGIN_FLAG, /* Plugin flag*/
0xFFFFFFFF /* empty - extra data word */
};
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__GNUC__)
__attribute__((section(".boot_hdr.conf")))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.conf"
#endifconst flexspi_nor_config_t flexspi_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackInternally,
.csHoldTime = 3u,
.csSetupTime = 3u,
.columnAddressWidth = 0,
.deviceModeCfgEnable = 0,
.waitTimeCfgCommands = 0,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
.controllerMiscOption = 0u,
.deviceType = kFlexSpiDeviceType_SerialNOR,
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_50MHz,
.lutCustomSeqEnable = 0,
.sflashA1Size = 8u * 1024u * 1024u,
.dataValidTime = {16u, 16u},
.busyOffset = 1,
.busyBitPolarity = 0,
.lookupTable =
{
[4 * NOR_CMD_LUT_SEQ_IDX_READ] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x03, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ+1] = FLEXSPI_LUT_SEQ(READ_SDR, FLEXSPI_1PAD, 0x01, STOP, FLEXSPI_1PAD, 0x04),[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x01),[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x00),[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD7, RADDR_SDR, FLEXSPI_1PAD, 0x18),[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM+1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x00),[4 * NOR_CMD_LUT_SEQ_IDX_CHIPERASE] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xC7, STOP, FLEXSPI_1PAD, 0x00),[4 * NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_1PAD, 0x08, STOP, FLEXSPI_1PAD, 0x00),
},
},
.pageSize = 256U,
.sectorSize = 4096u,
.blockSize = 32768u,
.ipcmdSerialClkFreq = 0
};
<LIST name="MXRT105x-DevBootFlexSPI_noXiP" desc="Manufacturing with Flashloader">
<!-- Stage 1, load and execute Flashloader -->
<CMD state="BootStrap" type="boot" body="BootStrap" file="ivt_flashloader.bin" > Loading Flashloader. </CMD>
<CMD state="BootStrap" type="jump" onError = "ignore"> Jumping to Flashloader. </CMD><!-- Stage 2, Program boot image into external memory using Flashloader -->
<CMD state="Blhost" type="blhost" body="get-property 1" > Get Property 1. </CMD> <!--Used to test if flashloader runs successfully-->
<CMD state="Blhost" type="blhost" body="fill-memory 0x2000 4 0xc0000002"> Prepare FlexSPI Flash Configuration option </CMD>
<CMD state="Blhost" type="blhost" body="configure-memory 0x9 0x2000"> Configure QuadSPI NOR Flash </CMD>
<!-- This erase size need to be updated based on the actual boot image size-->
<CMD state="Blhost" type="blhost" timeout="30000" body="flash-erase-region 0x60000000 0x100000" > Erase 1MBytes </CMD>
<CMD state="Blhost" type="blhost" timeout="15000" body="write-memory 0x60000000 \"Profiles\\MXRT105x\\OS Firmware\\boot_image.bin\"" > Program Boot Image. </CMD>
<CMD state="Blhost" type="blhost" body="Update Completed!">Done</CMD>
</LIST>
<#-- Only insert header if Flash region starts at true base address -->
<#if (MemUtils.location(CODE) == Utils.strToInt("0x60000000")) >
/* Image Vector Table and Boot Data for booting from external flash */
.boot_hdr : ALIGN(${text_align})
{
FILL(0xff)
__boot_hdr_start__ = ABSOLUTE(.) ;
KEEP(*(.boot_hdr.conf))
. = 0x1000 ;
KEEP(*(.boot_hdr.ivt))
. = 0x1020 ;
KEEP(*(.boot_hdr.boot_data))
. = 0x1030 ;
KEEP(*(.boot_hdr.dcd_data))
__boot_hdr_end__ = ABSOLUTE(.) ;
. = 0x2000 ;
} >${CODE}</#if>
Hello Scott,
if you are using I.MXRT1050 SDK 2.3.1 or above version, you don't need to convert .bin file to be .sb file. please write .bin file to QSPI NOR FLASH by MFG tools.
Then configure board boots from port connected to QSPI NOR Flsh, and power it on!
Try it , please!
Have a nice day!
Best Regards,
Weidong
Thank you!
The problem with subsequent flashing is that I was using the profile identified in the App Note to load the boot_image.sb and that XML entry doesn't erase the flash--that's why all subsequent attempts to program the device have failed.
I created a new entry for FlexSPI_noXIP and see where the similarities in configuring using this tool and the accompanying .bd file are, so was able to configure for FlexSPI (x1) configuration at 50 MHz. Am now able to erase the chip, etc.
I still have to troubleshoot why my image doesn't boot, but I may need to rework the memory a bit, but you have got me on the right track.
Thank you for pointing me in the right direction; and I'm very happy to not have to fuss with the 'elftosb' tool and can certainly leverage the MfgTool to program the device when not pushing directly to RAM from MCUXpresso.
Really appreciate you taking the time to answer my question.
Cheers,
Scott Thompson, TC Helicon