BLHost - Execute application from NOR

cancel
Showing results for 
Search instead for 
Did you mean: 

BLHost - Execute application from NOR

Jump to solution
751 Views

Original Post - https://community.nxp.com/t5/i-MX-RT/BLHost-Execute-application-from-NOR/m-p/1546942#M22300


Hi

We are a production partner for a product that uses MIMXRT 1061. We are trying to set up a production test SW for the MIMXRT1060-based custom board.

 

During our development we had the following boot fuses configured FLASH_AUTO_PROBE_EN=1 and BT_FUSE_SEL=1. This gave us a successful boot to the application with both BOOT_MODE[1:0] = 00 (Boot from fuses) and BOOT_MODE[1:0] = 10 (Internal ROM).

Now we are trying to boot a production test application from FLEXSPI NOR memory on unfused units. I am trying to use the flash loader for MIMXRT1060 to load the application into the NOR memory. The write seems to be fine but the application does not seem to boot properly.

 

Here are the steps I am following.

sdphost -u 0x1FC9,0x0135 -- error-status

sdphost -u 0x1FC9,0x0135 -j -- write-file 0x20001C00 unsigned_MIMXRT1060_flashloader.bin

sleep 1 sdphost -u 0x1FC9,0x0135 -j -- jump-address 0x20001C00

sleep 3

echo ### Configure FlexSPI NOR memory using options on address 0x2000 ###

blhost -t 5000 %blhost_connect% -- fill-memory 0x2000 4 0xC0000008 word

blhost -t 5000 %blhost_connect% -- configure-memory 9 0x2000

@echo ### Erase memory before writing image ###

blhost -t 50352 %blhost_connect% -- flash-erase-region 0x60000000 35248 9

@echo ### Create Flash Configuration Block (FCB) using option on address 0x2000 ###

blhost -t 5000 %blhost_connect% -- fill-memory 0x2000 4 0xF000000F word

blhost -t 5000 %blhost_connect% -- configure-memory 9 0x2000

@echo ### Write image ###

blhost -t 5000 %blhost_connect% -- write-memory 0x60001000 test_sw.bin 9

blhost -t 5000 %blhost_connect% -- read-memory 0x60001000 8

blhost -t 5000 %blhost_connect% -- execute 0x6001 0 0

 

With the above steps, I am able to load the image to the external flash memory. The Factory Test application can boot if I fuse BT_FUSE_SEL=1. But the problem for us right now is that we don't want to fuse the unit during testing. Also, we are fully relying on SDP Host for our customer SW flashing at the end of production (we wont have access to JTAG pins when the unit is assembled).

I was wondering if there is a way to kick-start the factory test application from the NOR memory without fusing the unit. 

Please let me know if you need more information on this.

0 Kudos
1 Solution
608 Views
dereksnell
NXP Employee
NXP Employee

Hi @raghulshanmuganathan-sigm ,

First, I apologize for not being clearer about the interrupt vector table.  This device uses an Image Vector Table (IVT), that points to the application image, which then also has an interrupt vector table.  I went through the steps to execute the app using blhost, so I will explain this more below.

To provide you these detailed steps and knowing that you are using Zephyr, I built the Zephyr blinky application for the MIMXRT1060-EVKB board using Zephyr v3.2.  But by doing these steps, I realized the default application images built by Zephyr (and MCUXpresso SDK examples) will not boot with the blhost execute/call commands.  That is because by default these applications have the linker place the data in external SDRAM, including the stack.  The applications also include the Device Configuration Data (DCD) in the application image.  When the ROM bootloader boots from flash, it finds the DCD and configures the hardware according to that DCD, which initializes the clocks and SEMC for the external SDRAM.  But if the ROM bootloader boots in Serial Download mode instead, and blhost is used to launch the app, the bootloader does not read the DCD, and the SDRAM is not configured before the application executes.  

To workaround this, I modified the Zephyr devicetree to place data in internal SRAM instead of SDRAM, specifically in the Data Tightly-Coupled Memory (DTCM).  With this change, the DCD is not needed to launch the application, and blhost can launch it.  To make this change for this EVK, I modifed the file \zephyr\boards\arm\mimxrt1060_evk\mimxrt1060_evk.dts with the line below:

zephyr,sram = &dtcm;	# was &sdram0

 

Then I built the Zephyr application with this command below.  Attached is the generated binary file.

west build -b mimxrt1060_evkb samples\basic\blinky --pristine

 

I then used sdphost and blhost commands same as you to load the flashloader, configure the memory, and read the memory.  As you said, the Image Vector Table is located at address 0x60001000 in the flash.  Here are the first two words in this blinky IVT:

>blhost.exe   -u 0x15a2,0x0073 -- read-memory 0x60001000 8
Inject command 'read-memory'
Successful response to command 'read-memory'
d1 00 20 41 00 20 00 60
(1/1)100% Completed!
Successful generic response to command 'read-memory'
Response status = 0 (0x0) Success.
Response word 1 = 8 (0x8)
Read 8 of 8 bytes.

 

The second word in this IVT is the entry address that points to the address of the application.  For my blinky app, the blhost read command shows the entry address is 0x60002000.

dereksnell_0-1667920095670.png

 

I do another read command at the entry address to read the interrupt vector table of the application:

>blhost.exe   -u 0x15a2,0x0073 -- read-memory 0x60002000 8
Inject command 'read-memory'
Successful response to command 'read-memory'
00 10 00 20 91 33 00 60
(1/1)100% Completed!
Successful generic response to command 'read-memory'
Response status = 0 (0x0) Success.
Response word 1 = 8 (0x8)
Read 8 of 8 bytes.

 

The first word in the vector table is the initial stack pointer (SP), shown here as 0x20001000.  Note that after my devicetree change, this SP is now in DTCM.  That is important for the next steps.  Originally this SP was in SDRAM at base address 0x80000000, and blhost could not launch the application.

The second word in the vector table 0x60003391 is the reset vector.  With these two addresses, I can now use blhost to launch the app:

>blhost.exe   -u 0x15a2,0x0073 -- execute 0x60003391 0 0x20001000
Inject command 'execute'
Successful generic response to command 'execute'
Response status = 0 (0x0) Success.

 

 

 

Note in the above execute command, the 3rd argument is the stack pointer.  I also tested this command as "execute 0x60003391 0 0" and it does work in this case.  But I suspect that may depend on the application setting the SP before using it. 

I can also launch the app with the blhost call command like below.  When I use this command, you can see blhost reports an error because the app does not return to the flashloader.  But the app does execute on my EVK.

>blhost.exe   -u 0x15a2,0x0073 -- call 0x60003391 0
Inject command 'call'
sendCommandGetResponse.readPacket error 5.
Response status = 10004 (0x2714) No response packet from target device.

 

So now you can try these steps.  Your last post shows your entry address in the Image Vector Table is 0x6001A951, which seems like an unusual address for the application.  Can you read the flash at this address 0x6001A951 and share the results?  If needed, you can also use the .MAP file generated by the linker to confirm the reset entry address for the app.

Let us know if this works for you

View solution in original post

0 Kudos
10 Replies
609 Views
dereksnell
NXP Employee
NXP Employee

Hi @raghulshanmuganathan-sigm ,

First, I apologize for not being clearer about the interrupt vector table.  This device uses an Image Vector Table (IVT), that points to the application image, which then also has an interrupt vector table.  I went through the steps to execute the app using blhost, so I will explain this more below.

To provide you these detailed steps and knowing that you are using Zephyr, I built the Zephyr blinky application for the MIMXRT1060-EVKB board using Zephyr v3.2.  But by doing these steps, I realized the default application images built by Zephyr (and MCUXpresso SDK examples) will not boot with the blhost execute/call commands.  That is because by default these applications have the linker place the data in external SDRAM, including the stack.  The applications also include the Device Configuration Data (DCD) in the application image.  When the ROM bootloader boots from flash, it finds the DCD and configures the hardware according to that DCD, which initializes the clocks and SEMC for the external SDRAM.  But if the ROM bootloader boots in Serial Download mode instead, and blhost is used to launch the app, the bootloader does not read the DCD, and the SDRAM is not configured before the application executes.  

To workaround this, I modified the Zephyr devicetree to place data in internal SRAM instead of SDRAM, specifically in the Data Tightly-Coupled Memory (DTCM).  With this change, the DCD is not needed to launch the application, and blhost can launch it.  To make this change for this EVK, I modifed the file \zephyr\boards\arm\mimxrt1060_evk\mimxrt1060_evk.dts with the line below:

zephyr,sram = &dtcm;	# was &sdram0

 

Then I built the Zephyr application with this command below.  Attached is the generated binary file.

west build -b mimxrt1060_evkb samples\basic\blinky --pristine

 

I then used sdphost and blhost commands same as you to load the flashloader, configure the memory, and read the memory.  As you said, the Image Vector Table is located at address 0x60001000 in the flash.  Here are the first two words in this blinky IVT:

>blhost.exe   -u 0x15a2,0x0073 -- read-memory 0x60001000 8
Inject command 'read-memory'
Successful response to command 'read-memory'
d1 00 20 41 00 20 00 60
(1/1)100% Completed!
Successful generic response to command 'read-memory'
Response status = 0 (0x0) Success.
Response word 1 = 8 (0x8)
Read 8 of 8 bytes.

 

The second word in this IVT is the entry address that points to the address of the application.  For my blinky app, the blhost read command shows the entry address is 0x60002000.

dereksnell_0-1667920095670.png

 

I do another read command at the entry address to read the interrupt vector table of the application:

>blhost.exe   -u 0x15a2,0x0073 -- read-memory 0x60002000 8
Inject command 'read-memory'
Successful response to command 'read-memory'
00 10 00 20 91 33 00 60
(1/1)100% Completed!
Successful generic response to command 'read-memory'
Response status = 0 (0x0) Success.
Response word 1 = 8 (0x8)
Read 8 of 8 bytes.

 

The first word in the vector table is the initial stack pointer (SP), shown here as 0x20001000.  Note that after my devicetree change, this SP is now in DTCM.  That is important for the next steps.  Originally this SP was in SDRAM at base address 0x80000000, and blhost could not launch the application.

The second word in the vector table 0x60003391 is the reset vector.  With these two addresses, I can now use blhost to launch the app:

>blhost.exe   -u 0x15a2,0x0073 -- execute 0x60003391 0 0x20001000
Inject command 'execute'
Successful generic response to command 'execute'
Response status = 0 (0x0) Success.

 

 

 

Note in the above execute command, the 3rd argument is the stack pointer.  I also tested this command as "execute 0x60003391 0 0" and it does work in this case.  But I suspect that may depend on the application setting the SP before using it. 

I can also launch the app with the blhost call command like below.  When I use this command, you can see blhost reports an error because the app does not return to the flashloader.  But the app does execute on my EVK.

>blhost.exe   -u 0x15a2,0x0073 -- call 0x60003391 0
Inject command 'call'
sendCommandGetResponse.readPacket error 5.
Response status = 10004 (0x2714) No response packet from target device.

 

So now you can try these steps.  Your last post shows your entry address in the Image Vector Table is 0x6001A951, which seems like an unusual address for the application.  Can you read the flash at this address 0x6001A951 and share the results?  If needed, you can also use the .MAP file generated by the linker to confirm the reset entry address for the app.

Let us know if this works for you

0 Kudos
548 Views

The second word in the vector table 0x60003391 is the reset vector.

 

Thanks a lot, @dereksnell. That was the missing piece in the puzzle for me. 

I have tested the solution and it works well.

0 Kudos
737 Views
marek-trmac
NXP Employee
NXP Employee

Hi Shanmuganathan Sabarisathasivam,

it is also possible to select boot mode via pins. You can try this on EVK board, the step-by-step procedure is also described User Guide of the Secure Provisioning Tool.

Regards,
Marek
0 Kudos
736 Views

Hi,

Thanks for your response.

We have a custom board and we won't have access to the Boot Mode pins (test points) when the unit is fully assembled. 

I have noticed that I can use blhost -- execute command to start the application when BT_FUSE_SEL=1 but it doesn't seem to work when the unit is completely unfused.

0 Kudos
726 Views
marek-trmac
NXP Employee
NXP Employee

Hi,

so basically this command fails, right?

blhost -t 5000 %blhost_connect% -- execute 0x6001 0 0

So you are trying to start the code at address 0x6001 with stack pointer at 0, is it intended? Sorry, I do not have any experience with that, so I'm just asking.

Have you tried "blhost -- call" ?

Regards,
Marek
0 Kudos
719 Views

Hi again @marek-trmac , 

blhost -t 5000 %blhost_connect% -- execute 0x6001 0 0

No, the execute command does not fail. It gives success but the application does not seem to run.
But when I tried the call command, it seems to fail.

The reason for using the address 0x6001 is from the following answer from @dereksnell 

https://community.nxp.com/t5/i-MX-RT/mimxrt1024-EVK-flash-and-boot/m-p/1306050

This is the address I see on the reset vector.

 

0 Kudos
715 Views
marek-trmac
NXP Employee
NXP Employee

Hi,

in RT1024 thread, they write an image to address 0x0 and then start execution with some offset.

You wrote application to 0x60001000, so you should run it from 0x6000XXXX

 

We do not use execute command for RT10xx in Secure Provisioning Tool, so I do not have any expirience with it, so I do not have any functional example.

Regards,
Marek
0 Kudos
712 Views

Hi @marek-trmac,

The execute or call command from 0x6000xxxx fails all the time.

I have also tried to uncomment the entry point address (0x60002000) from the flexspi-image-unsigned.bd file to not let Reset Handler handle that. Then I tried the SDP host command JUMP_ADDRESS to directly jump to that address. That seems to not work either.

 

0 Kudos
664 Views
dereksnell
NXP Employee
NXP Employee

Hi @raghulshanmuganathan-sigm ,

You are trying to eXecute-In-Place (XIP) from the NOR flash, correct?  If so, the address of 0x6001 would not be the correct address for the reset vector, as 0x6001 is in the ITCM internal SRAM.

The reset vector will be included in the Interrupt Vector Table (IVT) that you programmed in the flash.  After programming the image, you can use the blhost read-memory command to read the IVT and confirm the address in the reset vector.  The reset vector will be the 4 bytes at offset 0x4 in the IVT.  Can you share the results from blhost when reading the IVT, so we can see the reset vector?

With the correct reset vector address to the application in flash memory, then you can use the blhost execute command to start that app.

Thanks

0 Kudos
622 Views

Hi @dereksnell ,

Yes that's correct. 

IVT must be at the address 0x60001000. Here are the results after reading that address.

D:\test>blhost -t 5000 -u 0x15A2,0x0073 -- read-memory 0x60001000 8
Inject command 'read-memory'
Successful response to command 'read-memory'
d1 00 20 40 51 a9 01 60

 
Should I use 0xa951 in this case?

0 Kudos