I've written a boot loader for the Atmel SAM4E device which is working to a point, it can receive new application code via SPI, erase flash and write to flash, but I don't understand how to execute the new application. I've learned the VTOR can be relocated, but I'm not sure how. (my application sits at address 0x00420000).I'm very new to writing code for ARM, so I'd appreciate any help.
Many thanks
Paul
Hi,
I tried this code ;
Here's the output of my boot loader
-- Boot Loader --
VTOR:0x00400000 <- I have a printf to show me the current VTOR value
BootLoader Starting....
BootVTORValue = 0xffffffff <- This is the value read from flash location 0x00420004, before receiving the code
waiting..... for 165 bytes <- this is my code waiting for data
PageNumber:511 <- This is the code showing it has recived 512 pages (each being 256 bytes, so 64K)
65536 Bytes Page Written to 00420000 <- This is showing
Wait For Flash Ready <- Pause whilst flash writes
NewBootVTORValue = 0x004220f9 <- This is the value read from flash location 0x00420004, after receiving the code
reboot <- This is sent by the bootloader just before jumping to the new code.
stack overflow 20015b68 Monitor <- this is what I got after trying your code.
At this point, the PC is wrong, it's showing - 0x0040660A
The SP is showing - 0x20014AC0
I just checked the code in flash;
:020000040042B8
:10000000A0450020F92042006920420069204200FA
Pulling out the first 32bit word in the VTOR gives me the SP; A0450020
Putting that the correct way round gives; 200045A0,
Stepping through the code, after this line has run - asm volatile ("ldr sp,[%0,#0]": "=r" (v) : "0" (v));
it does indeed show SP as 200045A0
However when the next line - ((start_fn *) *((uint32_t *) 0x00420004))();
Causes the stack overflow but the PC is showing as 0x0040660A, so is in the boot loader code rather than the application code.
Hello Paul,
I don't know the meaning of ":10000000" but it seems that the SP and PC initial values are respectively 0x200045A0 and 0x004220f9 from the code.What is the meaning of "when the next line - ((start_fn *) *((uint32_t *) 0x00420004))();"?I think the next step of the line would be 0x004220f9.Can you show us the dis-assembly code around 0x0040660A?
Best regards,Yasuhiko Koumoto.
Hello again Paul,
it is the Intel Hex, isn't it?I understand and it would be reasonable.However, it is strange "((start_fn *) *((uint32_t *) 0x00420004))()" causes a stack overflow.Did you set the stack pointer before execution the asm statement?Otherwise, you should add the "__attribute__((naked))" attribute to the bootloader function in order not to use stack.
I have found the problem
It would seem that on boot a number of things are 'assumed' as being in a certain state by the compiler.
If I disable the global interrupts, cpu_irq_disable() , before jumping, and then re-enable them, cpu_irq_enable() in the application, it works.
My next challenge is reading and writing a single value to a specific location in flash (say 0x0048FFFF) so I can detect if I should be self writing or jumping to the application.
I am afraid to change a single position of a flash would be impossible as the flash should be block erased before writing a new code.
If you want to do so, you can copy the whole data of the flash block to SRAM, changing a value on the SRAM and write back to the SRAM contents to the flash.
Best regards,
Yasuhiko Koumoto.