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?
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.
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!
-----------------------------------------------------------------------------------------------------------------------
Dear @Alice_Yang
Just a question: how I can put a code into linker file whether it is auto-generated?
Reagrds
Marco
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
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
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
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.
Hi Bill,
OK, I think your idea is excellent , thanks for your sharing.
BR
Alice