Topic : Dual boot on XL devices

Forum : ARM

Original Post
Post Information Post
October 6, 2011 - 9:15pm
Guest

Hi,

I'm having a lot of difficulty using the dual boot functionality on the XL devices (I'm using a STM32F103ZG).

This is my process:

- Write working code to the device using the default startup & script files
- Clear the word at 0x08080000 (the start of bank 2)
- Run- everything seems fine
- Use the rlink tools to write 0xF7 into the user byte (this should clear BFB2)
- Restart the processor. I would expect this to boot into system memory, check the word at bank 2 (0x0), check the word at bank 1 (the default top of stack address- 0x20018000), and then vector into the code in bank 1. It doesn't do this, it just sits there.

I have both boot0 and boot1 pins tied to ground through a 100k resistor. When I attempt to reprogram it gives me the error "Wrong boot mode detected: RAM mode" (until I clear the option bytes). I tried with the debugger attached as it jumped into system memory and I end up 'out of code' at 0x1FFFEDCC (which seems right, that's in system memory). If I leave it running it ends up around 0x1FFFEAE4.

What am I missing?
Thanks,
Ben

Replies
Post Information Post
+1
0
-1
October 7, 2011 - 9:20am
Raisonance Support Team

Hi,

Thank you for the report.

Please first make sure you are using the latest versions of the Ride7 and RKit-ARM software. The boot mode detection has been slightly improved in the latest version.

Then please read the memory back from the device at the end of your process (or at each step if you prefer) and check that it matches what you expect. For example in your second step, depending on how you do it, you might accidently erase what you have done in the first step.

If all this gives no result, then I will inquire deeper. Note that I'm not sure that system memory can be debugged at all. I'll need more time to check this.

Best Regards,

Vincent

+1
0
-1
October 7, 2011 - 10:53am
Guest

Hi Vincent,

Thanks for your quick response-

I have Ride version 7.34.11.0250 and Rkit version 1.34.11.0250 installed. I was careful to verify that the memory was correct and I tried a couple variations of my approach- for example I tried setting the option bytes through the IDE and also in code using the latest ST libraries and the code found in the dual boot example. When I cleared the word at 0x08080000 I simply unlocked, wrote and locked without any erase flash commands for the reasons you mentioned (no erase flash is necessary because I was setting the bits to 0 and erasing resets the bits to 1). I also tried with an erase bank 2, just for redundancy.

I'm at a loss for what the problem could be. Based on the datasheets I've found there seems to be only a few possible causes- illegal memory pointers at the bank base addresses or problems with the boot pins- but both boot pins are pulled down and I never have problems in normal operation (without the BFB2 bit reset), and the word at 0x08000000-0x08000003 is the top of stack address (I also tried a middle of stack address) just as it comes out of the default linker.

If you have even a simple Ride based example that runs on the 103ZG that would be really useful to me for debugging.

Thanks,
Ben

+1
0
-1
October 7, 2011 - 2:39pm
Raisonance Support Team

Hi,

I have checked the ST doc about the dual boot and made a few tests using RFlasher and I think I understand the main cause of your problems...

When the BFB2 bit is 0, the bootloader boots in a bank (2 or 1) only if the word at address 0 of this bank (initial SP) points to _a_valid_RAM_address_. However, the default value for the initial SP is 0x20018000, which is _outside_of_the_RAM_. Therefore in case you have 0 (or 0xFFFFFFFF) at address 0x08080000 and 0x20018000 at address 0, then the bootloader will not boot in any of the two banks.

So if your application is linked for bank 1 with an initial SP at (for example) 0x20010000, and the word at address 0x0808000 is 0, the aplpication will work regardless the state of the BFB2 bit.
But if the initial SP at address 0 is set to 0x20018000, then the application will start if BFB2 is 1 but not if it is 0.

All this is what I got from the doc, and I could confirm that in RFlasher using the following procedure, which I suggest you try exactly like this, just to be confirm the theory (you can replace the toggle by anything else that is visible on the board, as long as the application fits in bank1 without using bank2, and doesn't use too much stack):

1. Program a simple toggle application in bank1, SP=0x20010000, bank2 empty (full of FF), USER OB = 0xFF
2. Power cycle and check that the LEDs toggle
3. Write USER OB = 0xF7. read it back for checking
4. Power cycle and check that the LEDs toggle
5. Modify the initial SP to 0x20018000 in the application's image, set USER OB = 0xFF, reprogram everything (flash+OB)
6. Power cycle and check that the LEDs toggle
7. Write USER OB = 0xF7. read it back for checking
8. Power cycle and check that the LEDs DO NOT toggle

The simplest solution I see to this first problem is to initialize SP at 0x20017FFC instead of 0x20018000.
I checked here and it works.

Now I will check if there are also some problems for debugging when the BFB2 bit is 0 and the initial SP of bank1 is inside the RAM.

Best Regards,

Vincent

+1
0
-1
October 7, 2011 - 3:00pm
Raisonance Support Team

Hi,

I indeed observe some problems when debugging with BFB2 = 0, even if the initial SP points to a valid RAM address.

I will correct them for the next version of the RKit-ARM software, which is due very soon. (it was in pre-release validation since this morning, I'll just correct that and restart the validation)

Thank you for reporting the issues.

Best Regards,

Vincent

+1
0
-1
October 8, 2011 - 12:01am
Guest

Hi Vincent,

Fantastic- I thought I'd tried addresses just below 0x20018000 before for that exact reason, but I followed your steps exactly and it worked as it should so I must have made a mistake.

Thanks for your help. I would be eager to get my hands on the new RKit-ARM when you're in a position to do some user testing.

Also- I would love to see an alternate version of the linker file which links all addresses relative to 0x0000 0000 rather than 0x8000 0000 for use when working on dual boot applications. Just making this change doesn't seem to be enough b/c the debugger won't flash the hex correctly. For example, in our application we will be flashing the devices in the field so it's impossible to tell whether a given hex will be based in bank1 or bank2- therefore it's necessary that all addresses be based on 0x00000000 which is remapped to the appropriate bank by the processor. I've made a basic script which seems to work but I haven't had much experience writing linker scripts so I'm sure it's not the correct way.

Thanks again for your help!
Ben

+1
0
-1
October 8, 2011 - 2:20am
Guest

Hi,

To follow up on the linker script-

I wrote a linker script (uploaded here: http://benstabler.com/STM32F103_1024K_96K_FLASH_CUSTOM.ld) which works- only I discovered that the reset handler pointer (found right after the stack pointer in the vector table- in other words at 0x08000004-0x08000007) /must point/ into the 0x08000000 region (so a pointer of 0x08001234 would work but a pointer of 0x00001234 wouldn't work, even though those should both alias to the same thing).

So- if you want to use this script you need to modify the startup script to or the reset handler with 0x08000000 (I believe that should work- I tested by modifying the .hex file instead).

Vincent- does this make sense based on what you've seen? Can you test for me to confirm?

Do you think this applies to every entry in the vector table or just the reset handler entry? My tests suggest it's just the reset handler entry, but I'm not sure.

Also- you might note that this doesn't work in the debugger b/c the base is 0x00000000 but the breakpoints /do/ work- is this fixed in the new version of RKit-ARM?

Thanks again for your help,
Ben

+1
0
-1
October 8, 2011 - 6:13am
Guest

Actually- that was just a debugging artifact. Or-ing the reset handler pointer with 0x08000000 doesn't make it work. So I don't understand why that linker script doesn't work.

Ben

+1
0
-1
October 10, 2011 - 2:49pm
Raisonance Support Team

Hi,

I confirm that it seems that the reset vector must point to 0x08... when using the dual boot mode but I don't see any mention of that in the doc. (in normal boot mode I can place code at 0 and it executes fine at 0, but the same code does not excute if I clear BFB2)
I suggest you ask ST if/how what you want to do can be done. I'm not sure the device can be used as you are trying to. In the end you might have to make two versions of each application, for executing in one bank or the other. But maybe I missed something in the doc.

Note that you can use the "offset" option of the debugger for loading data at 0 in the file to address 0x08000000 in the flash. That works fine except for the breakpoints (as you mentioned) and C stepping (because that uses breakpoints). We will modify the software for allowing to give a different offset for the symbols and for the code. Then all should be fine. But that alone will not solve your problem, and it will take some time and force us to re-run all the tests, so it cannot be done for the coming release.

So in the meantime I suggest you debug your application like a normal application, at address 0x08000000. Then after it is validated you just need to re-link it at address 0 (just changing the Flash address in the linker script, not using "AT") And then you can re-validate it by using the "offset" option of Ride, which will work fine except for the breakpoints and C-stepping. But since you already validated the application, there should be no need for these features at this point. ;)

Best Regards,

Vincent

+1
0
-1
October 10, 2011 - 6:25pm
Guest

Vincent- if I just change the flash address in the linker script, will the Raisonance tools allow me to program to the device? My experience was that it would say 'programming' but not actually transfer any data, because it seems to only transfer data in the 0x080...0x081 range. Is that correct?

Thanks,
Ben

+1
0
-1
October 10, 2011 - 6:31pm
Raisonance Support Team

Using the 'offset' option will tell the programmer to add a fixed value to all addresses during loading... ;)

+1
0
-1
October 10, 2011 - 6:37pm
Guest

Ah, I see. Thanks!

When I hear back from ST I'll post my findings here so future debugging may be avoided...

Cheers,
Ben