 So now you'll know where to find all the information to get the device up and running. So this section we're now actually going to have a look at what happens when we start the device. So the goal of this section is to understand what happens from when you release the reset line when your power has hit a suitable level for the microcontroller to operate all the way up to the first line of main.c. So the first line of your application code. So we're now going to cover what goes on from that releasing of the reset line up to the point of executing your first line of application code. So these are the seven steps that actually have to happen before we start executing any code that you have written. So we have the hardware configuration loading. So this takes the information from the option bytes to configure the microcontroller in a particular way. Then we define where we're going to start executing code from. So this is coming from the boot pins. Once we've know where our code is going to execute from, then we have to initialize our stack pointer. After that, we then start executing some code. So we then call the reset vector. So that we're going to actually jump to a certain area of code now to start running some configuration. Then we run the system initialization. So this is ARM standard code. So this is the CMSIS section of some code which puts certain things into known states. So where the rest of the interrupt vectors are located, the clocks, etc. Then we do what's normally a background task. So this is the memory environment setup. So this is loading the variables that you've declared in your software into the actual RAM and allocating the RAM and clearing the RAM. And then finally, we will jump to the main routine where we can actually go and execute your code. The hardware configuration loading is where we take configuration information from the option bytes and load them into hardware registers. So this is where we take the memory protection to make sure the device is accessible. We look at where the watchdogs have been initialized. Then we have a look to see what the reset voltage level is configured as and other features like what happens when we enter low power modes. So these are all affecting the hardware that are completely independent of what goes on in the software. So these are all just hardware parameters that have to be set up before we actually start executing any software. Key one in this one is the memory protection. So this will decide if when we send commands in, so when we send that sending software commands into the device, the hardware will know to say, no, the memory is protected, or yes, we can access programming or reading of the memory array at this time. So once all these hardware configurations have been loaded, then we move to where we're going to start executing code from. So as well as the physical boot pin, which we have on the device, there is also one option bytes as well. And this will define which of those three different memory areas we will go and execute code from. So we have the option of main flash, the RAM, or the system memory which contains the bootloaders that are pre-programmed inside the device in our factory. So one of these three areas will get allocated to address code 0x0000, which is the default execution place for our microcontrollers. And then at that point we can then start executing some code from address 0x0000. Once we've allocated the memory, then the vector table is loaded into this address, which is at 0x0000. And this contains various pieces of information that we need now to get the device up and running. The most important variable is the first element of this vector table, and that is the initial stack pointer value. So this is a very important item that we need to load into a specific register. So stack pointer is loaded at address 0x0000. And in hardware this is automatically transferred into one of the core registers within the ARM core itself. So it goes to register number 13. And this configures where our stack pointer value is going to sit in RAM. So it's going to be a RAM location for where we're going to send information when we enter the stack, when we load information onto the stack. Once we've initialized the stack pointer, then the next word we pull out of the memory array is the reset vector. The reset vector is now where we're going to actually do some execution of code. So we're now going to run a line of code at this point and jump to certain pieces of information. So here's the startup file. So this is the kyle startup file. This will be different for each of the IDEs that are available on the market. So our reset handler is going to execute some assembly instructions now. And we're going to load our procedure for what we do in our reset handler. So once we've jumped to our reset handler, the first line of code we are going to do is we are going to load a register. Load register R0 with the location of our system initialization. The system initialization is the first section of code we're actually going to execute. And this is our CMSIS startup information. So this is the definition of the clocks. So we're going to put the clocks into a known configuration. We are going to remap the vector table to whichever area of memory we need it to do. And we are going to make sure that the hardware configuration has been completed before we start executing any more code on the device. So this is all CMSIS compliance standard software. It's been defined by ARM themselves. And this has to happen before we actually initialize the rest of the microcontroller. So once we've finished the system initialization, then we will jump to a procedure called underscore underscore main. So this is not your main routine. This is another piece of software code which is actually going to configure the memory. So this is where we now load the variables that you've defined inside your software into the RAM. So we have to initialize the RAM first. We have to reset the RAM to known conditions. So normally it resets it to zero. And this is where we will then load in all those variables and allocate them inside the RAM itself. So normally this is a hidden routine if you're using IAR and Kail. If you're using GCC tool change, you can normally see this routine. But IAR and Kail will hide it unless you're doing the debugging at assembly level. So you can actually then see what this routine is doing and the copying of these variables from the flash into the RAM and the initialization elements that go on to clear the rest of the RAM memory that's available for this device. So once we've completed our underscore underscore main, the MCU will then automatically jump off into your application code. So it'll go off and link into normal main.c. And then if you're in the debug environment, your software will then usually stop at the first line of main.c. The first line in your main void main array. And then you can then start running your code from that particular point. So these are the various steps that have to go through before you actually start executing any of your code. Step numbers one, two and three are all happening in hardware. So there are actually no software code involved in any of those. Four through to seven is all when we've started executing some form of software on the actual STM32 device itself. So hopefully now you've got an understanding of what goes on in the background before you actually start running any code. And you can now understand what these steps are, why they're important and why you need to do them for your microcontroller configuration.