3
\$\begingroup\$

I am developing for the STM32F0 using Keil uVision.

I have a custom bootloader loaded running at address 0x08000000. I need the bootloader to jump to my main application which I flash at address 0x08003000. The ultimate goal is to allow remote updates of the main application. The bootloader code that jumps to the application is this:

__disable_irq();
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS+4);
Jump_To_Application = (pFunction) JumpAddress;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();

I am getting a hard fault in the Jump_To_Application() line, with "Cannot access memory" message given by Keil.

Within Keil, I set the IROM1 start address to be 0x08003000 in my main application's project configuration. I feel like the problem lies in some further settings within Keil. For example, should IROM2 be set to anything? Should anything be adjusted from defaults in the Keil configuration within the bootloader project?

Does anyone have any recommendations?

asked Jul 10, 2016 at 13:58
\$\endgroup\$
4
  • \$\begingroup\$ Do you have a valid application at the address 0x08003000? \$\endgroup\$ Commented Jul 10, 2016 at 14:09
  • \$\begingroup\$ Can you add the relevant parts of your linker scripts (bootloader and application). \$\endgroup\$ Commented Jul 10, 2016 at 17:06
  • \$\begingroup\$ Batuu - I am using STLink to flash the application at 0x08003000. \$\endgroup\$ Commented Jul 11, 2016 at 14:42
  • \$\begingroup\$ rfkortekaas - I am assuming Keil produces based on the GUI configuration. I don't actually configure any scripts manually. Which files do you need to see? \$\endgroup\$ Commented Jul 11, 2016 at 14:45

2 Answers 2

1
\$\begingroup\$

I had the same problem: I solved it with commented this lines:

__disable_irq();
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);

Some advice for anyone writing a bootloader for first time:

Turn your code into small sections:

  1. In the first write a simple blinky code without any interrupt.
  2. use of sector erase ability and and write your put your bootloader and application code together in flash. Now you just,must try to jump from bootloader in application code. If it works, this means your jumping is correct.
  3. Now try receive your application code with USART (or with any other peripheral) and write in flash. It must work, if not, it means write it flash is wrong (open hex code file and compare flash data,flash address and other thing with hex file) (attention to little_endian writing)
  4. Now write a blinky code with timer and interrupt. It must work, if not, it mean is mistake is in jumping vector table
Mahendra Gunawardena
1,7661 gold badge14 silver badges18 bronze badges
answered Oct 26, 2019 at 21:18
\$\endgroup\$
0
\$\begingroup\$

You need to reconfigure the vector table offset. The offset being your app's starting address.

Your bootloader code should look like this:

__disable_irq();
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS+4);
Jump_To_Application = (pFunction) JumpAddress;
SCB->VTOR = APPLICATION_ADDRESS;
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
Jump_To_Application();

And if you have used STM32CubeMX to generate your code, you need to add the same line of code at the beginning of your app's main():

 SCB->VTOR = APPLICATION_ADDRESS;

Because of the system init resetting the vector table offset, The offset has to be reconfigured pointing to the start address of your app.

answered Jan 22, 2021 at 15:41
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.