cancel
Showing results for 
Search instead for 
Did you mean: 

Bootloader to Application Transition Not Fully working.

johnsotack9
Associate II
Posted on January 31, 2013 at 19:47

I have an application I build from Atollic True Studio that runs correctly stand alone on an STM32F407ZE processor. I am working to insert a boot loader that later branches to the application.  The boot loader runs fine on its own.  When branched to by the boot loader, the application apparently runs slowly and may be mising all interrupts from an external digital input  (or is just to slow to keep up).  My boot loader starts at the start of my prcessor's flash 0x0800000.  On reset Flash location 0x4 contains the reset vector also stored in the isr table at 0x08000004.  The boot loader uses the internal oscillator while my application uses an external osciallator  Ther version of the application that runs stand alone starts at 0x0800000 (ISR table location).  However, the version designed to coexist with the boot loader starts at Flash Bock 1 at 0x08004000 (Also ISR table location).  It builds and runs correctly when started from the debuger directory.  The problem occurs when branching to the application from the boot loader.

My boot loader, also an Atollic True Studio C/C++ application branches to the boot loader using an inline class method as follows:

__attribute__

( ( always_inline ) )

static

inline

void

BranchToApplication()

{

asm

volatile

(

''

movw

r3, #0x4000\n\t''

''

movt

r3, #0x800\n\t''

''

ldr

sp

, [r3, #0]\n\t''

''

movw

r3, #0x4004\n\t''

''

movt

r3, #0x800\n\t''

''

ldr

r3, [r3, #0]\n\t''

''

bx

r3''

);

It sets the stack pointer from the first location in the applications vector table, and then branches to the Rest_Handler address at the second location in the vector table.  My application uses a debug terminal which runs at the correct baud rate and works.

 

Is there a more effective way of branching to the application such that it will behave as though its Reset_Handler was called at power on?  Is there something I can do to initialize all non processor register and branch to my application's reset vector.

John
3 REPLIES 3
Posted on January 31, 2013 at 21:11

You could presumably use your debugger and step into the application from the boot loader.

You could branch into the application very early in the boot loader, perhaps from ResetHandler, and you could confirm if the boot loader is doing any setup that is objectionable.

Things to watch:

What SystemInit() is doing. Turning on clocks, switching clocks, with regard to what's currently running rather than assumed reset states.

That the vector table is setup correctly, and that SCB->VTOR is set to your new address.

Any interrupts set up by the boot loader need handlers in the application if they are left running, ie SysTick

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
johnsotack9
Associate II
Posted on January 31, 2013 at 21:42

The application partially works including the underlying RTOS.  I have implemented a debug terminal and can use my debug menu from the appliaton.  However, I notice a long delay between printing my boot text and getting to the first menu.  The init code within the application does appear to reset the clock registers before setting them.  It is code that came with my build rather than code I wrote.

void SystemInit(void)

{

  /* FPU settings ------------------------------------------------------------*/

  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

  #endif

  /* Reset the RCC clock configuration to the default reset state ------------*/

  /* Set HSION bit */

  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */

  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */

  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */

  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */

  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */

  RCC->CIR = 0x00000000;

#ifdef DATA_IN_ExtSRAM

  SystemInit_ExtMemCtl();

#endif /* DATA_IN_ExtSRAM */

         

  /* Configure the System clock source, PLL Multiplier and Divider factors,

     AHB/APBx prescalers and Flash settings ----------------------------------*/

  SetSysClock();

  /* Configure the Vector Table location add offset address ------------------*/

#ifdef VECT_TAB_SRAM

  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */

#else

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */

#endif

}

The RTOS and UsART comms would not work if interrupts were not operating.  I also have VECT_TAB_OFFSET set to 0x4000 and my start of flash set as follows in my ld file:

/* Specify the memory areas */

MEMORY

{

  FLASH (rx)      : ORIGIN = 0x08004000, LENGTH = 240K

johnsotack9
Associate II
Posted on February 01, 2013 at 16:55

If I branch to the application immediately without initializing registers it works.  Writing a branch to app magic number to ram and resetting should do the trick.  Thanks.

John