What address to Jump to after CAN ISP code update for LPC15xx

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

What address to Jump to after CAN ISP code update for LPC15xx

2,546 Views
gregwilson-lind
Contributor II

I don't understand what address to use to start the program after updating code using CAN ISP. The Cortex-M Reset vector (vector 1) looks like it is expecting to have the MSP set to the value in vector 0, the starting value of the MSP. The CAN ISP commands do not have the option to load the stack pointer, so I don't understand what address should be used as the starting address for the CAN ISP Go command.

Any help would be greatly appreciated.

Greg

Labels (1)
Tags (2)
0 Kudos
17 Replies

1,876 Views
Dezheng_Tang
NXP Employee
NXP Employee

Use SDO Execution Address (Index: 0x5070) to specify the execution address first, then use
SDO Program Control (Index: 0x1F51, value = 0x01) to run from above address + 1(Thumb mode).

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Yes, I know how to do it, I don't know what address to set it to.

On power up the processor jumps to the address contained in vector 1 (address 0x0004), with the MSP (Stack Pointer) set to the address contained in vector 0 (address 0x0000). While it is easily possible to jump to the address in vector 1, i.e. set OD5070:0 to vector 1. There is no way to set the MSP to the value in vector 0. If the code expects the MSP to be set on entry, then the code is not going to execute properly if the MSP is not set to the correct value. If the Reset code pointed to by vector 1 loads the MSP itself, then everything will work properly, but I do not know of any documentation that says that that is the case.

That is the crux of my question, what address to jump to the get the processor to execute properly after updating the code.

Of course, a reset of the processor would work also, but that doesn't seem to be possible either.

0 Kudos

1,876 Views
Dezheng_Tang
NXP Employee
NXP Employee

The execution address should be the beginning address of your RO region when you build your application.

The user code should reload the stack pointer(SP) yourself, if you don't do that, the SP is pointing to somewhere used by the CAN ISP. See 34.3.6.3 "RAM used by ISP command handler".

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

On an ARM Cortex-M3 the beginning of the Flash is the interrupt vector table, not code. On the LPC15 elf files that I've dumped the 'text' section starts at address 0x0000, which is the interrupt vector table. User code starts at some address after the interrupt vectors. The start up code is not necessarily the first code after the vector table, that's why vector 1 points to the 'reset' vector, or code to execute on coming out of reset.

As far as the 'user' code setting up the stack pointer, that is handled by the startup code provided by NXP's & ARM's libraries, the 'user' has no control over how that works and no visibilty as far as I know, I haven't seen source code for the start up. The LPC15 User Manual (UM10736 @ 5.4.2) doesn't say if the boot code sets up the Stack Pointer from vector 0, just that it executes the user app, which according to ARM is pointed to by vector 1.

In the 'M3 Guide' written by Joseph Yui, in section 3.7 RESET SEQUENCE, it says that the processor reads address 0, the starting value of MSP, and address 4, the Reset vector, and that the MSP is loaded by hardware so that exceptions can be handled immediately. So, on a hard power up the MSP is initialized by hardware and software does not need to initialize it. I would expect that the ROM boot up code needs to follow the same procedure and initialize the MSP before executing user code.

So I still don't know if it is possible to just start execution at the address in vector 1, it would seem that it isn't.

0 Kudos

1,876 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Greg Wilson-Lindberg,

Let me clarify it.

When MCU is powered up, it will follow the reset sequence which is illustrated in the section 3.7 RESET SEQUENCE as you mentioned. And the MCU can load the MSP and fetch the reset vector automatically after reset.

To enter or jump secondary application code, you also need to follow the same sequence:

1) Updating the stack pointer (SP)

2) Program counter (PC) register

And I'd like to share a jump function, and you can refer to it.

// the parameter means the first address of the target application

__asm void boot_jump( uint32_t address ){
   LDR SP, [R0]        ; //Load new stack pointer address
   LDR PC, [R0, #4]    ;//Load new program counter address
}

Hope this is clear.
Have a great day,
Ping

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

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Yes, I understand that it is necessary to set up the stack pointer and the execution address. The problem comes in that i'm trying to do this across the CAN bus with the the CAN ISP functions.

If what you are trying to say is that I should add this function to my code and then have the ISP Go call execute this function, how am I supposed to find the address for this function so that I can have the Go function execute it

0 Kudos

1,876 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Greg Wilson-Lindberg,

In my opinion, the CAN go command is the trigger which is used to execute the jump function to start application, and the jump function just likes the __asm void boot_jump( uint32_t address ), it has already loaded new stack pointer address before jump to the application code, so you needn't to do this kind of job before send the Go command.

Hope this is clear.
Have a great day,
Ping

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

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Hi Ping,

I've got what the function does, How do I figure out what the address of the function is so that I can get the Go command to jump to it.

Regards,

Greg

0 Kudos

1,876 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Greg Wilson-Lindberg,

The function is located in the ROM area, and you needn't know the exactly address of the function,

the command would call the function automatically.
Have a great day,
Ping

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

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Hi Ping,

I do not find a boot_jump() function listed as one of the functions that can be executed from the CAN ISP interface, so the question still becomes if I add the function in my code, how do I find its address so that I can give it to the GO command to execute it?

0 Kudos

1,874 Views
converse
Senior Contributor V

jeremyzhou provided the source code in one of the first replies above. The code (extracted from one of the messages in this thread) is:

// the parameter means the first address of the target application

__asm void boot_jump( uint32_t address ){
   LDR SP, [R0]        ; //Load new stack pointer address
   LDR PC, [R0, #4]    ;//Load new program counter address
}

0 Kudos

1,874 Views
gregwilson-lind
Contributor II

Hi Con Verse,

I understand that jeremyzhou showed the routine to add to my code to restart the system. There are still two problem. 1, where does the routine get loaded to, i.e. what address do I pass to the Go command. 2, as written, the routine takes a parameter that can't be passed with the Go command.

Number 2 is relatively easy to solve, just change the routine to load R0 with the proper address.

Number 1 is more difficult, do I have to force the Linker to put the routine at a fixed address so that it's possible to have an address to give to the Go command to execute?

Greg

0 Kudos

1,874 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Greg Wilson-Lindberg,

Let me introduce the appropriate flow of jumping to the specific address via Go command.

1. Enter in the ISP mode firstly.

2. You should write a boot_jump function which be used to jump the specific address smoothly, and you also need to get the binary code after parse the function.

3. Write the binary code to RAM via the Write to RAM command, then the function will reside in the RAM after done.

4. Finally, using the Go command to execute the function, then complete the jump operation.

Hope this is clear.
Have a great day,
Ping

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

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Here is my function:

void boot_jump(void)

{

   __asm__("MOV R0, #0x0"); // load vector base address

   __asm__("LDR SP, [R0]"); // Load new stack pointer address

   __asm__("LDR PC, [R0, #4]"); // Load new program counter address

}

From your comment I am assuming that if I take the hex code for this function it is going to be position independent and I can put it anywhere in Ram and it will execute correctly?

0 Kudos

1,876 Views
garyaltenberg
Contributor II

Hi Greg,

Did you ever get this to work? If so how did you do it?

Thank you,

Gary

0 Kudos

1,876 Views
gregwilson-lind
Contributor II

Hi Gary,

What I'm doing is downloading the boot_jump() code to an address in ram and using the Go Command to jump to it. The Go command works when the processor is booted into the CAN ISP mode but doesn't when I use the Reinvoke command to enter CAN ISP mode, NXP Tech Support is still looking into that problem.

Greg

0 Kudos

1,876 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Greg Wilson-Lindberg,

Thanks for your reply.

Yes, the crucial step is writing the binary code of the boot_jump to the specific address in the RAM, then you can execute it correctly via the Go command.
Have a great day,
Ping

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

0 Kudos