 The goal of this part is to demonstrate how we can use STM32 Cubemix to prepare an application, which is using free R2S. We will reuse an empty project prepared for STM32L476 VGT6 microcontroller, so as you can see we've got an empty project, there is nothing assigned to the pins, and we can start a new application. The first thing we need to do is to select the debug interface pins. So I go to System Core Sys, I select within the debug tab serial wire, so I can see both debug pins present. And the second thing, very important, here is to select the different time-based source. Time-based source is in fact the timer, which is used by the HAL library over the code generated by Cubemix. And what is important is that the same timer, SysTick, is used as well, it's dedicated for free R2S as a time-based for this system. It is not recommended to use SysTick for both purposes, so for HAL library and free R2S. So we need to select the different time-based source for HAL library. What we can select? We can select any other timer which is available within the microcontroller. What I would recommend here is to use either Timer 6 or Timer 7, which are timers without any input nor output channels. Those are dedicated to synchronize other peripherals and to generate a simple time-based. I would select Timer 7 in this case. And if now, if I would go to the timers, I can see that Timer 7 is not accessible anymore for me. And I've got the message that this timer is used for sustained time-based. Okay, so this is the first point. The second point is to add free R2S library. We can do it as well, within pinout and configuration tab, going into the middle bar section. And now I can see free R2S. And when I click on it, I can select the interface. There are two options here, CMC's V1 and V2. What is used within HAL libraries and the SDM32 Cubemix is in fact the free R2S API with an additional layer, which is called CMC's OS layer. There are two files, CMC's OS.C and CMC's OS.H. We are describing this API within different sections of this training. So for our purposes, I would select CMC's V2. And now I can see the configuration for the free R2S. There are a lot of tabs within this. Now we will focus on two most important ones. Config parameters, which is the main configuration of the free R2S. And include parameters, which is used to select the modules, the functions, which will be included into our code. Please remember that if you are not using any of those functions, it is highly recommended to disable it. So to not include it into the code, to not extend, to not increase the code size of your application. Let's come back for a while into the config parameters. As you can see, some of the options are not accessible for us. Those are the API version, free R2S version, CMC's R2S version. But most of the fields are still available for us. We will describe most of them, the most important ones, within different sections about the configuration of the free R2S. So let's not focus on it here. So the second option, the include parameters, we already described. We can enable or disable the function, which could be included into our code. Then we've got some user constants, which can be used as well for us. And the rest of the tabs are related to particular parts of our R2S system. So starting from tasks and queues, I can see here two parts of this window. The first one is tasks, where I can add, delete, modify the tasks I would like to generate within my free R2S application. By default, there is only one task created. It's so-called default task with the priority normal, stack size 128 bytes, and entry function, which is called start default task. I can change it by double-click on this line. And now I can change the name, priority, stack size, entry function, and as well, code degeneration option, parameters and allocation can be either dynamic or static. So this is how we can modify existing tasks. If you would like to add something, I just press add. I can see the new window where I can put the information about my new task. If I press OK, I can see the second task present. I can do similar operations for the queues. So as you can see below, I have no queues by default. So I can add one of those. Here I need to put the name, queue size, so number of elements, which would be inside the queue, and the size of one particular element. Queue, in this case queue, will contain 16 elements, and each of these elements would be the size of 16 bits without sign. If I press OK, I can see this new queue as defined. I can change settings of this queue, its name, size or item size by double-click on its name, like with the tasks. Then the next tab is about the timers and semaphores. If I click here, I can see the first part is about the software timers. The second one is about binary semaphores and counting semaphores. So for the timers, if I click OK, I can see as well the name of the timer. It's called back, so the function which would be called when the timer will overflow, and the type of the timer. The timer can be periodic or one-shot. We've got a dedicated section within our training on software timers, so you can have a look on this. And again, if I press add, I've got some default settings, and I can see my timer. And if I would like to edit existing timer, I just double-click on its name. The same story is with binary semaphores. So if I click add, I've got only two fields, the name of the semaphore and its allocation. Because binary semaphore, it is something either turn on or turn off. There are no parameters, there are no values, no variables inside this. So it's a very simple component of the operating system. I can see the binary semaphore edit. The same story is with the counting semaphores. The only difference is that with the counting semaphores, we've got an additional component variable, which is count. Because counting semaphore can be given or taken a few times, depending on the value we will set during its creation. So if I press add, let's change its name, semaphore cnt, and I would change this to 5. If I press OK, I can see its name, semaphore cnt, count 5, dynamic allocation. It means that we will have the semaphore named semaphore underscore cnt, which can be taken 5 times, and then it should be given maximum times 5 times. So this is an extension of the binary semaphore. And again, we've got a dedicated part within this session, which is about the semaphores binary and counting. You can refer to this part for more information. The next tab is about mutexes. If I click here, I can see two fields. I can see mutexes and recursive mutexes. Mutex is an extended version of the semaphore, which is giving more mechanisms, which are protecting the tasks, which are operating with the mutex. The creation of the mutex is very similar to the semaphore, so I just click add. And as you can see, we've got only the name of the mutex. I would just change this name into the mutex, mutex1, and that's it. So it's very, very simple. More information about the mutex, as you will find in the related part of this training later on. Additional tab is about the heap usage. So it's a very, very useful one, because it demonstrates to you how much memory you have already consumed and how much of it you've got still available for your operating system. As you can see at the beginning, we've got heap still available in bytes. So we've got still 1,300 bytes available for our system from allocated 3,000 bytes. Then what we use so far is 1,700 bytes. And as you can see, most of this has been consumed by the tasks. Then some part for the queues, a little bit for timers, and 264 bytes for mutexes and semaphores. And then you've got more details. You've got how many bytes has been consumed by each task, and then each queue, each timer, each mutex, and semaphores. So it's very useful. It demonstrates to you whether you need to increase or decrease the size of the heap which you declared within the config parameters. So this is the area where you are declaring the size of the heap. So total heap size is a RAM memory declared to store the information, the variable information about the components of the operating system. It has been defined by default as 3,000 bytes. The next section will be dedicated for the configuration of the operating system. So you can learn a bit more about each of the parameters you can see right now on the screen. This is the configuration of the 3-year tasks. The important point is to properly configure the interrupts within the system, which is working with 3-year tasks. Let me go to the system view to demonstrate to you how it is done. Now what you can see is the list of available interrupts within the system. So what you can see, there are some system interrupts which are enabled by default, and then you can see the priority number. At the moment we've got 3 values, 0, 15 and 5. 0 means the highest possible priority. It is assigned to the system interrupts. 15 is in our case the lowest possible priority, as we've got 4 bits available to set the priority level. And those two interrupts are related to our operating system to system context switch. We will describe this topic more in details when we will discuss about the scheduler. So now please have a look that the switching of the context has a lowest possible priority. It is done to not block any hardware component and hardware peripheral by the operating system. So as you can see the operating system, the 3-year tasks in the embedded system, is working as an additional layer which should not interact in a negative way. It should not delay any of the hardware interrupts which are present within the system. This is why the switching of the context has a lowest possible priority. Below you can find a few interrupts which has been assigned by the priority number 5. This number 5 is coming from our configuration of FreeRTAS. Let me come back for a while to FreeRTAS configuration, so I click on this FreeRTAS. I go to the config parameters and I scroll down at the end. Please have a look on two last fields within these config parameters. The first one, library lowest interrupt priority. It is a definition configuration of the lowest possible priority, which is available within our embedded system, in our case within Cortex-M4. So in this case it is 15 as with an STM32 we are using 4 bits only. And this interrupt would be assigned to the interrupts which are used to switch the context, as you already seen on the previous screen. The second component where we've got this value 5, it is the constant called library max Cisco interrupt priority. And this constant, this define, is setting the maximum level of the priority of the interrupt, which can still execute APIs or functions from the operating systems. This is a very important point due to the fact that all of the operations with an operating system, so switching the context, changing the priority of the task, waiting for the semaphore, waiting for the queue, changing anything within the semaphore's queue smooth access, any change within the components of the operating system is done with so-called critical sections. All the critical sections within the FreeRTAS are done in such a way that we are blocking all interrupts with the level which is set to library max Cisco interrupt priority. So we are blocking those interrupts which can execute any of the function from the operating system. We are not blocking interrupts which are related to the hardware and do not use any function of the operating system. So this is this number 5 we've seen within the NVIC configuration. And at the moment the other components have assigned this number 5. And then if you go on the right side you can see use FreeRTAS functions. This use FreeRTAS functions means that all those interrupts which has selected this column must have the interrupt level between 5 and 15. We can have a look on the first example. As you can see I can have a selection from 5 to 15. Lower number is not possible due to the fact that we configured in the FreeRTAS config.h file, so within the FreeRTAS configuration this level is a maximum priority level for the interrupts which could execute FreeRTAS functions. So this is the configuration of any interrupts. We will come back to this point later on within the description of the operating system. The rest of the components including the code generation, including the DMI configuration is completely the same like with the different STM32 Cubemix application. We will not spend time on this part. This is all information I would like to pass to you within this section. Thank you for watching this video.