 In this second step, we are going to activate Tracex. For the ones who do not know, Azure-RTOS Tracex is a Microsoft host-based analysis tool that provides developers with a graphical view of real system events, and enables them to visualize, better understand the behavior of the real-time system. So with Azure-RTOS Tracex, developers can see clearly the occurrence of system events like interrupt and context switches that occur out of view of a standard debugging tool. So the most important thing is this slide is to understand that we are going to see this behavioral view of our system using an external tool, which belongs to Microsoft and it's called Tracex. You should have already installed it and as it was present in the installation pack that we provided. Another important feature that maybe can anticipate some of the question is related to the fact that Tracex allows a post-mortem analysis. So it means that it's an offline analysis of the sequence that is running on our microcontroller. So here you have the steps needed to make Tracex work. You need to activate the feature in firmware. We will allocate the memory. It will be an SRAM memory. We then need to execute the firmware to fill in the trace in the memory and then basically, we save the content into a file with a specific extension we are going to see, and we will use the Tracex application on your PC to display the results. Now, we are going to see all of these in practice. So I will come back to our code, which was in running mode and we go out from debug. So we click on the red square and we terminate the debug section. Now, we should be back to our .ioc file. So the configurator for our H7, we now need to go to software pack, select component, and we need to activate Tracex support. We activate Tracex support, we flag the related line, and we click okay to validate. We go to software pack, stmicro, xcube is RTOS H7 2.0.0. You see there is a new tab called a trace that we enable right now. We have to go into that and enable the event trace. You see that there is this time source. This time source is an ARM core register, is the DWT register precisely, so data watch point and trace unit, from which we are going to take the timestamp source that we'll use for the tracing. At this stage, we only need now to generate code. So another way to generate code is to click on this yellow wheel, wait for a few seconds until the code is regenerated. Okay. So as you saw from the part one, the entry point is uptrend.c, and we are going to work mainly on that for the Tracex enabling part. We are now at slide number 54 of the presentation that you got. The first thing we have to do is to allocate a specific section in SRAM to save our tracing buffer. So we have to go to our linker file, which is STM42H723ZGTXflash.ld. You see that here we specify the different memory areas of the microcontroller. We are going to put a dedicated section in SRAM D1 for the trace buffer. So at line 1 to 2, around line 1 to 2, so after a flash definition, we define a new section. We can cut and paste from the slide or follow along from the sheet sheet, and we define, we basically place a section to AXI SRAM. So now the trace buffer location will be known and location will be the starting address of SRAM D1, which you see here is 2460s. So now what you can do is close the flash.ld and save the file. Perfect. So now you can go back to your uptrend.c, which as I promised is the main file that we are going to work on for the whole morning. And we basically have to define the buffer use for trace and put the buffer to a specific RAM section. And this is exactly what we are going to do. So right after the definition of the thread pointer in this section, use code begin PV between use code begin and use code end PV, we are going to define the trace buffer size. The trace buffer here is calculating, is calculated knowing the TX trace header, the TX trace object entry and the TX trace buffer entry. Then we are going to basically define the trace buffer, which is an array of length 64k, and we put them in the section we have just defined before. Now we have to enable the trace and to enable the trace, we move to uptrade init function. And right after the TX thread create, in section user code begin uptradex init, we are now going to add the TX trace enable. So here we have defined the trace X enable. This is our trace buffer, this is the buffer size 64k, and this is 30 is the amount of trace objects in the buffer. So we are actually going to use just four rows in total, which are the thread scheduler and the idle task, but you may want to see more. So we allocate up to 30 trace objects for this instance. Okay, so this is all we have to do before building and flashing our project. So at first we are going to click on build, so on the hammer and we compile the project. This may take some time. We click on run debug. Okay, so now we are in debug mode and in order to see the trace buffer fillet, we need to open the memory view. So for opening the memory view, you should have this cylinder picture right above the TX list in your debug perspective. Or alternatively, you can enable it from window show view memory. As a first thing, we need to add a memory monitor for the variable that we have just defined, which is tracex underscore buffer. And we click OK. Okay, you see it's correctly and we're not surprised it's positioned at the beginning of the SRAM, XC SRAM, at the same address that we defined initially. Now we have to fill this buffer with relevant information. So it's very important to remember that we need to run the project and see the LED blinking for a certain time period before suspending it. So in fact, we see that the value in the memory monitor are changing, so it means that the buffer has been correctly filled with the data that we are going to use as an input for the tracex. So now we have some data here. We just need to click on export button, which is this arrow pointing on the top of your screen. You see you should have row binary format. The start address should be untouched. You should put the length 64K, which is the one we defined at the beginning, select again row binary and select the directory in which you want to save the file. The important thing is to give the file an extension dot TRX, otherwise you cannot open it with tracex and give it a name, okay? I call it the log number 20, okay? Because I have many in that folder and I click on, okay. Good. Now we are gonna move forward and for a few minutes we are gonna use the tracex application. So you should have tracex installed and please open it, okay? So you should have a blank view like this one. You shall click on open file. Open file is this folder with the error that goes into it and you're gonna click on your log. For me it's log 2.0 to differentiate from previous ones. Okay, so it's working exactly as expected. It could pop up an error mentioning error opening custom event file. You can just click okay and move forward. So we are now seeing something very interesting that I'm gonna explain. So this is basically the sequential view mode. This is actually the default mode and in this mode events are shown immediately following each other. So regardless of the elapsed time between them. It basically shows the event from the beginning to the end and it definitely gives you a good overview of what it's happening in the system independently from the time that has elapsed. So it's definitely very interesting just to understand how our application is behaving. You see that we are running the thread and when the thread is asleep the control passes to the scheduler and the system goes in idle mode and you see the interrupt line. The interrupt line is actually the timestamp so it's actually the tick we selected the beginning. You see here that again this is not timestamp it's just a sequential view of what is happening inside the system. Another important thing I suggest you to look at is view threadx legend. If you click on view threadx legend you got the legend to be able to understand what all of these letters inside the block meaning. For example IS is thread suspended, IR is thread resum, R is thread running which are the most common you will see in our demo there are many more, TZ is thread sleep. Okay so this is definitely not all that we wanted to see because we would like to see how these events are behaving into the time domain and to do this we use the time view. So please click on time view tab and the first thing we need to do is to select the right scale. So a good number is 550. You can choose another number but basically this 550 gives us a pretty good scale so it means that every microsecond is actually 500 of, 550 is made of 550 blocks inside the viewer so it gives us the right granularity to see the events we want to see. First thing you notice is that actually our thread is running for a super short time. You see we are quite all the time in idle task. Actually you couldn't see quite anything in my thread. You have to zoom a lot. To zoom a lot you have to select a vertical line and zoom. You see that actually in fact we are executing but we stay in the thread for just a few microseconds. This is expected in fact because our thread actually is really running only during GPIO toggle and during sleep the scheduler passes the control to the idle task. So this is completely expected that we see the GPIO toggle only for a few microseconds. Okay so let's change a little bit the behavior and let's try to come back to our uptrend.c to see how we can spend more time to see the thread running for more time without passing immediately the control to the scheduler and the idle task. So a good way to do this is try to run some operation inside the thread entry. So in order to simulate some activity inside the thread entry we are gonna use a HAL delay. So maybe some of you will like to write us in the chat which is the difference that exists between HAL delay and the TX thread sleep. Okay just to do a small checkpoint to see if we are all aligned with this. So in the meantime I'm gonna write HAL underscore delay and then to auto compile I'm gonna click control space and I'm gonna put 500 here and semi column. In this case you are expected to have something like this. So the HAL delay running for 500 milliseconds and the sleep running for 200 milliseconds. Let's see if this is the exactly what we were expecting. So we can launch the debug session. Okay, so we should actually make exactly the same thing we did before. So we should run the code, break after a few seconds, go back to memory monitor and click this time you have already the trace buffer selected and you click on X integer. And as expected you see that the buffer is filled with some value that now we are gonna analyze. So again, please click on export. Everything should be set exactly as before. So you should have a row binary length of 64K and please give it another name. I'm gonna call it log 21 and click okay. Now if you have trace X open again you have to click here on the open file select your new file. In this sequential view there is no much difference as expected but actually if you go in the time view and you zoom out a little bit, okay. You see that it's behaving as expected. So we stay the thread is running basically for, you see here 500 milliseconds and we stay in the idle thread while our main thread is leaping which is 200 milliseconds. So it's exactly behaving in this step and we have seen how to change the behavior and see basically the thread properly running. There is another nice view that you can use in trace X which is execution profile. If you click to view execution profile you can see that in percentage the time is split between 75% of my thread running and 25% of idle. So for a total let's say typical profile of 700 a typical cycle of 700 milliseconds we spend 500 milliseconds with the thread running and 200 milliseconds in idle.