 Some examples of main interface procedures for GCC compiler. Let's have a closer look on a startup procedure of FreeR2S. We will analyze PRV port start-first-task function within port C file, prepared for GCC compiler and STN32L476, so Cortex-M4 based platform. At the beginning, the scheduler needs to locate the beginning of the stack and load it to the stack pointer register. In this case, it would be main stack pointer MSP. Beginning of the stack in Cortex-M-based devices is always start at the beginning of the vector table. As this core allows us to relocate a vector table, we need to check where it is. This is why the scheduler needs to perform the following list of operations. Load to R0 address of NVIC register, which contains the offset value. Load to R0 content of the offset register. It will be the address of the beginning of the interrupt vector table and then load to R0 content of the beginning of the interrupts vector table and it will be an address of the beginning of the stack. Then the scheduler needs to load this address to the stack pointer register, so the main stack pointer used by FreeR2S kernel MSP register. Next step would be to unblock all of the interrupts by clearing the pre-mask bit if it will be set to one, only the hard fault and NMI interrupts could be executed and clearing the fault mask bit. Next two instructions are so-called barrier instructions, which should guarantee that all of the current data and instruction busses operations will be finished before next instruction. Our interrupts below this line can be visible. Next step is to call SVC interrupt, which would start operating system. As you remember, it is one of the three interrupts dedicated to FreeR2S. Let's have a closer look what is happening within SVC interrupt handler. SVC system call interrupt handler is present within port.c file as vPortSVC handler. At the beginning scheduler needs to find the location of the currently selected, so being in run mode, task. It is pointed by PX current TCP address. Scheduler needs to load the first address from this TCP, so task control block, which is an address of the next free location within current task state. Then it needs to take R4 to R11 and R14 core registers from this task stack to recover it last state before it has been moved from run mode. At the end of this operation scheduler stores an updated stack pointer into process stack pointer, PSP. Then it needs to enable all of the interrupts related to the operating system. For this scheduler needs to store 0 into base pre-register, so in fact disabling this mask register. Last step is to execute selected task code. Let's have a look what is happening within pentSV interrupt handler. This handler is present within port.c file as xPortPentSVHandler function. Within this function scheduler is moving currently executed task from run state to ready state and is selecting another task to be in a run state. It is starting from storing the data of the current task on its stack. At the beginning it cives current process stack pointer in R0. It is the top of the stack of the current task. Then it reads the address of the current task TCP address and store end of its task stack into R2. Then the scheduler is checking whether the task which needs to be removed from run mode was using FPU by test of R14 content. If FPU was used scheduler needs to store FPU registers S16 to S31 on current task stack. If FPU was not used it escapes this step. Then scheduler needs to save core registers of current tasks so R4 to R11 and R14 and it saves new top of the stack as a current top of the stack in TCP of the current task being now in run state. Then the beginning of current task stack TCP is stored in a stack pointer register main stack pointer register as the MCU is in the interrupt mode executing operations of the core. Please note that the application is still in old task execution mode. Now it is the time to switch the context. The first step is to freeze operating system for a while. To do this scheduler is blocking all of the interrupts from config.max.cisco interrupt priority value till the end. So all of the interrupts which may execute operating system functions plus cystic interrupt plus pentSV interrupt are blocked. It is not blocking all other interrupts of the MCU. For this operation base premask register inu is used. After this operation there are barrier instructions which guarantee that the next instruction will be executed once all of the data transfers and previous instruction executed will be finished. Now it is the time to switch the context. Switching the context so selecting the next task to be in the run mode is done by vTaskSwitchContext procedure located in task.c file. After this operation scheduler can unblock the interrupts by clearing base register content. In the next step the scheduler will operate on the stack of the new task to restore the core registers R4 to R11 and R14 and in case there were any FPU operations done in the task this new task during previous execution it needs to restore the content of S16 to S31 registers as well. Next an update of the process stack pointer, psp, is done and come back from this procedure which allows the new task to be executed from the last place it was stopped during previous context switch. Critical section mechanism allows us to block all the interrupts during sensitive or atomic operation execution of an operating system in particular. The blocking of the interrupts it is valid only for the interrupts which are using operating system functions. So till the level specified by the configuration config library max syscall interrupt priority. All interrupts with higher priority than this one would be not blocked. So our hardware which is important for our application would still be fully operational. Its interrupts would be executed would be not blocked. The blocking point would be only for operating system and its components and all interrupts which are cooperating with the operating system functions. To enter into the critical section we are using the macro port enter critical to exit from it port exit critical is used. As you can see from the picture below within the port enter critical what we are doing we are configuring base pre system register with the value of config library max syscall interrupt priority to block all the interrupts related to the operating system. Then we can perform any operation which is touching which is modifying queues, tasks, semaphores and after the sensitive code execution we can restore the base pre so the masking register to the default value which is 0 so in this case all the interrupts are unlocked in this case. Let's have a look on the critical section implementation within the port for STM32 devices. The critical section functions are stored within two files port.c and port macro.h. Within port.c file we can find the functions c functions which allows us to enter and exit to and from the critical sections and both functions are calling in fact the macros which are operating on the base pre register which is masking interrupts so in fact blocking some of the interrupts on some level within the critical section. As we can see from the port enter critical we are calling the macro port disable interrupts which is the beginning setting the base pre register with a config max syscall interrupt priority the priority which is the maximum value for the interrupts which are allowed to execute the functions from the operating system then next two instructions are the barrier instructions to be sure that the execution the previous one of the set base pre will be really finalized in the system to exit from the critical section we can use the c function vport exit critical without an argument it can be found in a port.c file and this function is calling the port enable interrupt macro from port macro.h file and this macro is in fact clearing the base pre-mask register so instead this config max syscall interrupt priority we are setting here zero so we are not masking any interrupts and all the interrupt system is fully operational again. Thank you for watching this video.