I am upgrading AN4379 MSD bootloader from K60 to FRDM-KL25Z. Here is the code snippet.
void Switch_mode(void)
{
volatile uint_32 temp = 1; /* default the button is not pressed */
/* Get PC and SP of application region */
New_sp = ((uint_32_ptr)IMAGE_ADDR)[0];
New_pc = ((uint_32_ptr)IMAGE_ADDR)[1];
if(temp)
{
if((New_sp != 0xffffffff)&&(New_pc != 0xffffffff))
{
/* Run the application */
#if (!defined __MK_xxx_H__)
/* */
asm
{
move.w #0x2700,sr
move.l New_sp,a0
move.l New_pc,a1
move.l a0,a7
jmp (a1)
}
#elif defined(__CWCC__)
asm
{
ldr r4,=New_sp
ldr sp, [r4]
ldr r4,=New_pc
ldr r5, [r4]
blx r5
}
#elif defined(__IAR_SYSTEMS_ICC__)
#if defined (MCU_MKL25Z4)
asm("msr msp, New_sp");
asm("msr psp, New_sp");
asm("mov r5, New_pc");
asm("mov pc, r5");
#else
asm("mov32 r4,New_sp");
asm("ldr sp,[r4]");
asm("mov32 r4,New_pc");
asm("ldr r5, [r4]");
asm("blx r5");
#endif
#endif /* end (!defined __MK_xxx_H__) */
} /* EndIf */
}
}
But IAR reports my assembly is wrong.
Does anyone can recommend some assembly language covering Cortex-M0? Although we are working on high level language. Sometimes assembly programming is still very useful in highly optimized code and libraries.
Solved! Go to Solution.
Hi Kai,
Please kindly refer to the following attachment for details.
Hope that helps,
B.R
Kan
Hi Kai,
You may add the following assembly code in your project.
; AREA CortexMx, CODE, READONLY ; name
SECTION .noinit : CODE (2)
PUBLIC boot_app
;New_sp: r0
;New_pc: r1
boot_app:
;PUSH {LR}
msr msp,r0 ;//set SP
blx r1 ;//run!
POP {PC}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END
and modify your code like the following:
#elif defined(__IAR_SYSTEMS_ICC__)
#if defined (MCU_MKL25Z4)
boot_app(New_sp,New_pc);
#else
asm("mov32 r4,New_sp");
asm("ldr sp,[r4]");
asm("mov32 r4,New_pc");
asm("ldr r5, [r4]");
asm("blx r5");
#endif
Hope that helps,
B.R
Kan
Thank you. Kan.
Actually I have followed the another solution available from other bootloader project. Which uses R0/R1 as params' carriers.
#if defined (MCU_MKL25Z4)
JumpToUserApplication(New_sp,New_pc);
#else
...
static void JumpToUserApplication(LWord userSP, LWord userStartup)
{
// set up stack pointer
__asm("msr msp, r0");
__asm("msr psp, r0");
// Jump to PC (r1)
__asm("mov pc, r1");
}
In early 8051 age, and other highly optimized DSP application, assembly is a must. It seems even in ARM world assembly sometimes very important as well.
Do you know any resources introduce Cortex-M0/M0+/M3/M4 assembly language?
Hi, Kan Li
I have an issue related to this topic. The bootloader I developed Any update fro AN4379 MSD device bootloader? can download firmware correctly, which is verified by inspecting via memory window, it can jumps to user application. But the user application (FRDM-KL25ZDemo-blinky) doesn't work.
So either user application, or bootloader has some bugs.
I load re-directed user application in FRDM, runs from 0x8000. The demo works.
What's going on here? In principle, only three elements are important: SP/PC.
SP: Same before redirect vectors: 0x20002FF8
PC: redirected, from 0x0000 to 0x8000
Maybe I got some confusion here. Please give me some directions. I will compare the AN2295 bootloader with AN4379 as well as cross-check.
Hi Kai,
I am suspecting if the "JumpToUserApplication(New_sp,New_pc);" you are using has some problem. Would you please try my code instead to see if any difference would be made. Thanks for your patience!
Hope that helps,
B.R
Kan
Hi, Kan,
I have found the root cause. Maybe we can not call it as the root cause, since I have not traced down to register level.
In my bootloader, I init MCG before GPIO(push button+LED) , timer and UART and control transfering to user application, since I though MCG is critical for all the modules. And MCG is configured as USB device.
In my user application, there is another USB CDC application, so the MCG is configured as USB device as well.
If bootloader jumps to user application, then MCG has been configured twice. And for some reason, it returns as 0x01 from pll_init( ), as FEI ?
Then I swap the init order, I init GPIO at very beginning without MCG init and jumps to user application. It works now.
BTW, now I use your code. I found it is available from AN4370 USB DFU bootloader.
Now I prepare a document for updated AN4379 bootloader at https://community.freescale.com/docs/DOC-97782.
Thanks
I will spend my hours on them.
Kan.