2016-02-23 09:15 AM
I've recently delved into this subject because I need to design a firmware upgrade mechanism on the STM32L4xx. The documentation is pretty much useless, as it is not only incomplete, but contradictory too. I'm guessing the guy/gal who wrote that section of the Reference Manual wasn't sure how it worked either. The only prose description is the following passage from section 2.6:
When booting from the main Flash memory, the application software can either boot from
bank
1 or from bank 2. By default, boot from bank 1 is selected. To select boot from Flash memory bank 2, set the BFB2 bit in the user option bytes. When this bit is set and the boot pins are in the boot from main Flash memory configuration, the device boots from system memory, and the boot loader jumps to execute the user application programmed in Flash memory bank 2. For further details, please refer to AN2606. The string ''BFB2'' does not appear in AN2606. There is a ''dual bank boot'' flow chart (figure 55), but it seems to indicate that the decision to boot from bank 1 or bank 2 depends on whether ''the value of first address of bank 1/2 is within internal SRAM address''. I must be missing something fundamental, as I don't see what any of this has to do with SRAM... I know this topic has come up before, but I am still not clear on what, exactly, the BFB2 bit does: 1) Does it select which bank to boot from, as the ref manual seems to imply in one place, or does it merely put the system in a mode where you can select the bank using some other mechanism, as AN2606 (and the register description itself) implies? And if the latter, how do you choose the bank to boot from? 2) When booting from bank 2, is flash memory actually remapped so that bank 2 appears at the bank 1 address and bank 1 appears at the bank 2 address? Or does the bootloader merely jump into bank 2 instead bank 1? In other words, must I build relocatable code and set VTOR, or not? I find nothing in the ST docs to suggest a hardware-level remapping, but a previous comment by clive suggested it. It would be nice to clear this up once and for all, since ST don't appear to be fixing their documentation. (Search hits in this forum were from 2013 and 2014.)2016-02-23 11:37 AM
Can't say I've invested any resources in the L4 family.
For the Dual Bank F4, the System Loader, BFB mode, checks to see if the first vector points to SRAM, it does so to make sure the Stack Pointer (SP) has some validity, and isn't junk or just erased. You want the SP in SRAM otherwise bad things will happen. The Banks get flipped. So either firmware you expect to run using the System Loader needs to be built for 0x08000000 regardless of where you park it. The same memory bank you have mapped at 0x08000000 will also shadow at 0x00000000, and the other bank will be at 0x08100000. This allows for the symmetrical use of the memories, ie the same firmware image, or versions thereof, can be placed in either bank and function. You can write your own loaders, in say the first 16KB sector, and have it do anything you want. Code can be placed and executed at 0x081000002016-02-24 09:02 AM
Thanks Clive,
I finally discovered the FB_MODE bit in SYSCFG. Presumably that bit is toggled by the rom bootloader based on its reading of BFB2 and sanity checking the initial SP. This is starting to make sense. Gotta love these undocumented features...2016-04-08 10:40 AM
Hi,
to sum this up: Assumed I have a valid firmware in the first bank and in the second bank (both linked with a flash starting address of the first bank [0x08000000]):To configure the device to execute from the first bank, we simply disable dual-bank boot, by setting BFB2 to 0. To boot from the second bank, we enable the bootloader by enabling dual-boot by setting BFB2 to 1 and the internal bootloader will start the firmware from the second bank? And the internal bootloader will map the second bank to address of the first bank and visa a verse? Did I got this right?TIA,Torsten2016-04-08 12:03 PM
Yes, that would seem a valid interpretation
It flips the flash banks in memory, but from the Flash Controller's perspective they are still bank 1 and 2, so you have to factor that in when writing new firmware to the appropriate bank.2016-08-03 08:15 AM
I've been ''tracking'' several answers by @clive1 where he advocates for placing a custom bootloader on the first 16 kb sector, rather than using the BFB2 bit and bank swapping. I have two questions on the matter:
1) AN4701 and other documents state that access to the main flash memory is denied with RDP level 1 or 2 if the boot took place from the system bootloader; then the explanation of how BFB2 works (e.g. from RM 0090) says that if the BFB2 bit ''is set and the boot pins are in the boot from main Flash memory configuration, the device boots from system memory, and the boot loader jumps to execute the user application programmed in Flash memory bank 2''. Then the question would be: if I boot from bank2 because of the BFB2 bit (through the system bootloader?), would the firmware running there be able to write on the other bank if RDP is set to level 1 or 2?2) if I were to write a custom bootloader to handle firmware updates, I cannot really ping-pong banks with every update, could I? (e.g. booting version 1 from bank1, version 2 would be saved to bank 2, then booting version 2 from bank 2, version 3 would be saved on bank1, etc.)? Because without the bank-flipping provided internally, the code needs to be compiled specifically for the bank address, right? Is this assessment correct, or am I missing something?2016-08-03 09:16 AM
2) Code that you are running can do all manner of things, the ability to swap the banks is a register you can write. You'd want to compile the code for the address it is natively going to run at, but this doesn't preclude you from parking it somewhere else, and then swap it later. You don't need the System Loader to do this, but you do have to manage your update process.
I am an advocate for implementing loaders that do what you want them too, in the order you want. The ROM based loader provides you with some options, but it is clearly fixed and inflexible.2016-08-04 02:55 AM
1) Works for me on RDP Level 1. My software can program flash of other bank from both banks. I use no own bootloader. I guess RDP Level 2 will not work: ''Booting from RAM or system memory bootloader is not allowed''. The system bootloader is needed to handle bit FB_Mode in the SYSCFG memory remap register.
2017-02-27 12:48 PM
Actually, your BFB2 value is 'backwards'. I know the docs say 'set BFB2' to enable the auto-sense of BANK2, but BFB2 defaults to = 1, which is only boot BANK1, ignore BANK2. You set BFB2 to 0 (okay, odd word choice :-]), then then per the docs it does the check of first word in vector table for valid SRAM stack offset.
2017-02-27 02:16 PM
Actually to my actually, I might be wrong ... seems some MCU have a BFB2, which as you say is 1=enabled/0=disabled, and others (like my L15) has a nBFB2, which 1=disabled/0=enabled!