STM32 Tutorial - Bootloader That Can Update And Jump To Multiple Applications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys in today's video i would like to show you how i made my own stm32 bootloader for this board and basically this bootloader is capable of modifying and jumping to two different applications and it uses usb peripheral to update those applications so once you will understand how this all works you will be able to make your own bootloader on your own so those who don't know what a bootloader is it is basically an application that sits at the beginning of the memory of the flash memory and this application is capable of erasing other parts of the memory and putting their new data such as new application which is many times called a firmware so basically this application is supposed to be there forever and via this application you will be able to update your application or firmware for your own product basically this bootloader is basically an application that is supposed to be there forever and the client as he will buy for example your product or you he will be able to update his applications with new features bug fixes etc so as you can see this stm32 board has 64 kilobytes of flash memory in total so basically i have splitted this flash memory into three separate partitions and basically the first partition has 20 kilobytes for the bootloader and right after that there are two other partitions for two applications and each one of them has 22 kilobytes and later in this video i will explain you what you should modify and how you should set up your projects in order to have proper flash memory origin and proper size this is mainly for the vector table and for the linker so basically this stm32 board uses usb peripheral which is initialized as a virtual comport and it is used for the flash mode to upload new firmware to your to your flash memory and basically you know this boot one pin uh is used to select either jump mode or flash mode at the booting up or resetting the mcu and basically this boot one pin is simply an ordinary bb2 gpio input pin and to select which one application you would like to flash or to jump to you just need to use this simple switch that sets the pb 11 to logical one or zero and over here here you can see these 22 ohm resistors which are for the usb data plus and data minus and this 1.5 k resistor is used to enable and disable or connect or disconnect the usb peripheral from the computer so this way your computer knows when your usb device has connected or disconnected and as i explained just a few moments ago this simple switch is used for the bootloader to select your application one or application two and this middle pin isn't connected directly here but it is connected over here to pb11 and it is used to select the logical zero or logical one so that's simply all for this introduction and now i'm going to demonstrate these applications what they do so now i'm holding this reset button and uh after releasing this the bootloader is gonna read this boot one pin that says it is time for a jump and this switch tells the bootloader to jump to application one and after i release it the bootloader already jumped to application one and it just blinks that's the this application one and uh on this position we are still in the application one because the bootloader is already gone it jumped out of the bootloader to this application one and simply i'm using this switch to read this state and it is a part of this application one so this is the application one and i'm gonna keep this switch in this position and after resetting this microcontroller it's gonna jump to application two so now it's in application two and this led is on and it has one second delay after toggling this switch so this is a simple application too but the point is that uh this microcontroller is running uh currently application two and uh the bootloader was running only at the very beginning uh after the reset so basically after it jumps out of its boundaries it it runs a totally different application so this is basically the point of the bootloader of this example that it can jump to multiple different applications as many as you want so now i will switch this boot one pin to the flash mode and after releasing a recipient the led is gonna blink 10 times quite rapidly and afterwards it's gonna initialize as a virtual com port so now it has initialized as a virtual com port and i've also made this stm32 flasher application let me show you so this is a java application that is capable of erasing the flash memory and flashing new firmware so let me just select this bootloader and connect to it and now i can erase the flash memory so now it is erased and after i disconnect now from this i can close this and after i set this boot one pin to zero again to jump mode uh after i reset of this macro controller basically uh it's not gonna find any application and this led is gonna blink as sos signal so three short blinks three long and three short so i'm holding the reset so three short three long blinks and three short so it's signalizing that there is a problem in this case the application one is missing so in the next cut i'm going to show you how that you can flash there again a new application so i'm back again so basically i've switched this to the flash mode and we are still in this error mode and after i reset uh this microcontroller it's going to blink 10 times so now we are back initialized and i can run this application again and i can connect to this bootloader and now i can go to this file chooser and pick up this application one but for now i can show you what happens if you pick up a quite big file as you remember this uh memory has only 22 kilobytes of size so when you pick up a lot bigger files such as 68 kilobytes it's gonna show you this error message which says that this memory is really big like three times bigger than it should so this application is gonna quit so when i connect again i can pick up the correct file this application one and now i can flash this application and it was quite quick and it's done so now i can disconnect from this and close this application so this is how simply a user can update his own application so now i can switch back to this jump mode and reset this microcontroller and as you can see this led blinks as it was before and now it's going to blink faster so this is no the simple application one so let's start explaining how you can make your own bootloader basically you need to keep the origin of the flash as it is but to determine the size of your bootloader you need to write your code and have it almost finished and after you build your almost finished application you will be able to estimate the size of the flash memory it will take so in my case i ended up having 19.5 kilobytes of flash memory and one sector or one page of this stm32 flash memory has one kilobyte and your next application can start right after your bootloader your bootloaders last page so basically this bootloader takes 20 kilobytes of flash memory therefore 20 pages and on the 21st page your next application can start so therefore i've ended up having this 19.5 kilobytes of flash memory and i had to round it up to those 20 pages which is 20 kilobytes and it is 20 480 bytes and i've used this calculator to check the size of the memory it converts the kilobytes to two decimal values and basically therefore i knew that the next application can start with this 5000 hexadecimal offset and to find out how big your page size is is in your particular model you need to go for example to a reference manual where you can find it out they are quite long like over 1 1000 pages long but you will find basically everything there you need so when it comes to a bootloader project you need to modify basically more or less only this flash or this this linker called flash ld and you need to keep the origin but you need to lower the size according to your bootloader application size and it should be rounded up to your page so when it takes 19.5 kilobytes for example you need to round it up to 20 kilobytes and over here i have put there just a few definitions from the code just to get around so i've decided to define where the application 1 starts and application 2 starts and over here you have explained that you have this origin plus bootloader size it's the origin of the application one and application two starts as the origin of the flash memory plus bootloader size plus the allocated application one size which is 22 kilobytes so therefore i was able to define how much memory i would like to allocate for each flash memory partition and each page size for this on this stm32 board has one kilobyte so therefore i know how many pages i need to erase before i flash a new firmware there and here are just a few definitions this is for the jump it contains stack pointer and program counter value and basically once you set up uh this value like where to jump uh it's just uh need you just need to de-initialize everything and then you can use this uh assembly uh command to to jump to your new application but you need to properly de-initialize your microcontroller and to do it properly you just need to do it the opposite way as you initialized your microcontroller so basically when you first initialize the hole in it then system clock and then your gpios and other peripherals you you should do it the opposite way that's the safest way to do it because when you forget to de-initialize something for example pwm uh and you will jump to your next application the pwm will be still running or any peripheral that they will keep initialized so when you for example initialize the spi and you forget to de-initialize it or it's going to be still configured as it was in your bootloader so this is a really important thing to do so when it comes to this stm32 project i'm gonna explain it right now so let's start with this flash.ld linker file basically i kept the origin and set the file size to 20 kilobytes after i knew how much memory it's gonna take and over here i've defined a few structures for example for the bootloader mode jump mode or flash mode or to which application i would like to jump and the status of the memory whether it is unraised and erased erased unlocked or locked and i've also defined this application pointer sort of and over here here's the definition of the structure that can jump to your specific application which consists of stack pointer and program counter and that's basically it so when i uh when this application starts it just calls this bootloader init function and i've only included this bootloader.h file so for the main file i've just placed here this line and this line quite simple and uh when that bootloader init function is called it just sets the flash status to unerased i check whether the boot one pin is set or reset so when it is set uh it's for the flash mode and when it is reset it's for the jump mode and in the flash mode i basically blink the led 10 times and then i set up the usb enable pin that enables the virtual comport communication with the computer and i have therefore i am able to flash a new firmware to this microcontroller otherwise i turn the usb pin to zero which disables this usb communication and then i read the switch and decide whether to flash or jump to application 1 or application 2 so when the mode is set up to jump mode i just jump to application 1 or to application 2. and oh before that uh before the jump i read the first 10 values of the flash memory and if it is erased i i can detect it and i can decide to show the error blink led that blinks sos signal and if it is occupied or if there are any data or then i can jump to the function or to the new application so that's basically it when it comes to this bootloader init function but when this bootloader is initialized then i use this usb peripheral and i just try to receive some commands and this bootloader knows a few commands for example here is memory flash start that unlocks the memory and potentially erase it erases it and this flash finish locks the memory and in case it receives this flash abort it basically stops the flashing erases the memory and locks the memory so it's quite straightforward so this function waits for the commands to be received and when the received message has length of 4 bytes it assumes that these are data for the flashing so basically i just try to get those data and write them to flash memory or but only in case if the status of the memory is unlocked and in case uh you know the length of the message is different i just jump to this message handler which is down here in the bootloader c and i just uh check what kind of command it was so i can as i told you i can erase the memory then i send back the message the report that the flash memory was erased or i can flash i can start the flash mode that unlocks and erases the memory so here are all the functions uh up here or i can finish the flashing or abort and if oh there's some kind of problem or i just received the messages those commands in incorrect steps i just report back that that's an error so that's basically it when it comes to this erase memory i just try to unlock the flash unlock the option bytes oh then i check like which application was selected based on this application i just can set up the origin of the address and then based on the flashbang size or partition of the flash memory divided by the page size i know how many pages i should erase and then i erase the memory and then unlock the memory back and also lock the option bytes and then i just set flash tattoos to erased so that's basically it and when it comes to unlock and flash memory i just do the same i just unlock the flash memory unlock the option bytes then if the memory has not been erased i i should just erase it again and then i just keep the memory unlocked and if it was erased in previous step then i don't have to erase the memory because it was already erased and when it comes to lock the flash memory this is supposed to be called after flashing new firmware uh then i just call these two commands to lock the flash and now this function to lock the option bytes and when it comes to this abort i just call these two functions to to lock the flash and erase the memory so that's basically it and when i try to flash the memory now i should go back to this this function so when i receive the four bytes i suppose that those are for the flash memory and i just basically increment the address it's over here this flash offset so when i successfully write the word i just increase i just increment this offset by 4 bytes because so this is 32 bit micron microcontroller which means that i can receive four bytes at once and write them down so this means that uh before i flash this application i have to check you know which application is already selected therefore i know where i should write those data and afterwards i just verify by reading that those data if they were or correctly written or not so if everything was successfully written then i increment the the offset and then return back to this usb function so basically uh afterwards it was successfully written i just sent back this report that flashing was okay of that particular word which is 4 bytes so i need to unlock the memory write the new firmware and then log the memory so that's basically it it's not that complicated you can follow my readme file over here so that should explain how to achieve it you just need to know that you need to first unlock the memory it it should be erased and then you can write new data and lock the memory again so that should be that's all for this stm32 bootloader so when i move back now i can now start explaining how you can set up your application 1 and application 2 because this setup differs so let's move on to this application one okay so let's have a look at this application one basically over here i have changed the offset of this application one by 5 000 in a hexadecimal and i've also defined this flash size to be 22 kilobytes it is a size of this partition so basically for the application one which is written over here you just need to change the linker to have a specific origin offset and the specific length and when it comes to the c code you just need to go no and go to this system stm32 dot c and look for this vector table offset and you need to uncomment uh one definition this user vector table address and then you can set up your offset so let's go on and search this so when i go over here and press ctrl h i can go to this file search and search it and it found these results so basically this this line was commented originally i've uncommented it and then i was able to set up this offset to 5000 hexadecimal which is 20 kilobyte offset which is based on my bootloader size so you should start your next application as on next page uh as your bootloader was taking so when your bootloader takes for example 19.5 kilobytes uh therefore you should round it up to to your page size so to 20 kilobytes and then your application can start at 20 kilobytes so that's basically it and so this uh this program is quite simple as you can see i just toggle the led pin and i just read this switch and if it is in logical state 1 it waits short time and if it's in a logical state 0 it waits slightly longer so that's the difference between the short blinking and the fast blinking of the led so that's basically this so this is the short this is the long blinking and this is the quick blinking so this is this application one so it's not that complicated to make your own application with offset you just need to set up this vector table offset by uncommenting this line and setting up this offset and also by changing this one particular line in your linker file and i've left here this command which is the shortest manual how to set it up so that's basically it and the same works for this application too so it's quite similar i've also defined this new offset which is the offset of the bootloader and the next application so that's the new offset and the partition size is the same it's 22 kilobytes and you also like have to do the same exact exact step as i explained you just to look for this definition define vector table offset just pressing this ctrl h again searching it and so it's the same i just uncommented this line or set up the new vector table offset which should be the same as here so if you forget to set up this offset or if you mess something up your interrupts will get stuck so this is really important that you need to have now your vector table offset uh has to match uh with your linker because for example you know such as this whole delay or any interrupt caused by for example uart or spi peripheral or anything or will cause the crash of your application so your mcu will stop so that's a really important note here so when i reset this board i just jump to this application too so this is the led switching with one second delay so that's quite simple and that's basically all for this stm32 tutorial part and now i can move on to this stm32 flasher application basically this application contains only four classes this one main class is for the graphical user interface that defines the fixed size of this stage and displays the icon and disables the resize capability of this stage and also it initializes the comfort menu and the rest of the layout so this serial comport class tries to look for the available comport devices now it is spliced them and also it contains the button to connect and to disconnect to the virtual comport as well as these functions that contains listeners and in case this serial comport receives this error message for example it it calls this custom prompt which is also available in this main class and this class contains all the objects and variables and over here uh this app functions contains all the functions of this application basically over here i just set up all the buttons what they should do like what should happen after you click on for example on button file and what should happen afterwards then all the objects are set up like labels and so progress bars etc and i also have these other buttons to erase the memory like after clicking it sends this command and uh this uh this is file chooser that tries to filter all the files visible only down to binary files so that's quite simple and basically this timeline tries to update the graphical user into interface mainly for the progress bar as the flashing progresses so that's basically it and as you can see here are just a few more functions so this java application is quite simple and also when when a message is received and it is complete then basically this class calls this message handler function which is over here and uh if it receives uh this message that flash was erased it sets the buttons back to its original condition as they supposed to be also when the flash is unlocked it knows that it can start flashing uh the data basically or if it uh receives the message that the flash was okay like the flashing of of one word so this way i can increment uh the content of the file and i'll send it word by word into the mcu and this content of this file is basically uh this binary content which is defined as a byte array but it was opened after clicking this button file so by opening that file chooser which is basically this one i can show it to you after clicking this this button file which is this one it opens this dialog window and this file chooser window basically can filter all the binary files only and when you open one of them it does all these steps such as to recalculate how much memory does it take and all the content of the file uh is copied into this binary file content so oh therefore all the file is read and once and it is stored in this array and then when the microcontroller wants to get a new data uh this message handler sends a new data to it so that's basically it and that's all for today's tutorial which is available on my github so when you read this closely you should be able to make your own bootloader application as i mentioned at the very beginning of this tutorial you know if you will understand how this all works you can make your own application it know the new applications can be updated via wi-fi via bluetooth in any way from where you can get a new firmware binary file so it's up to you and so if you want to try out this application you can follow all these steps like how to properly flash a new firmware to your stm32 board after you export or generate your own binary file that matches the vector table so keep in mind that your vector table and your link linker file have to match otherwise any interrupt will cause the failure of the microcontroller so the program is going to be stuck somewhere so keep this in mind just try to understand it not to copy paste my code just try to learn from this and that's all so keep trying keep learning thanks for watching see you next time bye
Info
Channel: Viktor Vano
Views: 13,260
Rating: undefined out of 5
Keywords: STM32, Bootloader, Tutorial, FLASH, FLASH MEMORY, Code, Firmware, Update, Flasher
Id: S0s69xNE1dE
Channel Id: undefined
Length: 42min 56sec (2576 seconds)
Published: Sun Oct 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.