[MUSIC] In this module we want to have deeper look in to what actually happens inside OS when scheduling real time tasks. We therefore going to dedicate part of this module the real-time operating systems. Real-time operating systems can be categorized into different types depending on functionality and complexity. The most basic OS type is the thread package which contains only a simple task based execution model. Most other OS level functionalities like file handling, networking, and sometimes dynamic memory allocation is only available as an option outside of the OS. Thread packages use, in general, no virtual memory so tasks can operate in the global memory space and the developers must ensure that memory violations do not occur. Microkernels are a step up from the thread packages, but it's still a very small system with only the basic functionality inside the kernel. Microkernels use message passing instead of kernel calls. Permit communication between tasks and the kernel. One upgrade from thread packages is also the use of virtual memory and this simplifies the life for the programmer since the task can declare a virtual memory space and a run time system will ensure that no memory violations happen. Monolithic kernels have also been used in real time operating systems. The idea behind the monolithic kernel is completely the opposite to the one of micro kernels. They have here one big kernel containing most of the functionality and all kernel resources are called synchronously by kernel calls. There's a strong separation between kernel space, in which for example device drivers run and use the space where the real-time applications run. The OS we focus on in this course is FreeRTOS. FreeRTOS is a small real time kernel ported over 35 different architectures. From tiny 8 bit micro controllers to our grade mobile phone multi core CPUs. It is a very popular choice both for industry and academia because of its light weightness and low learning threshold. FreeRTOS is also open source. So no functionality in the kernel is hidden from the programmer. It supports both preemptive and cooperative scheduling, and FreeRTOS in itself is not very big. It uses about 500 bytes of data memory for the kernel, and then additional memory for each task, depending on the stack sizes. And the whole OS uses about 10k of program memory. Depending on the compiler and its options. So it fits in almost all small micro-controllers without a problem. FreeRTOS is up and running in about one millisecond. So compared to a normal desktop OS this is quite fast. RTOS uses task as a definition of work instead of the traditional process. Tasks are created in FreeRTOS either during system initialization or during run time in another task. So when a task is created in FreeRTOS, the task gets a C structured called a Task handle. The task handles away the control interface between the task and the OS. So for example, if the OS wants to change the priority of task. The task handle is first as a reference to the system call. The task also needs a stack to store local variables in. And this stack is allocated in the memory heap and its size is given as an input when creating the task. The information about the task is stored in a structure called a Task Control Block or TCB. Here we store information about the references to the task handle, the name of the task, and its priority. They also store a point that their task function which tells the OS where to jump when this task is selected for scheduling. The stack size of the task is defined here and it is possible to pass some parameters to the task in form of a void pointer. We will show this in practice by defining the functionality of two tasks. So here we have the first task called the SensorTask. And this task is use to simply read a value from a physical sensor and send it a message que. The task is written as a C function. With an infinite loop which never ends unless the task is deleted by the system. Inside the loop we have one read function which gets the measurement value from the ad converter connected to the sensor. And the other task is called the LCDTask. It is also a C function which contains code to display the measurement value on an LCD display. So in the same fashion this task is also an infinite loop with continuously reads the message queue for incoming data. Once data arrives it's res variable gets a value and the function for writing the LCD display is called with res as the argument. You will see to end both tasks a function call to vTaskDelay. This is a functionality in FreeRTOS to place a task in the blocking state and it will stay there as long as the parameter indicates in milliseconds. When the functionality of our tasks are defined, we must include the tasks in our system, and start scheduling them. This is done in FreeRTOS, by firstly including the FreeRTOS.h header in the project. In the main function, we create one TaskHandle per task. And we have one called sensorHandle and one called LCDHandle. We then create the tasks by using the vTaskCreate function called in FreeRTOS. And pass the handle, the priority, the stacksize and a function pointer as a reference to the system call. We then start the scheduler by calling the vTaskStartScheduler. And after this we go into an infinite loop because after this point only the tasks should execute, not the main function. In conclusion, we have chosen FreeRTOS as the reference OS because it is very easy to learn. It is ported to almost all popular embedded processors, and it is open-source. In FreeRTOS we defined a task in a single style function. And the FreeRTOS kernel switches between these different functions, as it schedules the tasks. In other lessons in this course we will also have a look at some more advanced concepts of FreeRTOS.