Debug Fails When Application is Offset in Flash

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

Debug Fails When Application is Offset in Flash

2,178 Views
billherring
Contributor I

Hi,

I have MCUXpresso 10.1.0 and an LPC Link 2 debug adaptor connected to my application hardware which is based upon an LPC1766 microcontroller. The debug connection is SWD.

My main application is located at an 0x3000 offset in flash in order to leave room for a boot application at 0x0000. This seems to cause a problem for MCUXpresso!

I am trying to migrate from an existing IAR Embedded Workbench tool that has absolutely no problem loading, running and debugging my main application at the offset. However MCUXpresso simply refuses to do so automatically. The failure is normally 'Wire ACK fault in DAP access' and at the same time it manages to find its way to the Hardware Fault vector routine.

If I change my code and memory map in order to run the application from a 0 offset in flash instead then the problem does not arise. So there is obviously nothing wrong with the probe or my hardware or my code. But I'd rather not fiddle around like this, changing everything, depending upon whether I'm building for debug or release!

Because running from offset 0 seems to work, I expected that if I first wrote my boot application to flash (i.e. at offset 0) then, when I requested a main debug, the boot would run and route to my main application as its designed to do. Unfortunately not - same failure which I've come to suspect is when the debug has no source to match what is running. So I tried adding my boot application source/symbols to the main debug which resulted in some success in that the 'Wire Ack fault' is eliminated but still the hard fault.

An interesting work around I've found is to simply copy the vector table from my compiled main application binary and write it to flash at 0 offset. This seems to be enough to get me to my main application 'main' without any fault. Again I don't really want to have to do this every time I compile and debug! However it does support the feeling that MCUXpresso is not itself coping with finding an offset application.

Can anyone help please? Am I missing something, doing something wrong? Or can MCUXpresso simply not do this?

0 Kudos
8 Replies

1,887 Views
billherring
Contributor I

Hi,

For anyone that might be interested I've now got to the bottom of my problem. It was my fault.

I was using similar 'boot' code to that suggested by Alice (above). At least it had the same intent but it was different. It had compiled fine with my old IAR compiler but I hadn't noticed (until looking more closely) that mcuxpresso was optimising an important element of it away, causing the hard fault every time my boot attempted to jump to my main application. I've now modified it to look more like Alice's suggested code. 

So, if your application is offset in flash and you need to debug it there, I can now vouch for the fact that a reasonable approach is to first flash your boot code (or something similar to Alice's suggestion) into place at 0x0. Subsequent application debugs then work fine.

0 Kudos

1,887 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hello Bill Herring,

It seems the MCUXpresso debug probe doesn't include this function about directly jump to

the offset address (eg. 0x3000) .

The reset address is 0x0000, while in your case there is no data at this memory, so debug crash.

If want to debug project directly from 0x3000, you can add some jump code at 0x00 address,

make SP = 0x3000, PC = 0x3004 .

For example add the below code in to your project (just a suggestion, maybe more complex than change start address to 0x00)

//*****************************************************************************

load  these code in 0x00 address:

__attribute__ ((used, section(".isr_vector_test")))    
void (* const g_pfnVectors_alice[])(void) =
    &_vStackTop,
    reset_alice,

};

__attribute__ ((section(".after_vectors_test")))
reset_alice()
{
    jump_test(*((unsigned long*)0x3000), *((unsigned long*)(0x3000+4)));
}

__attribute__ ((section(".after_vectors_test_2")))
void jump_test(long int userSP, long int userStartup)
{
    // set up stack pointer
  __asm("msr msp, r0");
  __asm("msr psp, r0");

  // Jump to PC (r1)
  __asm("mov pc, r1");
}

in linker file :

 /* Define each memory region */
Flash_00 (rx) : ORIGIN = 0x0, LENGTH = 0x3000

   .text_Flash2 : ALIGN(8)
    {
       FILL(0xff)
      KEEP(*(.isr_vector_test))
      KEEP(*(.after_vectors_test))
     KEEP(*(.after_vectors_test_2))

    } > Flash_00


Have a great day,
TIC

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,753 Views
MarcoGiammarini
Contributor III

Dear @Alice_Yang 

Just a question: how I can put a code into linker file whether it is auto-generated?

Reagrds

Marco

0 Kudos

1,748 Views
ErichStyger
Senior Contributor V

Hi @MarcoGiammarini ,

you can modify the automatic linker script with using Freemarker scripts. See for example I do this with for a bootloader: https://mcuoneclipse.com/2019/10/06/linking-bootloader-applications-with-eclipse-and-freemarker-scri...

Another usage is here: https://mcuoneclipse.com/2017/08/29/tutorial-porting-blenrf-kinetis-design-studio-project-to-mcuxpre...

The folder needs to be named 'linkscripts' and then you can place your 'overrrides' into it.

 

I hope this helps,

Erich

0 Kudos

1,738 Views
MarcoGiammarini
Contributor III

I try to follow your article, but my application doesn't start and goes into hard fault. I had also the following code, but nothing. Do you have any ideas? I am working on KL27.

Regards

Marco

#if defined(APPLICATION_HAS_BOOTLOADER)

  #define ISR_VECTOR_ADDRESS    (0x4000)

  // Set VTOR register in SCB first thing we do.

  SCB->VTOR = ISR_VECTOR_ADDRESS;

  __set_MSP(((uint32_t*)ISR_VECTOR_ADDRESS)[0]);

  __set_PSP(((uint32_t*)ISR_VECTOR_ADDRESS)[0]);

#endif

0 Kudos

1,740 Views
MarcoGiammarini
Contributor III

HI @ErichStyger 

Thanks for the reply. I read your article, but I don't understand why there is two flash section with the same address. Flash and PROGRAM_FLASH are equal!

  /* Define a symbol for the top of each memory region */

  __base_PROGRAM_FLASH = 0x0+__BOOTLOADER_APPLICATION_OFFSET ; /* PROGRAM_FLASH */  

  __base_Flash = 0x0+__BOOTLOADER_APPLICATION_OFFSET ; /* Flash */  

  __top_PROGRAM_FLASH = 0x0 + 0x40000 ; /* 256K bytes */  

  __top_Flash = 0x0 + 0x40000 ; /* 256K bytes */  

  __base_SRAM = 0x1fffe000  ; /* SRAM */  

  __base_RAM = 0x1fffe000 ; /* RAM */  

  __top_SRAM = 0x1fffe000 + 0x8000 ; /* 32K bytes */  

  __top_RAM = 0x1fffe000 + 0x8000 ; /* 32K bytes */  

 

Regards

Marco

0 Kudos

1,887 Views
billherring
Contributor I

Hi Alice_Yang,

Thank you for your suggestion which I agree should work. I do already have very similar code to yours that I've tried writing to flash 0 but I still get trapped by the hard fault interrupt handler when I try to debug the main application.

I've decided I need to make progress with my development and so for now I've created a 'Debug' build that locates my main application at flash 0 and this obviously allows me to debug it without fault. I then have a separate 'Release' build that correctly locates the application at flash 0x3000 and generates a binary that can be used away from the debugger.

Cheers.

0 Kudos

1,887 Views
Alice_Yang
NXP TechSupport
NXP TechSupport

Hi Bill,

OK, I think your idea is excellent , thanks for your sharing.

BR

Alice

0 Kudos