Hard Fault in ResetISR function when executing data_init() to copy data sections from flash to SRAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hard Fault in ResetISR function when executing data_init() to copy data sections from flash to SRAM

6,625 Views
dmckeever
Contributor II

I am attempting to add OTA to my rt1064 application based on examples from the latest SDK . I am using MCUXpresso IDE v11.7.1

I have modified my application to perform OTA upload and store signed bin file to secondary partition in flash; based on the evkmimxrt1064_lwip_httpssrv_ota_enet  example

I modified the start address to 0x70040400

I am now attempting to put the signed application image to the primary application partition, following method b) of the doc/readme,txt form the above example project:

- load the bootloader (successful, since terminal output is as expected)

- load the unsigned application using debugger then jump-start it by pause debugging and issue command 'jump ResetISR'

The application begins to execute the ResetISR function but stalls in the for loop within data_init with a hard fault.

__attribute__ ((section(".after_vectors.init_data")))
void data_init(unsigned int romstart, unsigned int start, unsigned int len) {
unsigned int *pulDest = (unsigned int*) start;
unsigned int *pulsrc=(unsigned int*) romstart;
unsigned int loop;
for (loop = 0; loop < len; loop = loop + 4)
*pulDest++ = *pulSrc++;
}

The application with unmodified start address of 0x70000000 runs fine from the debugger: the data sections are copied successfully from flash to RAM

Can you suggest why running by jump-start from debugger could cause this issue?

Thank you

0 Kudos
Reply
12 Replies

6,048 Views
dmckeever
Contributor II

I have at last found an explanation based on information in this topic:
https://community.nxp.com/t5/i-MX-RT/How-to-jump-to-application-from-custom-bootloader-where-both-ar...

My application has  XIP_BOOT_HEADER_DCD_ENABLE=1  and the evkmimxrt1064_mcuboot_opensource  project from the SDK does not have this setting. So the SDRAM is not configured when my application is jumped to, and so it stalls in the for loop within data_init with a hard fault.

I have modified the mcuboot project:
- added preprocessor symbols XIP_BOOT_HEADER_DCD_ENABLE=1  and SKIP_SYSCLK_INIT

- copied dcd.c from my application to ensure that they match

The application now starts using jump ResetISR

( I think that the documentation of the mcuboot opensource project in SDK should be enhanced to explain the necessity of XIP_BOOT_HEADER_DCD_ENABLE=1 to match the application)

0 Kudos
Reply

6,048 Views
dmckeever
Contributor II

I have a remaining problem.

The application loaded at 0x70040400  when started by jump ResetISR is behaving differently from the "standalone" version loaded at address 0x70000000 (ie with no bootloader present): it is stalling during ethernet access.

Is there any other property of the runtime environment that might not be set properly after jump ResetrISR?

0 Kudos
Reply

5,919 Views
dmckeever
Contributor II

Changing code location in XIP Flash causes program failure.

I have done further experiments to try to determine why the application loaded at 0x70040400 (for starting via bootloader) is behaving differently from the "standalone" version loaded at address 0x70000000 .

The difference is that the "bad" version fails: it stalls during sys_check_timeouts() in the LWIP code and the debugger loses control. The standalone version is "good" in that its execution continues without stalling.

To test if is is a code location issue, or an issue with the runtime environment set up for app execution, I took the "good" standalone version, temporarily disabled managed linker scripts, and added a padding directive as follows to the .ld file:

/* Image Vector Table and Boot Data for booting from external flash */
.boot_hdr : ALIGN(4)
{
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 ;
. = 0x40400 ;  /* Add padding to load next section at 0x70040400 */
} >PROGRAM_FLASH

/* MAIN TEXT SECTION */
.text : ALIGN(4)
{
FILL(0xff)
__vectors_start__ = ABSOLUTE(.) ;

This aligned the main text section in the modified "good" version to load at 0x70040400, ie same as "bad" version. Extract from .map file to show this:

0x00002000 . = 0x2000
*fill* 0x70001460 0xba0 ff
0x00040400 . = 0x40400
*fill* 0x70002000 0x3e400 ff

.text 0x70040400 0xc7734
FILL mask 0xff
0x70040400 __vectors_start__ = ABSOLUTE (.)
*(SORT_BY_ALIGNMENT(.isr_vector))
.isr_vector 0x70040400 0x2b8 ./startup/startup_mimxrt1064.o
0x70040400 g_pfnVectors
0x70040400 __Vectors
0x700406b8 . = ALIGN (0x4)

The remaining functions in the modified "good" version are loaded at addresses corresponding to those in the "bad" version

The modified "good" version with padding now fails in the same way as the "bad" version . Aside from the addition of padding, no other changes were made. So it appears to be a code location issue.

Can anyone suggest how changing the location of code in XIP flash could make a difference to program execution?




0 Kudos
Reply

6,583 Views
dmckeever
Contributor II

Further investigation. (Having set Opimization level to Optimize for Debug.)

Set breakpoint at for statement, ie after pulDest = (unsigned int*) start has been executed.

Expression evaluation shows:

Name : start
Hex:0x8005a0a0

Name : pulDest
Details:0x700426c4 <__section_table_start+12>
Hex:0x700426c4

So the address 0x8005a0a0 has been remapped to 0x700426c4 which is an address in flash

ie, pulDest is pointing to an address in flash and hence the subsequent assignment will cause the hard fault.

Can anyone suggest how this remapping may have occurred?

Thanks

 

 

0 Kudos
Reply

6,547 Views
dmckeever
Contributor II

We have discovered that the memory organization in the bootloader, plus location of stack and heap, must correspond with that in the application being jumped to / upgraded to. When these are brought into alignment the hard fault does not occur.


This is puzzling. I would have assumed that when an application is started at its ResetISR entry point it configures all memory settings etc independently. But it appears that some setting(s) from the bootloader that is already running can be incompatible with the new application.

0 Kudos
Reply

6,480 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @dmckeever ,

What do you mean of "correspond with"? Can't change?

 

Regards,

Jing

0 Kudos
Reply

6,473 Views
dmckeever
Contributor II

I mean that they must match:
- same memory blocks in same order
- same size of stack and heap

0 Kudos
Reply

6,416 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @dmckeever ,

I modify the start address to 0x70020000, so

jingpan_0-1690452009595.png

and in flash_partition.h

jingpan_1-1690452038133.png

I use MCUBootUtility to download signed image to flash. It works fine. 

 

Regards,

Jing

0 Kudos
Reply

6,409 Views
dmckeever
Contributor II

Hi Jing


Thanks for your reply.

Bootloader v 1.9.0 memory details:

dmckeever_0-1690454173652.png

My application memory details:

dmckeever_2-1690454365160.png

1. Use MCUXpresso to build and load bootloader

2. Use MCUXpresso to build and load application

3. Pause debugger. In Debugger Console, issue jump ResetISR. Application will not start.

 

By reverting to bootloader 1.7.2 from an earlier SDK, I was able to bring its memory details into line with my app

dmckeever_3-1690454813921.png

When this booloader 1.7.2 is loaded, the jump ResetISR to app works.


If I try to bring the memory details of latest bootloader 1.9.0 into line in the same way, then the bootloader itself does not start.

 

 

 

 

0 Kudos
Reply

6,363 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @dmckeever ,

You can use MCUBootUtility to download signed image to 0x70040000.

 

Regards,

Jing

0 Kudos
Reply

6,352 Views
dmckeever
Contributor II

Hi Jing

Thank you for the reply. I understand that I can use MCUBootUtility to download the signed image.

I have yet to confirm whether when using the bootloader and app combination where the jump ResetISR does not start the app, the bootloader will subsequently be able to start a downloaded signed app.

However, what I cannot yet understand is the following: why should it matter if the bootloader and app are different in their memory block usage or in any other properties?

When jump ResetISR fails to start the app when bootloader is already running, it appears that there must be some residual configuration of the system arising from the execution of the bootloader that is not overwritten by the initialization sequence in the app that is performed by the ResetISR function. What can this be?

My app is built from SDK examples; my understanding is that it should perform all necessary initialization to configure the system to the required state for its execution.

Any explanations or suggestions will be welcome.

0 Kudos
Reply

6,322 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @dmckeever ,

I use SDK2.13. Change the Heap and stack to itcm, and also the size. But it still can run by "jump ResetISR"...

 

Regards,

Jing

0 Kudos
Reply