LPC1768 secondary USB bootloader lock

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

LPC1768 secondary USB bootloader lock

3,056 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by il_mix on Mon Aug 19 02:21:39 MST 2013
Hi everyone!

I have a custom board (several boards of the same type) with an LPC1768 processor. Following AN10866 and the NXP example in the LPCXpresso folder, I made a secondary USB bootloader, that loads my user application (a blinky led, in the most simple case).
Everything works fine on most of my boards, but on some of them the bootloader fails to start the user application most of the time. Note that everytime I can upload my .bin file to the target; the lock happens after the system reset, when the loaded application must be run.
When it fails, the target can't be further accessed with JTAG (must erase the memory via ISP).
Also, in standalone mode (without the bootloader), the application always run correctly.

The application uses a custom script (.ld file) that defines the memoty like this
MEMORY
{
  /* Define each memory region */
  MFlash512 (rx) : ORIGIN = 0x10000, LENGTH = 0x70000 /* 512k; Bootloader mode */
  RamLoc32 (rwx) : ORIGIN = 0x100000C8, LENGTH = 0x7F38 /* 32k */
  RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */

}
  /* Define a symbol for the top of each memory region */
  __top_MFlash512 = 0x10000 + 0x70000; /* Bootloader mode */
  __top_RamLoc32 = 0x10000000 + 0x8000;
  __top_RamAHB32 = 0x2007c000 + 0x8000;


0x10000 is the address used by the bootloader for the "jump". The jump is made in this way
void (*user_code_entry)(void)
unsigned *p;// used for loading address of reset handler from user flash

// Change the Vector Table to the USER_FLASH_START 
//in case the user application uses interrupts 
SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80);

// Load contents of second word of user flash - the reset handler address
// in the applications vector table
p = (unsigned *)(USER_FLASH_START +4);  // USER_FLASH_START == 0x10000

// Set user_code_entry to be the address contained in that second word
// of user flash
user_code_entry = (void (*)()) *p;

// Jump to user application
user_code_entry();


I made several tests (here the most significant ones):

1) disable irq (with routine __disable_irq()) before the jump;
the user application won't run

2) step debug the bootloader;
after user_code_entry(), the debugger won't work anymore (can't pause, ...)
NOTE: when the bootloader works and the app starts, the debugger is still working, and when I pause it, I see a message that tells me it can't find the surce code at 0x12293 (or some other memory address). It's okay, since the code is in another application; the good thing is that the CPU is running the application (the pause address is the the application "memory block")


At the moment, I have just these informations.
Does anyone have any suggestion about what could be the problem? And maybe how to solve it...

Many thanks!
MIX

12 Replies

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rajeshreddy on Wed Apr 01 04:05:13 MST 2015
Add the below code just before setting the MSP

__set_CONTROL(0); // Change from PSP to MSP
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by _hollie_ on Mon May 05 06:19:11 MST 2014
OK, found it. My user application code relies on the mbed libraries and there were two problems:

[list]
  [*] The setup of the vector table in the mbed libs is not handled correctly when the vector table is not located at address 0x0000. When using a boot loader, this is triggered. I created a pull request for the mbed libraries to fix this (https://github.com/mbedmicro/mbed/pull/293)
  [*] The clock setup routines in the mbed code conflict with the clock settings I use in the boot loader (the CMSIS defaults). Under certain conditions this caused the controller to hang. Updating the clock settings in the mbed library (more specifically PLL0CFG_Val and CCLKCFG_Val) and recompiling them solves this issue.
[/list]
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by _hollie_ on Sun Apr 27 11:28:35 MST 2014
Hey,

yes, I'm using P1.30 as VBUS to detect if I should start USB mode or if I should jump to the user application.

I'm in the process of tracing the problem to the application code (based on the mbed libraries) and not to the boot loader. I suspect something is wrong with the reallocation of the interrupt handler.

With a very minimal application (just flashing LEDs with CMSIS) the application runs fine every time.

Good hint on putting a breakpoint in the exception handler. I'll try that out.
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 0xdeadbeef on Sun Apr 27 10:12:39 MST 2014
The code looks almost identical to the one I'm using.

For my understanding: are you using P1.30 as VBUS (which I also do) or is this also used as entry pin for the bootloader (which would be probably a bad idea)?

One more thing: I think I faintly remember that I had these "deadlock" situations as well when the CPU entered the exception handler with a very tight loop (while(1){}). Maybe I'm confusing this with another project/CPU but at least this kind of very short loop can result in situations where it looks like the CPU is frozen even though it's just in a very tight loop.
Usually it helps to set a breakpoint in the exception handler (e.g. IntDefaultHandler).
I also added some code there to have something to break on before the while loop. E.g.
dbg_dfsr = SCB->DFSR;
dbg_hfsr = SCB->HFSR;
dbg_mmfar = SCB->MMFAR;
dbg_bfar = SCB->BFAR;
dbg_afsr = SCB->AFSR;
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by _hollie_ on Thu Apr 24 11:49:26 MST 2014
Hello,

I am experiencing the same problem as described by @il_mix and I'm unsure on how to proceed to resolve it.

Problem description:
[list]
  [*]custom board with LPC1768, first batch made 2 years ago. That batch has been running the bootloader+application without problems.
  [*]a second batch was recently made, with minor hardware updates, the most important change that could be relevant to the problem is connecting the V_USB net to P1.30 to enable auto detect of the USB cable that is connected to enter the USB boot loader
[*] the boot loader runs fine at every reset (either by pulling the reset pin low or by removing the power)
[*] the application only gets started fine when the board has been powered down long enough (by physically removing the power). At all other times the boot loader runs and when the user code should get started from the boot loader the controller 'hangs' so hard that the debug connection becomes unavailable.
[*] when I leave the controller in this state sometimes the application gets started after a long and variable time
[/list]

I have read through the documentation, I have stepped through the boot loader up to the point where the application should get loaded. But I can't debug after this point as the debug connection becomes unavailable. I tried disabling the interrupts, I added the code to init the stack pointer to the correct address. I veried that the oscillator keeps running, that the Vcc is available.

My 'execute_user_code' now looks like this:
void execute_user_code(void)
{
void (*user_code_entry)(void);

unsigned *p;// used for loading address of reset handler from user flash

__disable_irq();

/* Change the Vector Table to the USER_FLASH_START
in case the user application uses interrupts */

unsigned int stack_adr = (USER_FLASH_START);
stack_adr = *(unsigned int*)stack_adr;
__set_MSP(stack_adr);

SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80);

// Load contents of second word of user flash - the reset handler address
// in the applications vector table
p = (unsigned *)(USER_FLASH_START +4);

// Set user_code_entry to be the address contained in that second word
// of user flash
user_code_entry = (void *) *p;

// Jump to user application
    user_code_entry();

}


Any hints on how one would debug this further? Any obvious errors/mistakes in this code? I guess that if I could extract an error code or status from the controller at the time the hang happens I would know how to debug this further. But without a working SWD interface this is rather hard...

Kind regards,
Lieven.
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by il_mix on Mon Dec 02 02:32:29 MST 2013
The current state is almost like the old one. I made several tests with no luck, and than had to switch to other projects.
Thanks to LPCXpresso Support for the documents. I've already stepped through the bootloader, but I will spend some more time given your info.
About your comment, 0xdeadbeef, it was my exact though. But I think I wasn't able to correctly manage the stack reset.
I will make some more tests in the next weeks. Hope to come back with good news.

Thanks!
MIX
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by 0xdeadbeef on Sat Nov 30 16:55:40 MST 2013
I had similar issues with the bootloader based on AN10866.
The problem with just jumping into the main system from the bootloader is that the stack pointer is not re-initialized correctly.
While without the boot loader, the 1st dword on the start vector would be automatically used as stack pointer, it is ignored when just jumping to the 2nd dword. So your main program will continue to use the boot stack which in best case wastes space and in worst case could be located at a completely different location and overwrite variables etc.

My project was done with CooCox and the bootloader with Keil, so your code might look different, but before jumping to the main system, you should add something like this:

        unsigned int stack_adr = (USER_FLASH_START);
        stack_adr = *(unsigned int*)stack_adr;

        __MSR_MSP(stack_adr);
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sat Nov 30 10:08:27 MST 2013
So please document exactly what the current behaviour is - rather than us relying on a report from 5 months ago, which may well be out of date as to the exact current situation.

Also, I presume that you have seen this…

http://support.code-red-tech.com/CodeRedWiki/DebugThroughBootloader

It might also be worth trying if you can start an attach only debug session…

http://support.code-red-tech.com/CodeRedWiki/DebugRunningSystem

Regards,
LPCXpresso Support
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by il_mix on Sat Nov 30 07:59:59 MST 2013
Since I'm still at the same point, bump!
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by il_mix on Mon Aug 19 23:43:22 MST 2013
It's the one I'm using. I've just removed the LCD part.
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Aug 19 09:19:42 MST 2013
Have you taken a look at the USB bootloader example provided by Code Red?

lpcxpresso\Examples\NXP\LPC1000\LPC17xx\RDB1768cmsis2.zip

and take a look at the usb_bootloader example
0 Kudos
Reply

2,406 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by il_mix on Mon Aug 19 07:25:56 MST 2013
I've read (again) various posts here and there, and applied various possible solution, but I'm still stuck with the bootloader jumping in a black hole.

I've tried:
1) Disable/enable IRQ, as said before
2) Switching to privileged mode in both the bootloader and my application
3) Removing all global variables and working with just local ones
4) Setting you jump address LSB to 1 (thumb instruction). Well, didn't really understand what this means. If I jump to the reset address+1, I jump to a wrong address. If I change the content of the address, the instruction changes. With these modification, as expected, even the usually working devices won't run the application correctly. Am I missing something?

So, still testing.
And waiting for good advices!

Thanks
MIX
0 Kudos
Reply