cancel
Showing results for 
Search instead for 
Did you mean: 

After jumping to application address from bootloader successfully, application gets stuck somewhere

KShah.1
Associate II

I am working on STM32F412CGU.

I have an application which runs correctly from 0x08000000. (consists MPU, freeRTOS etc)

But need to verify that image so designed a bootloader that can jump to main application at 0x08008000 address.

Now the problem is after jumping to main application address, main application gets stuck.

I am not able to identify whats wrong. Am i missing something which need to be taken care of in order to run my application smoothly ?

Here is modified part of linker script of application:

/* Specify the memory areas */

MEMORY

{

FLASH_priv (rx)   : ORIGIN = 0x08008000, LENGTH = 16K

FLASH (rx)        : ORIGIN = 0x0800C000, LENGTH = 976K

RAM (xrw)         : ORIGIN = 0x20000000, LENGTH = 256K

}

-------------------------------------------------

Here is the bootloader main part:

------------------------------------------------

#define APPLICATION_START_ADDRESS  0x08008000U

typedef void (*pFunction)(void);

static void vNavigateToApp(void)

{

   if (((*(uint32_t*)APPLICATION_START_ADDRESS) & 0x2FFE0000U ) == 0x20000000U)

   {

       /* First, disable all IRQs */

       __disable_irq();

       /* Get the main application start address */

       uint32_t u32AppStartAddr = *(uint32_t *)(APPLICATION_START_ADDRESS + 4U);

       pFunction pfNavigate = (pFunction)u32AppStartAddr;

       /* Set the main stack pointer to to the application start address */

       __set_MSP((uint32_t) *((__IO uint32_t*)APPLICATION_START_ADDRESS));

       HAL_DeInit();

       // Now jump to the main application

       pfNavigate();

   }

}

int main()

{

HAL_Init();

SystemClock_Config();

vNavigateToApp();

while (1)

{

   /* USER CODE END WHILE */

   /* USER CODE BEGIN 3 */

 }

}

8 REPLIES 8

Stop in the debugger and determine where it is stuck.

Have Hard Fault Handler and Error Handler output some actionable data.

Make sure to enable interrupts on the other side, and turn off the specific ones you enabled on the loader.

Make sure SystemInit() sets the vector table address properly.

Have some familiarity with the MCU you're using.​

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
berendi
Principal

Here is modified part of linker script of application:

MEMORY
{
    FLASH_priv (rx)  : ORIGIN = 0x08008000, LENGTH = 16K
    FLASH (rx)    : ORIGIN = 0x0800C000, LENGTH = 976K
    RAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 256K
}

If these are the only modification in the linker script, then the vector table will end up at 0x0800C000, not at 0x08008000. Adjust your bootloader accordingly.

While debugging I found that,

At the time when application initializes, FreeRTOS kernel init is failing due to the error code -6 which indicate current context is interrupt context.

So I found the when I jump to the application, application is running in interrupt context.

What could be the reason for this and how to avoid app getting into interrupt context ?

In bootloader I have set APPLICATION_START_ADDRESS as 0x08008000 according to linker script I provided and application starts by using this.

But it somehow runs in interrupt context. See above reply.

According to the linker script you have provided nothing gets flashed at 0x08008000 (unless you have modified something else in the linker script as well). The bootloader starts whatever fragment of code remained there from your previous experiments.

Calling from interrupt context is problematic because all the priorities and preemption levels are managed by the MCU/NVIC, so you'd have to unwind all of that properly first.

Ideally you'd do from the main() loop, with the RTOS shutdown, and all interrupt generating sources torn down properly. Like changing drivers while stationary in a parking lot, not while doing 150 KPH down the autobahn..

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I have used __disable_irq() api before jumping to my application which sets priority mask register to prevents the activation of all exceptions with configurable priority. This makes jump successful.

But I am not able to init/start kernel due to this PRIMASK bit set.

I also tried using __set_PRIMASK(0) to clear this register just before FreeRTOS kernal init but it did not worked.

How do I clear this register properly to get the freeRtos running?

Piranha
Chief II

Another example of a consequences of bad design... For a better and simpler one read my post there:

https://community.st.com/s/question/0D50X0000AFpTmUSQV/using-nvicsystemreset-in-bootloaderapplication-jumps