This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Is there any example code available for a custom bootloader for the MSP432?
I am looking for the code that prepares the micro and then jumps to the main program (say, defined at 0x8000).
I assume you need to set the interrupt vector table location and jump to the new start location? How is this best achieved?
Hi Josh,
I have been working on a similar example code.
Josh Adler2 said:I assume you need to set the interrupt vector table location and jump to the new start location? How is this best achieved?
Yes that is correct and I do not have any problem sharing these projects, but before doing that, which IDE (CCS/IAR/KEIL) are you using??
Regards,
David
Thanks David.
I think I have it sorted, I have my cmd files with App1 at 0x0000 and App2 at 0x8000,
then in App1's CMD file:
--retain=interruptVectors --retain=flashMailbox MEMORY { FLASH_BOOT (RX) : origin = 0x00000000, length = 0x00008000 FLASH (RX) : origin = 0x00008000, length = 0x00038000 FLASH_OTP (RX) : origin = 0x00200000, length = 0x00004000 SRAM (RWX): origin = 0x20000000, length = 0x00010000 } /* The following command line options are set as part of the CCS project. */ /* If you are building using the command line, or for some reason want to */ /* define them here, you can uncomment and modify these lines as needed. */ /* If you are using CCS for building, it is probably better to make any such */ /* modifications in your CCS project and leave this file alone. */ /* */ /* --heap_size=0 */ /* --stack_size=512 */ /* --library=rtsv7M4_T_le_eabi.lib */ /* Section allocation in memory */ SECTIONS { .intvecs: > 0x00000000 .text : > FLASH_BOOT .const : > FLASH_BOOT .cinit : > FLASH_BOOT .pinit : > FLASH_BOOT .flashMailbox : > 0x00202000 .vtable : > 0x20000000 .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM (HIGH) //.stack : > SRAM (HIGH), fill = 0xCDCDCDCD }
And App1's code:
{
SCB->VTOR = 0x8000; // // Load the stack pointer from the application's vector table. // __asm(" ldr r1, [r0, #0]\n" " mov sp, r1\n"); // // Load the initial PC from the application's vector table and branch to // the application's entry point. // __asm(" ldr r0, [r0, #4]\n" " blx r0\n");
App2's CMD File
--retain=interruptVectors --retain=flashMailbox MEMORY { FLASH_BOOT (RX) : origin = 0x00000000, length = 0x00008000 FLASH (RX) : origin = 0x00008000, length = 0x00038000 FLASH_OTP (RX) : origin = 0x00200000, length = 0x00004000 SRAM (RWX): origin = 0x20000000, length = 0x00010000 } /* The following command line options are set as part of the CCS project. */ /* If you are building using the command line, or for some reason want to */ /* define them here, you can uncomment and modify these lines as needed. */ /* If you are using CCS for building, it is probably better to make any such */ /* modifications in your CCS project and leave this file alone. */ /* */ /* --heap_size=0 */ /* --stack_size=512 */ /* --library=rtsv7M4_T_le_eabi.lib */ /* Section allocation in memory */ SECTIONS { .intvecs: > 0x00008000 .text : > FLASH .const : > FLASH .cinit : > FLASH .pinit : > FLASH .flashMailbox : > 0x00202000 .vtable : > 0x20000000 .data : > SRAM .bss : > SRAM .sysmem : > SRAM .stack : > SRAM (HIGH) //.stack : > SRAM (HIGH), fill = 0xCDCDCDCD }
Anything missing? Seems to work as expected, just not sure about the loading of the VTOR register.
Regards,
Josh
Hi Josh,
That's exactly how I did it. The only difference is that for VTOR, I used the "interruptVectors" (msp432_startup_ccs.c) instead of the address. Something like this:
SCB->VTOR = (uint32_t)interruptVectors;
Hopefully this helps.
David
Hi David,
Won't that be the interruptVectors for the current application (bootloader) instead of the application you are calling (main code)?
/* Interrupt vector table. Note that the proper constructs must be placed on this to */ /* ensure that it ends up at physical address 0x0000.0000 or at the start of */ /* the program if located at a start address other than 0. */ #pragma RETAIN(interruptVectors) #pragma DATA_SECTION(interruptVectors, ".intvecs") void (* const interruptVectors[])(void) = { (void (*)(void))((uint32_t)&__STACK_END), /* The initial stack pointer */ resetISR, /* The reset handler */ ... ... defaultISR /* Reserved 63 */ };
Josh
Hi David,
That sounds sensible, but I do it in the bootloader in order to determine the reset vector address so the bootloader knows where to jump. How do you do that part without setting VTOR?
SCB->VTOR = 0x8000; // // Load the stack pointer from the application's vector table. // __asm(" ldr r1, [r0, #0]\n" " mov sp, r1\n"); // // Load the initial PC from the application's vector table and branch to // the application's entry point. // __asm(" ldr r0, [r0, #4]\n" " blx r0\n");
**Attention** This is a public forum