 In the morning we started with the cube monitor and we created the example working from the internal flash. And our goal for this afternoon will be to move this example, which we named the hands-on number two to the OctoSPI that this hands-on will be executed from the OctoSPI. And to protect this code, which is normally readable from OctoSPI, we will use the on-the-fly decryption and also we will encrypt this hands-on number two that nobody will be able to read it without key. Then plan for this hands-on. And for this, we will use the OctoSPI one, which is directly connected on our board. And it's possible to see or configure this memory that way that it will be visible inside the cortex, memory space or at address 90 million. Then if we're referring to the 90 million, in our case today it will be OctoSPI one. There is also OctoSPI two, which is on the other 70 million and I'm missing here one zero. And this is not currently used. I think we're using it for SRAM or SDRAM, which is also connected there. But in our case, it's no OctoSPI. Then this is the mystery behind the 90 millions. To be able to run the application, we can do two things. One is to modify the hands-on number two to initialize the OctoSPI and then modify the linker a little bit heavily. Or we do the separate thing and we will create small application, which we can call bootloader. And the job of this application will be to initialize for us the OctoSPI, initialize the on-the-fly decryption eventually, and then just jump into the hands-on number two, which is directly inside the OctoSPI. And this is the approach which I choose for this hands-on. And for this, we need to create this bootloader. And I already pre-prepared a small project, which we use for the start. And we need to import it inside our cube IDE. And the name is SOM, I think, called hands-on number three. For SOM, it's called on-the-fly decryption underscore OctoSPI boot test. Then you should have inside your workspace at least the hands-on number two. If you have already had the hands-on number three or a boot test, then you don't need to import anything because you already have it. In my case, I don't have them, then I will import them. Then I will select the file and import. Again, we importing the existing project into workspace because I prepared the basic of this project. And here I should put the path to my ecosystem workshop because there is the folder where I have the hands-ons and I want the hands-on number three or in your case, it can be on-the-fly decryption boot test. Okay, made my boot hands-on number three is here or on-the-fly decryption is here. I have here one mistake, then I need the rename this IOC file to have the same name as a project. Then I will name it hands-on zero three. If in your case, the project is named the boot test, then you don't need to change anything. Then this was unfortunately my mistake and we were creating the package. I will describe what this hands-on number three is doing. Currently, it will be not possible to build because I put the one file which using the OctoSPI but currently I know OctoSPI drivers inside our project then it will be not possible to compile. And inside the main is smaller team which basically he is trying to look inside the application which is on the address 90 million and check if on the first position is a value which can be considered as a stack pointer which is the first thing which you should have at the beginning of your application or you usually have it. And he checking if it's inside the RAM memory and if yes, use the second word because there should be the reset vector and he trying to jump on this reset vector. Then this is what this small code is doing, this one and this is the code which we have usually inside our bootloader examples and inside our USB D a few examples then or this loaders and it's called when you jumping from the one application into the second one and we can open this IOC file. Please check if you have the both with the same name, the project and the IOC, they have the same name and I will try to open it. I don't want to migrate, it's not necessary. And what I want to do, I need to add the OctoSPI because it's there. The OctoSPI memory basically came from the standard SPI memory when we have the chip select clock and the one data in, one data outline. And it's now a little bit involved because we have now up to eight data lines. So we can read one byte on one clock cycle even more. We have the chip select and the clock, this is still the same. And we have the one optional additional signal for the data strobing because we're running on the high frequency that it's good to stop the data. And in our case, we will use the feature of the OctoSPI called DDR, which allow to read the data on the writing and the following edge. This is also purpose of this strobing signal because he can give us information when the data are already valid. The OctoSPI one, which is directly connected inside our discovery kit on this pins. This is what I check from the schematic. And our job is inside the QPE mix, configure the same situation that this pins will be configured to the OctoSPI. This is what we will do now. And you should have opened, if you open here the IOC, you should have see the same view. And I am not sure which UV you're seeing here. I recommend here to select the A2Z because I can better orient in it and select the OctoSPI one. In the categories, I think it's inside the connectivity, the OctoSPI one. Then select OctoSPI one. And here select the mode, which should be the OctoSPI. Then we select the clocks, which will be taken from the port one clocks. Chip select, also port one, chip select, data strop, also port one, data strop, data from zero to three, also port one, zero to three, and data four to seven, also port one, four to seven. As a result, all this thing circles with the pins inside should be green. If there is the circle with the pin inside, which is not green, then probably this one is not correct. If it's this done, in the addition we here enable the on-the-fly decryption, we only need to select on-the-fly OTF deck one. It doesn't matter which you select in your project because they are independent unit, but in my file, which I prepared, I'm using on-the-fly decryption one, then please select the on-the-fly decryption one and only activate it. As a result, there should be the green checkbox inside the OctaSpy one and on-the-fly decryption one. If you have it, we can store save the project with the diskette or control S and the KUPE mix should ask us if we want to generate the code and we want, and I want to switch back the perspective and he will regenerate the code. In this step, we should have here inside the domain of inside the Henshaw number three, added the OctaSpy in it and on-the-fly decryption in it, which is a good sign. And as a consequence, we will also have the drivers for the OctaSpy and on-the-fly decryption. So from this moment, it will be possible to compile the Henshaw number three. We can test it. It will possible to build it. But unfortunately, it's not enough because to make the OctaSpy running, it's not so simple. We need to add some few steps because by default, the OctaSpy memory, it's running as a standard SPI memory. It's using one data line. So what we will do is good to send the reset command to the memory to put it into the default state. Sometimes it's good to read the ID to check if it's working. And then we want to switch to the OctaSpy iMode to use all eight pins, the data lines, and enable the DTR mode, which will send data and the commands on the rising and the falling edge. This is done inside this small library, which I prepared or the file of the OctaSpy.c and the H. And we need to only add it into our project. You should see the OctaSpy here inside the source already and we only need to add few things inside our main. And for this, I can use this file to copy 0.3. I will put it next to it to be visible. And we need to copy the include of the OctaSpy.h. So by at the beginning, I recommend line 25 inside the main. Please check that you have the main from the hands on number three and not main from the hands on number two. To be sure, you can click here on this link. And basically it will show you which the file which you have opened here. If I open the different main, it will show me that I am in main inside the hands on number two. But I want to copy this and I want to copy this OctaSpy in it and memory map in it somewhere in the main and I recommend it around line 100 below the user code begin two. And this init will initialize the OctaSpy mode and the DTR mode. And this memory map function will switch the STM32 to know the memory the OctaSpy will be now linked on the address 90 million. Then after this, I should see here the content of the OctaSpy at address 90 million. So I can save, I can build and I want to check now what is at the address 90 million and to be sure that I can verify that it's somehow working. I can put something at the address 90 million and for this purpose I prepared some small BAT file which should be inside your workshop folder and inside the tools and inside the workshop and the tools should be the BAT file load test tags. Then we can execute this file. Please check if you used the cube monitor before then unconnect and connect the board to release the connection to the stealing. And here can run this load test hex which using basically the command line of the cube programmer and he will flash the content of this hex file into our OctaSpy. This only small routine to put something which we can recognize inside the OctaSpy. Okay, my load is done and I can now run the debug of the hands on number three. There is nothing to change and I should start inside the main. I will put here the break point at line 104. I putting it here because then I want to open the memory but I want to open this memory window after the OctaSpy is properly initialized because otherwise the memory window is a little bit confused. I can run the code with the run or F8 and I stop here and now inside the memory I can check the address 90 million. It should be nine and seven zeroes and this view doesn't helping me to recognize what I put there but I can here click on the new one and I will select the traditional one where you can select also the ASCII but the traditional one is maybe better and I can see that I have here the ASCII translation of the content which I put inside the OctaSpy and I have here the text we are trying to check if OctaSpy works. Then it seems that in this state I can read the content of the OctaSpy and on the address 90 million I see this content which is good first step and then seems the basic functionality of our bootloader the initializing the OctaSpy works. So we have the situation when the OctaSpy can give us the data and then the second issue I need some valid content put inside the OctaSpy because currently now my application, the hands-on number three is trying to jump to OctaSpy memory but there is only my testing text and no valid application. So now the question is what to do with the application from the hands-on number two to make it running from the OctaSpy it's not possible only to upload it directly we need to do some small changes. One of these changes and a very important one is that our hands-on number two is created that way that he's supposed to run from the address 8 million which will be not true anymore we want to run from the address 90 million then we need to change this and this will be done inside the linker and the second issue is that we need to tell this hands-on number two where we expect to have our interrupts because by default he expecting the interrupts on the address 8 million but we want to move them to address 90 million two so we need to add this line which is setting this Vito register which is the register telling the core where search for the interrupt vector table the most important table inside your code and this we need to put also into the 90 million. So we start to modifying the hands-on number two then now open the correct hands-on please hands-on number two and first we open here this linker file this STM city to H735 something something underscore flash dot LD which is this famous linker file and definitely check that you have hands-on number two it will not work if we use it for the hands-on number three and what we want to change here we will do the small change we will scroll up and at the line 49 should be defined the sec memory called the flash and currently it's put on the address 8 million and we will only change it to the 90 million we will change the 8 to 9 0 you should have 9 and 7 0s it's very important if you change only 8 to 9 it will not work later you must have the 9 and the 7 7 0s okay I can save this it should be at line 49 inside this linker file and the second part it's inside the main of the hands-on number two and we will put it at the beginning of the main I recommend the line 107.7 and we take here this system control box vector set from the 2 copy 0 3 it will be faster and I put it on the line 177 then from this point after this is executed this code, this application hands-on number two can use the interrupts if he used the interrupt before I call this it will basically end up inside the interrupts from hands-on number three this is the purpose otherwise it will not work second possibility is also to add this inside the hands-on number three but I think you must be sure that it's not changed anywhere in the hands-on number two which I think we have it somewhere inside the template okay then this was the one change and the basic needed change and there is the one issue which I discovered later then when we already created the package there is the one issue that we're using some board support package files for the audio, for the LCD and unfortunately this packages will configure the clock source from the OctoSPA1 and OctoSPA2 to PLL which will be not an issue in the normal situation the issue is that later on when they enabling the configure in the audio they disable this PLL2 and as a consequence it will stop the OctoSPA1 and OctoSPA2 when we already running the code from the OctoSPA1 then our application will basically deadlock then this is the part which we need to correct which is accidentally put there inside the code and we need to put it corrected inside the BSP files and it will be here we open here the diverse the BSP and the discovery, discovery BSPs and here the OctoSPA.C and we will search the line 995 995 and we need to do a few changes I already have some old file interesting because it shouldn't be here I think you should have here the two and you must change it to three and the second part is that you should have here this function I'm not sure why it is not in my case, interesting to have here this function and we need to remove it and put here the hello okay yes I want then here change the two to three and here put this function which was here somewhere else and put here for example hello okay this will basically prevent to switching the OctoSPA2 PL2 but they will stay on the system clock and they are not possible to disable which is good then we will always run from the OctoSPA1 flash without issues then we can build the hands on number two and if you will check the the build analyzer and the memory then here the flash should change from the others 8 million to 90 million I think it will take a few seconds to update yeah now it's changed to the 90 millions so this application is prepared to run from X10R Quad SPI if you try to debug the hands on number two now because the debug will upload this into our memory if you try to run the debug you will discover you will get an error it's because he is he don't know how to download the code on the address 90 million because for the debugger or the loader which loading the memory this memory is not known he definitely knows the internal memories he knows the RAM, the flash on the address 8 million but he is not sure what is this memory and how he can put the code inside it then we need to tell him and this we do if we open here the debug configuration or the run and the debug configuration and we select here the hands on number two this is important we want to change it for the hands on number two and select the debugger scroll a little bit down and there should be the option for the external loader because this is the external memory then we use the external loader and to tell the flashing routines how to put the code inside this flash then you can scan it and it will show you all the external loaders which we have they are basically the loaders for the memories which we have on our boards because okay we know them we know the configuration of the board the paints and all this all this information and we need to select the loader for STM32H735 it's somewhere if you put here this this bar to the middle then it should be here somewhere inside the middle of your screen I will show it again that is somewhere in the middle the 25 or 35 it now doesn't make any difference then they should be the completely the same but we have the 35 then we select the 35 and after we select this then part of the code which putting it's loading the code it's now know how to put the code inside the address 9 million this file is basically small program which was created for this microcontroller and for this memory for the specific configuration for the discovery kit and it's consist basically the routines for the initialization read write and erase and this can be we have the training showing how to create your own loader in case that you have your own board and your own external memory and your own device then for this you can create this loader and you can download the content to this memory with the debugger okay I run the debug and I have no error that seems that this somehow working then the debugging is running and you will probably see that he is somewhere inside some disassembly and he cannot show you what is the code this is because how the GDB server is enabling the debugging and also some other ideas when they reset the device basically after the uploading the code and they directly put the program counter into start of this application of the hands on number two which is not precisely the flow which we want because we want it first to execute the hands on number three which will initialize the octa spi and then we can jump into the hands on number two and this we can do if we stop here or the suspend the execution and we click on the reset here the reset the triangle with the arrow and it resets the the chip which means that the device is executed hands on number three because this is inside the flash then hands on number three is jumping to hands on number two and we see that we are currently inside the hands on number two and if i look somewhere inside the registers maybe i should see that the program counter it's starting on the others 90 million then currently this code is executed from octa spi and if i put here the the nine 90 million and also change the bsp then the code should be normally running and i should end up somewhere here inside the benchmark okay so my code is running if i check it now with the cube monitor which i have still still opened from the morning and i think i will try to connect i will just stop and run my board and i should be able to connect yeah seems that connection is successful and i see that without cache the performance of the octa spi is pretty low okay it's it's uh expectable because it's very slow very small bandwidth comparing the antenna flash if i enable the cache it should cover me the the disadvantage of the octa spi pretty pretty well and i can check the situation when i start to offload the the cache but this was only for the for the testing again this is not normal code which we created for the for the hands on number two which is not normal application the normal application more is more linear and even the linear code it's pretty good handled by the octa spi but the jumping on the memory this is the issue and this is usually the main focus of the of the cache so that seems that in my case the execution from the octa spi works pretty well we definitely managed to put our code inside the octa spi and we managed to create our simple bootloader so this is very good good progress now the issue is that everyone who have this loader which we use or will answer the octa spi memory everybody can read its content and can use this content again because they can understand it because they see directly the readable the valid data then we will try to protect this this content inside the hands on uh inside the hands on number two to be more secure and for this reason we will use the on-the-fly decryption on-the-fly decryption is basically using the as and the basic as acb mode is doing that we have the as unit we have the key and we put there some encrypted data and we get the decrypted data or text back but we're using something called the ctr mode which is a little bit more complicated but give us more advantage because we're using the key but basically we are not decoding the data or the instruction or the code we're decoding the something called the initialization vector or this is my how to say how i imagining it and the initialization vector is composed from some values called the non-serve and the version these are values which we can select how we want it's the similar to the key how you select them they will they will exist and there is one value which belongs to the region i selected for our purpose region number one because the octo spay have the on-the-fly decryption is possibility to use up to four region but i'm using region one and the second part of this initialization vector is the address which is the address which we want to decode this is the value which is changing with the address for the 90 million will be the address 90 million for the higher address the address will change and this is the value which will be decoded and it's good because when we ask the octo spay for the address 90 million he will immediately start in the same time to start this decoding and when the octo spay finally give us the data for the 90 million we simply do the XOR and we have immediately the data to use then the slow and the delay with the decryption will be minimal and i was not able to measure any which is good for us so we need to add the decryption and this is done with the file which i used on octo spay.c we only need to add this on-the-fly decryption in it and what this function do it basically set the key which i select as a one two three four seven eight and then it's setting the initialization vector so he putting this nonce values and this version this is this this values which we can select how we want i selected the a5 c3 and the version a bcd and the parameter of the on-the-fly decryption is which location will be covered with the on-the-fly decryption and in our case it will be a region of the 90 million because this is where it's our octo spi one the octo spay decryption will work then we only need to add this into our code so i will here go back into the main inside the hands on number three and i will here the copy this octo spi uh decryption in it somewhere at the line 102 if you have the similar numbering and i can i can build the project now and after this is executed then on the address 90 million he will always try to decrypt the data from the octo spi which is good i can test it by running the hands on number three and what i will see i will probably see nothing because currently inside the octo spi is my hands on number two and he will basically try to decrypt this hands on number two but issue is that this hands on number two is not encrypted at all then if he try to decrypt it then he will create complete nonsense then if i look on the address 90 million then on the first address i should see the stack pointer value which is somewhere inside the ram and i see that the first value is bd something which is far from the ram on both directions then this this code was maybe decrypted but i'm not getting any valuable result then i need to somehow modify the hands on number two and i need to create the encrypted version of this binary so i need to change somewhere the binary and create encrypted version the question is how to encrypt the hands on number two in addition to be useful for our decryption and for this i prepared one bot file which will do some steps uh basically i'm using for the encryption of this bin binary of this hands on number two the open ssl tool which i will give him the key and the initialization vector but the issue is that the open ssl tool acquire a little bit different by byte order then it's inside our binary it's usually a difference between microcontroller world and pc software then i need to reverse the bytes around the open ssl reverse the bytes back and then i'm using the tool which will create from the the hex file from the binary then for this i will give him the address where i wanted this hex file to start which i giving the 90 million and at the end of this binary uh he will program everything with the q programmer to our memory automatically so for this i prepared this bot file which is inside the tool which is the encrypt underscore bot and it requires as an input parameter the path to the file which i want to encrypt the name of this file i need to give him the key which i want to use inside the open ssl the initialization vector and address we can run this manually from the command line but it will be a little bit annoying to run it each time when we change the hands on number two then we can make some automatic version and we can use eclipse to do this all for us then we need to convince eclipse with some modifications and first is that i need here this this name which i i selected as a nk path you can copy it from the to copy zero three and i will put it by inside the hands on number two by clicking right click on this project and i will select the properties and i will here go to the c c plus plus build and inside the build variable and i will add new variable called the nk path i will select the type as a as a file and i will browse these files and the file should be inside my workshop inside the tools and there will be the nk bin underscore bin dot bat this is the bat file which will do for me the encryption and it basically if i use inside the eclipse this nk path name it will refer it with this this long value and he can execute it then i will add it like this and i will apply it okay i hope it's it's okay now i can close it and i will here copy the last command which i have inside my to copy is very long and a little bit complicated so i recommend to copy it and we again put it inside the hands on number two and inside the properties and i now put it inside the settings and inside the settings you should have something called the build steps and this is possibility which you can call some functions or the bin files or the bat files before the compilation starts or some post build steps which you can use some bat files after the compilation finished and this is what we will do then we will put here this long command and what this will do this dollar and the bracket means that what is inside will be executed and we have here the nk path which is our sorry our build variable which is linked to the to the bat file then he will know the bat file and he will execute him and if you remember from this from this file the first parameter is the path to the file which we want to convert and the his its name this is the second one then this pwd is the path to the bin file and the second parameter is the project name which is the name of the of the binary if you want to know how i discovered that this is the project name that here inside the build variables you can show all the variables and somewhere here will be pwd and i know that this is this path to the debug and inside this will be the project name hands on number two then decide how i discover what to put there okay then this will start the binary and the fourth parameter is supposed to be my key which is and it's a little bit inverted key because unfortunately how i told you that pc tool interprets the values a little bit differently than my code then inside my code i selected the key as 1234578 on the first place but unfortunately inside for this open ssl the order is a little bit changed and this 1234578 is at the end then if i compare it inside our ide then it fits that 1234578 is at the end and the fifth parameter is my initialization vector which is again composed film this non-ser values from the first one and the second one again the order is a little bit a little bit changed then be careful you need to switch the lsb and msb basically there is the four zeros which is defined by our reference manual for the on-the-flight decryption then it should be always zero there is the value for the version the abcd it should be the same abcd there is the region which is used in our application and i selected the region one and the last one it's the value of the address which we will use divided by 16 then it's i think only nine million and the last parameter is the is the address where we put want to put this hex file which is this 90 million so this is the this is the mystery behind this line then this is the key and this is the this is the initialization vector and they should match the values inside our project if not the decryption will be not successful okay we can save it apply and i can try now to build the hands on number two uh build project and i will check completion is done and then it was run automatically my script you see the there is the written encryption start encryption end then i have some cleanup i'm creating the hex file then i created the hex file and i'm running the cube programmer which will upload this encrypted hex file into the octo spi then now after this build i have inside octo spi the valid code which is encrypted and i should be able to to see if the if the result is correct then i can run the bug for hands on number three again and see if there are any any issues i again put the breakpoint on the 105 and i open the memory double click open the traditional and you see then the comparison between the previous attempt it seems that on the first address or the ninth million it's something 24 and this value is basically the run then it seems that this value is for me valid and the older values should be the position of the interrupt vectors first is the reset vector non-mask cable interrupt hard fault handler bus fault handler maybe and other faults and they all starting with the 90 million then it seems that definitely this is for me the valid valid it looks like that i have on the address 90 million valley code then i can decrypt correctly and i can execute the valid code with the decryption which is good then i can close this one the issue can be now if you try to debug hands on number two you will discover that it's not working how we want it and it's not possible to debug the hands on number two why because the build the building will create for us the encrypted hex file and also the build will upload the hex file into octo spi but if we try to debug he unfortunately take the hex file which is not encrypted and he will again rewrite the content with the octo spi and then the decryption will stop working again then we need to somehow prevent it and we can do it again inside the debug configuration inside we will switch to the hands on number two and we can here modify the startup of the debugging and we can tell him that we don't want to upload this file because we know that this is not encrypted then this is not good for us then we can here edit it and we can uncheck the download so he will not download this code anymore because it's done with our build and if i click on the debug i will be able to debug encrypted code inside the octo spi and if i running and i should be somewhere inside my main i am inside the main and i should be able to step yeah and if i check the registers i should see that i am inside the octo spi on the others 90 millions and even with the decryption so it seems that my my decryption is working i can also check my demo inside the note red it should work i hope it's still working and basically when i measure this i was not able to see any any difference compared to the code without the decryption then this was always the same it's because how the octo spi work because the octo spi works that i need to send the command i need to send the address then wait some dummy cycles before i get the data back and during this time he is able to decode this address this initialization vector and in the time when i get the data he have the result of the decryption and he simply do the xor and i get the data immediately without any delay so this was reason why i was not able to see any any difference i have here the results also i create some small graph showing how is the how is the performance measurement also be be careful with the performance it's a little bit tricky because this is not maximum how to say maximal performance of the core it's usually the setup which we created and i think definitely it's possible to squeeze the performance even more by the optimizing the usage of the memories and the other stuff but for us we can effect as a performance then in our case the without cache the flash was running always 73 percent and when the cache was enabled we get on the 100 percent and when we stop losing the cache the the performance drops slowly to 73 percent when we use the octo spi without the cache we run always on the 8 8 percent and if we stop using the if we were not able to use the the cache the performance was dropping to this 8 8 percent but be careful again this this code which we created is a little bit really unusual and in the normal situation i was never seeing the code which work like like the ours which is more linear which is better handled with the cache so if you will decide where you allocate the cache i would definitely recommend to allocate it to most of the cache to the octo spi if if possible because the flash performance is still good because the drop of the for the flash with the performance is maybe 25 percent but with the with the external memory is maybe 94 92 percent and it's usually better to cover external memory with the with the cache to decide which which memory will use the cache you can change it here with the configuring the unit called the mpu called the memory protection unit which can also set the behavior of the cache memory here are also the values which i was not able to see any difference where i used the on-the-fly decryption for the octo spi and not using it then the behavior was completely the same then this was no not the difference for me and only to see the bandwidth of the of the octo spi it's currently running on the 91 megahertz and i reading data on the rising and falling edge which means it's multiplied by two but don't forget that you need to set with this also the commands also the that the addresses and also wait for dummy cycles then the real bandwidth of the of the octo spi is much lower okay so if i summarize what what he did we were able to change the hands-on number two to run from the from the octo spi and we were able to run the on-the-fly decryption then we were not able to see any difference with and without on-the-fly decryption we checked that definitely the octo spi performance is much better when we're using the cache because this is the main purpose of the m7 i believe to use the cache and mainly for the external memories because otherwise it was not make no sense to use the external memories for the code for the data it's okay but for the code it was tragic and we were we were checking what is the difference of the of the drop when we start to or floating the octo spi memory from the out from the cache okay then thank you