Hello, I am trying to make an in house bootloader for a home project.
I made a program that just blinks an LED on and off every 500ms verified it works had keil generate the hex file transferred that file over to my pi where I have a script that sends it out to my NRF52 (M4) line by line and waits for an acknowledgement telling it that the CRC was valid and data was written correctly.
I have written all the data from the hex file to its corresponding area in flash starting at 0x4000 and all looks well in the memory window. I receive the second to last line with a data type of 5 (start linear address). From my understanding this is where I jump to to start my new application. I take that address and add my bootloader offset of 0x4000 so it corresponds with the rest of the flash that I wrote. The problem is that it just jumps off into no mans land. I have no idea why. r0 holds the address I want and expect and I can see my instruction set at location 0x4519;
I have tried this code from keil with no success http://www.keil.com/support/docs/3913.htm
Here is the code I am running. I receive this line from telling me where to jump. :0400000500000519D9 I interpret this as jump to location 0x0519... my offset of 0x4000 so I jump to 0x4519.
I am also reading the first and last line of the hex file but throwing it away first line = :020000040000FA last line = :0000001FF
__asm void binexec(uint32_t *address) { bx r0 }
__asm void binexec(uint32_t *address) { mov r1, r0 ldr r0, [r1, #4] ldr sp, [r1] bx r0 }
(I have tried both of these binexec files neither have worked)
void BootJump(uint32_t *Address) {
int i;
//binexec(Address); // -- Disable interrupts // Disable IRQ __disable_irq(); // Disable IRQs for (i = 0; i < 8; i ++) NVIC->ICER[i] = 0xFFFFFFFF; // Clear pending IRQs for (i = 0; i < 8; i ++) NVIC->ICPR[i] = 0xFFFFFFFF; // -- Modify vector table location // Barriars __DSB(); __ISB();
// Change the vector table SCB->VTOR = (( uint32_t )Address & SCB_VTOR_TBLOFF_Msk);
//__set_MSP( Address[ 0 ] ) ; // Barriars __DSB(); __ISB();
//( ( void ( * )( void ) )Address[ 1 ] )( ) ; // -- Enable interrupts //__enable_irq(); // -- Execute application binexec(Address);
}
Thank you,
Eric Micallef
Sounds more like you are building the code at the wrong base address. Go into the target settings and advance the IROM base to 0x4000 so the code is linked at the right location.