cancel
Showing results for 
Search instead for 
Did you mean: 

custom bootloader and peripherals in application

Posted on October 06, 2012 at 03:03

hello,

I am using STM32F107 with custom bootloader.

Quite a few peripherals are initialized and used in a booloader.

At some seminar (don't remember which one) I asked about reinitializing peripherals

after the jump to application and got an answer that peripherals settings are kept intact

during the jump.

So now I only relocate a vector table in the application.

Seems like some peripherals are ok (spi and i2c are working fine, for example),

but some seem not behaving good.

For example, until I reinitialized the timer, delays were much longer than asked for.

Now I have a strange behavior in the application I can't explain yet.

When I run it in a debugger (everything is initialized), it works fine.

But in real life, when it goes through the bootloader and some staff probably

is not reinitialized in application, I see problems.

Unfortunately, I can't debug bootloader and application together (I am using Keil and

they don't know how to do it).

Are there any ideas about peripherals behavior in application after the jump from a bootloader ?

Also maybe someone can advice me how to debug a bootloader together with application.

Thank you,

Gennady     
6 REPLIES 6
Posted on October 08, 2012 at 03:58

My experience in Keil is that you can debug the application while the boot loader is present and functioning. Basically, if Keil is writing and erasing the application area when the debugger starts you can still ''run to main'', and the debugger will stop at the application's main() routine.

You should be able to step through the boot loader in the disassembly window.

Conversely, if you have the boot loader project loaded you should be able to walk entirely through it in the source window.

The key thing is to make sure Keil is not set to erase the whole device, and only write to the section of flash either the boot loader, or application exist in, and that the memory areas are correctly defined for each.

The Keil debugger is also capable of debugging blindly into code it has no source for, but this requires you are comfortable in the disassembler view. Step in, over, and out should all function.

If peripherals get set to the wrong speeds, I'd be looking at the HSE_VALUE settings in both projects. On the vector table front, you should be able to relocate that to any 512 byte boundary, but any interrupt you have functioning needs to be serviced, otherwise you'll loop continuously.

If things are still problematic, I would suggest adding some diagnostics and telemetry via the serial port, and dumping peripheral and core settings between the functional and non-functional states.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 09, 2012 at 04:07

Thank you Clive,

I will try to debug an application with a bootloader.

In worst case scenario I am going to make a system state snapshot, send it over tcp and compare with a system state in bootloader.

By the way i have an interesting observation from one of my previous projects with a bootloader.

At that time I didn't know anything about micro behavior after the jump to  an application, so I completely reinitialized system at application start.

One of the problems I've noticed is that I could update an application from a bootloader, but couldn't program a bootloader from an application.

I've made sure that no memory is protected, talked to FAEs, nothing helped.

Even in debug mode (application only) bootloader couldn't be reprogrammed.

Then I've noticed that I am using different startup files in a bootloader and application.

Application was written later and I used a startup file from later software version.

Looking through files I've found that the new software version put a call to System_init() to a startup file. And I was using a System_init() call from a main file.

When i removed a call from main, I was able to program a bootloader from application in a debug mode. But I still couldn't do it when application ran after a bootloader.

Then I realized that reinitializing a system in application still creates double call to a System_init(). Removing System_init() call in application solved the problem.

I still don't know the reason, but double System_init() call somehow prevents flash memory operation.  

Maybe this experience will help someone.

 

charlieincanada69
Associate II
Posted on October 09, 2012 at 21:31

I'm also having some bootloader issues and would be grateful for advice.

IAR 6.4, STM32F103, following the bootloader example from

http://www.iar.com/Global/Resources/Developers_Toolbox/Building_and_debugging/Constructing a bootloader STM32F207ZG-SK.pdf

I notice that some variables are not correct. They are set on boot and (for the moment) do not change. I have separated the flash for bootloader and application. Do I need to perform a similar thing with RAM/stack?

Thanks in advance.

Posted on October 10, 2012 at 01:26

Do I need to perform a similar thing with RAM/stack?

Generally no, as both are independent entities, and when the boot loader calls/jumps into the application there is no expectation it will return. One area that might complicate this is if you want to pass some parameters or configuration data, in which cause you might want to agree on a specific area, or mechanism to achieve that.

 

The issue with System_Init() is that it assumes specific reset conditions and clock selections, ie running from HSI, and is not sufficiently aware or careful when changing the PLL, or the source the core is using. A little more defensive coding, or awareness, would fix that.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
charlieincanada69
Associate II
Posted on October 10, 2012 at 22:39

Interesting - thanks Clive.

I am providing a bootloader alongside a facility to remotely update the firmware with no local user interaction. This is simple enough as I have more than enough flash in the STM32F103xE for two complete firmware images.

I have to configure the bootloader to ''boot'' the image I want (usually after uploading a new image). It has a try count so that if it fails 3 times it will revert to the previous image.

Obviously this process requires some shared information between the bootloader and the application (which firmware to boot, how many tries, the currently booted firmware etc). What would be your suggestion in managing that data exchange between bootloader and application? I am thinking of your previous comments about RAM/stack.

Thanks,

Charlie

Posted on October 10, 2012 at 23:01

Keeping track of counts is hard, detecting if something crashes after you jump to it is harder.

To know if some image is newer a simple sequence number in firmware releases, which you could park at the end of the vector table, or within it.

To know if you have a complete and valid image you could use a checksum or CRC across the entire image, say at the end of a 48KB code space (0x08004000 .. 0x0800FFFF), suitably filled if the current code doesn't use the whole space.

You could carve some space in RAM to place configuration structures.

struct foo *bar = (struct foo *)0x20004F00; // Assign some hard address at end-of-ram

Other methods would be to call with a couple of parameters, in the ARM ABI four parameters pass in registers R0..R3, not on the stack, so would be safe for constants or bit vectors.

You can also code things in assembler, and do work early in the boot/app startup prior to the C runtime code, and calling main()

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/STM32 Internal Bootloader&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=3078]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex%5Fmx%5Fstm32%2FSTM32%20Internal%20Bootloader&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=3078
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..