cancel
Showing results for 
Search instead for 
Did you mean: 

Bootloader Issues

lee_trueman
Associate II
Posted on January 21, 2013 at 10:50

having difficulty getting a custom bootloader working. Basically this is a MSD device bootloader, using USB MSD and SDIO Sdcard drivers and Chan FATFS. Note MSD only runs if there is not a valid binary file on disk.

Bootloader is compiled with normal compiler and linker settings its size is 90K.

i.e.

VEC_TAB_OFFSET 0x0

FLASH (rw) : ORIGIN = 0x08000000, LENGTH = 512K

Applications flashed by the bootloader use the following and are around 180K

i.e

VEC_TAB_OFFSET 0x20000

FLASH (rw) : ORIGIN = 0x08020000, LENGTH = 384K

What we are seeing is that a small application that just flashes a LED in a C main while loop works fine, but when we try our own application it fails to run. We know the application is working fine as can build it to run standalone without bootloader and it works fine.

Thus this seems like it is a issue with the core state when a larger application is launched, possibly interrupts too ?

13 REPLIES 13
Posted on January 21, 2013 at 13:32

Like messing with the clocks and PLL a second time in SystemInit()?

The code assumes reset conditions, ie a processor running off HSI, rather than being written to check what clock the processor is currently running from before turning it off, or changing it.

Use a debugger, and step in to it.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
lee_trueman
Associate II
Posted on January 21, 2013 at 15:34

Hi Clive,

is it safe to assume then that the CLK and other parts remain the same configuration state across the transistion to the application ?

KR 

Posted on January 21, 2013 at 15:48

is it safe to assume then that the CLK and other parts remain the same configuration state across the transistion to the application ?

 

Well the peripherals and clocks will stay the same unless you reprogram them. If you have the PLL up to full speed there is really no value to bringing it up again. The main thing you need to do is change VTOR to reflect the new vector base.

All interrupts will also continue, so unless your application is immediately able to handle them the boot loader should probably turn off things it doesn't need once it's done.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
lee_trueman
Associate II
Posted on January 21, 2013 at 16:07

ok so in the application i've remove all the clock setup code from SystemInit() all it does now is remap the vector table to SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; Where VECT_TAB_OFFSET 0x20000.

In the bootloader i also call __disable_irq(); prior to calling the Jump_To_Application();

Still same nothing........ 

You said step into the application ? how can i do this, the application is complied to binary file, so i dont believe there will be any symbolic debug info in there ?

Posted on January 21, 2013 at 16:36

You said step into the application ? how can i do this, the application is complied to binary file, so i dont believe there will be any symbolic debug info in there ?

 

The debugger doesn't need any symbolic information. The failure is likely to occur prior to getting to main(), unless you can toggle a GPIO/LED to indicate otherwise. If you can get that far, you should be able to bring a USART up and spit out telemetry.

You should be able to identify gross failures by following the disassembly view, and having a grasp of the code flow, and routines called. Generate listing files if this helps, or review the .MAP file.

In Keil there are a couple of ways of doing this. You can write your application code into memory, then load up the bootloader and run that in the debugger, break point on the transition code and step into the application code. In this case it's going to be the start up code which is typically assembler anyway, read along in the listing.

The other tack is to write the bootloader into memory, then load up the application in the debugger. Select that it DOESN'T ''run to main'', and place break point(s) in the ResetHandler code in startup_stm32fxxx.s

If you disable interrupts make sure you re-enable them. I'm more for deinitializing hardware and interrupt sources rather than blanket disabling the interrupts on the CPU. That's a bit of a cop-out, and suggests you don't have a clear understanding of what the boot loader initialized, and the application really shouldn't have to deal with unknown dependencies the boot loader may have left hanging.

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

program is stepping into application ok, traced it down to this 

static void prvPortStartFirstTask( void )

{

__asm volatile(

'' ldr r0, =0xE000ED08 \n'' /* Use the NVIC offset register to locate the stack. */

'' ldr r0, [r0] \n''

'' ldr r0, [r0] \n''

'' msr msp, r0 \n'' /* Set the msp back to the start of the stack. */

'' cpsie i \n'' /* Globally enable interrupts. */

'' svc 0 \n'' /* System call to start first task. */

'' nop \n''

);

}

this is the function to start the first task in freertos (port.c), after this it hardfaults. 

Posted on January 21, 2013 at 21:08

So are you running FreeRTOS in the boot loader?

Not sure you can change the Main/System stack pointer from Process/User space.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
lee_trueman
Associate II
Posted on January 22, 2013 at 11:05

Hi Clive,

no, freertos is use in the application not the bootloader. So bootloader jumps to the application ok, C main is called, and then the application proceeds to start the freertos tasks. I can step through with the debugger upto the point this line code is called.

static void prvPortStartFirstTask( void )

{

__asm volatile(

'' ldr r0, =0xE000ED08 

\n'' /* Use the NVIC offset register to locate the stack. */

'' ldr r0, [r0] 

\n''

'' ldr r0, [r0] 

\n''

'' msr msp, r0

\n'' /* Set the msp back to the start of the stack. */

'' cpsie i

\n'' /* Globally enable interrupts. */

'' svc 0

\n'' /* System call to start first task. */

'' nop

\n''

);

}

The assembler SVC 0 instruction when executed casues a HardFault Handler.

frankmeyer9
Associate II
Posted on January 22, 2013 at 11:37

The assembler SVC 0 instruction when executed casues a HardFault Handler.

Because you probably forgot to provide a SVC handler routine.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/ar01s02s07.html