 Hello, in this part we will have a look how we can activate and use tickless mode in practice. Now let's have a look how we can activate and use tickless mode in practice. On the next slides there is a step by step guide how to make a tickless mode example. We will need for this exercise multimeter with microamper range to measure the current consumption or XNUCLEO LPM01A board with cube monitor power application installed on your PC. An application will be done using STM32Cube IDE toolchain, but it can be easily done within STM32Cube MX and the toolchain supported by this tool as well. Within this example we will use NUCLEO L476RG boards, but it can be easily ported to any other STM32 based board. Let's start from STM32Cube IDE or STM32Cube MX tools. We can reuse any of previous 3R2S examples or create a new one for selected MCU. We will start with 3R2S configuration. For this exercise we would need only one single task, with priority set to OS priority normal, the stack size 256 and entry function start task 1. Within 3R2S config parameters please enable use tickless idle by selecting built-in functionality enabled. What is the difference between available options there? Option one already selected built-in functionality enabled is generating automatically macros config press sleep processing and config post sleep processing within 3R2S config.h file and assigned to those functions press sleep processing and post sleep processing within 3R2S.c file. And those functions can be filled in by the user. While within the option to user functionality enabled user needs to prepare the code by himself. Within our example we will use low power timer as a timer which will work in background while we are in low power mode. It will be configured to 1 kHz and it will be sourced by LSE crystal 32 kHz which is present on a Nucleo L476 RG board. Within SDM32CubeID or SDM32CubeMix please go to timers lptim1 section and within this section please select lptim mode to counts internal clock events. Then within parameter settings please select clock prescalar to prescalar divided by 32. We need to enable interrupt on low power timer 1 within NVIC settings. The rest of the settings will keep in default state. We need to enable LSE clock source for low power timer. Within pinout and configuration please select system category then select RCC so reset clock configuration section and then within low speed clock LSE please select crystal ceramic resonator. Then please go to the clock configuration tab and select LSE as a clock source for low power timer 1 keeping MSI based 4 MHz as a default system clock. After this we can generate the code. Within SDM32CubeID it is enough to save the changes by CTRL S. Within SDM32CubeMix please click generate code button. Once the code is generated please open a main.c file for further operations. We will start with task code processing. Please go to start task 1 function body. We will not use an initialization code there. Within the task infinite loop we will perform the following operations. We will go to blocked state for 5 seconds. It will be time dedicated for tickless mode. Then we will toggle the LED or send 1 over SWO as our sign of life after wake up. It can be done by calling the task action function or a simple LED toggling function from HAL library. After this operation we will try to remain half of the second using the simple HAL delay function. It will keep our task in run mode as it will be only one apart of the idle task. In this example we will use single wire output SWO additional pin available within SWD debug interface to send data over instrumentation trace Microsoft ITM. For simplification our function will accept single character and will return nothing. Please add a following function declaration. Then within user code begin for section please insert task action function body. Function will accept only one 8-bit argument and will return nothing. Inside we will use ITM underscore send char function to send one character passed by arguments and additionally we will add a sign of new line. Depending on the version of STM32QPID or STM32QBemix and libraries you will use for the code generation. You may face a different implementation of config, press, slip, processing and config, post, slip, processing macros. Those macros are defined within freeRTOS config.h file and the simplest configuration is just empty configuration which allows you to implement your own press, slip and post, slip, processing functions within freeRTOS.c file. Sometimes you may face a bit more complex definition within this configuration file freeRTOS config.h. So in this case what I would recommend to you to complete this exercise or in general this series of exercises of tickless mode to replace it with this simplest configuration which you can see on the screen. In the next step we'll switch to freeRTOS.c file. At the beginning we need to make low power timer handler visible within this file. This is why we need this extern declaration at the beginning. Please remember that we need to put all of our code within the other code sections. Then we need to prepare application to enter into low power mode. It will be done within press, slip, processing function. At the beginning we suspend the hull timebase by calling hir underscore suspend tick function. In our exercises it will suspend timer 6 which is the timebase for our hardware abstraction layer library. In the second step we need to start low power timer 1 in interrupt mode using hir underscore lptim underscore timeout underscore start underscore it function with three arguments. Low power timer 1 handler then maximum possible period of this timer set to ff ff hexadecimal and an expected idle time to wake up the system given in milliseconds. The last argument is calculated based on the system clock and tick timer in this case stm-32c stick to not overflow it. So in our example the maximum expected idle time should not be more than 4194 milliseconds. In case all of the active tasks are sent to blocked states for a longer time so like in our example 5000 milliseconds so we can observe intermediate wake up of the system so after these 4194 milliseconds and entering into low power mode again for the remaining sleeping time it is handled automatically by the free r2s tickless mode implementation but it is clearly visible when we are observing the current flow over the time on our application. Next step within free r2s.c file is to prepare the application to exit from low power mode it should be done within post-sleep processing function in two steps. Step one within this step will stop low power timer by calling function hl underscore lptim underscore timeout underscore stop underscore it with the handler to low power timer 1 as an orderly argument and then within step 2 we will enable the time base timer for hl library in our case it is timer 6 by calling hl underscore resume tick function. After this we can compile the code and start the debug session then we stop the debug session to allow our application working on the board. Within this our application should work in the following way at the beginning the task is going into the blocked state for five seconds calling os delay function it allows us to use the tickless mode so idle task is starting the tickless mode for maximum five seconds and then after those five seconds operating system would be woken up by low power timer 1 and our active task will continue its execution so it will perform the operation of task action so it can be either the led toggling or sending something over the swo interface. After this short action there would be as well the delay of half a second by calling hl underscore delay function just to keep our task in run mode for half a second. After this there is would be another iteration of our active task and sending the task again to the blocked state for five seconds. Let's verify it we can connect our multimeter to jp6 jumper on nucleo l476rg or to connect it to x nucleo lpm 01a board then we can monitor the current consumption based on application we just compiled and programmed into the board this is our next step and on the next slides i would present how we can do it within x nucleo and what would be the final result let's start from our hardware setup within our current measurement experiments we will use the following configuration x nucleo lpm 01a board with micro usb cable to connect this board to pc so this is this big board on the screen on the left side of the on the nucleo then as a target board we will use nucleo l476 rg board with mini usb cable to connect it to pc so this is on the right side of the photo we need as well two wires to connect x nucleo board with our target nucleo l476 like you can see on the slide please connect one wire between pin one of cn14 at x nucleo board this is this cn14 this is white connector on the left side of the display with gnd pin on nucleo l476 so this is this black wire which we can see on the screen and then please connect pin three of cn14 of x nucleo with pin two of jp6 of nucleo connector what you can see on the screen this is marked on using the red wire then instead of no x nucleo you can use of course the meter in this case please connect the meter on jp6 instead of existing jumper the best is to use the meter with the current range below one micro amp on the next slide i would present how we can configure the application which is cooperating with x nucleo board this application is stm32 cube monitor power which should be installed on your pc okay let's focus on the software so this is the configuration in case you are using x nucleo board to measure the current consumption profile within our target board so once you run the stm32 cube monitor power application and before you perform the connection of both boards to pc you should see the possibility of selecting the board with an stm32 cube monitor power there is a connect select board field if you press on it you should see available comports which are detected by the application so please select the comport assigned to x nucleo lpm01 board on our example there is com21 then please press take control button it can take some time and then within the configuration please select 100 kHz sampling frequency then infinite acquisition time and we are ready for starting the measurements to start measurements please start acquisition button and to stop measurements please press stop acquisition button in between you can see on the screen the data which are collected from the board via x nucleo shield and you can see that the current consumption measurement in time here is the example of slip mode used within tickless mount the picture is coming from stm32 cube monitor power application working with x nucleo lpm01a board powering nucleo l476 rg board at the beginning we can see the run state then the task is going to block state for five seconds by call of osd live with 5000 as an argument in this case stm32 is in a slip mode and all of the tasks are in a blocked state and as you can see these five seconds it's not exactly five seconds it is divided into two parts the first one is more or less 4194 milliseconds where we can see the first wake up event this source of this wake up event is the protection of the cystic timer from being overflowed while it is being frozen during the tickless mode if we take into the consideration that cystic is 24-bit long timer and our system clock is set to four megahertz the overflow of this timer will occur just after 4194 milliseconds this is why when you request the slip time longer than this time it is saturated to this value to this maximum value so in fact how underscore low power timer timeout start it function is called with third argument not five thousand like we were thinking about it but four thousand one hundred ninety four this value is calculated within the code of tickless mode so after this first period this more or less four thousand milliseconds the system is running idle task again after wake up all of other active tasks are still in blocked state for more or less one second more so within this idle task system is entering into low power mode again for a remaining part of this requested five thousand milliseconds so after the complete five seconds elapses and there is a wake up from slip mode done by low power timer one again and our active task is moved from blocked state to run state and it is performing its code execution so further code execution after this is delay so the first instruction is a task action which can be the LED toggling or sending something over the communication interface like swo and then after this there is a call to how underscore delay with five hundred as an argument so it is keeping our task in a run mode for half a second as it is the only task there would be no context which in between after this half a second that task is calling again the first instruction from its endless loop so this is always delay with a five thousand as an argument it is again sending this task into the blocked state for the five seconds and it is starting the tickless mode with an idle task as you can see the slip mode is not giving too much current reduction thus it would be good to replace it with any of stop modes it will be our next step slip mode is only phrasing the code execution so the current consumption saving is not that significant much better result we can have using stop modes instead within stop modes at stm32 all high frequency oscillators are stopped while content of all of the registers and RAM is still kept change slip mode into stop low power mode within tickless mode at free r2s we need to do some modifications within vport suppress ticks and slip function at port dot c file the change location is between execution of config press slip processing and config post slip processing macros like on this example on the left side we can see the default configuration for slip usage activated by wfi instruction on the right side there is a proposal of reconfiguration to use stop one mode instead first please include main dot h file at the beginning of port dot c file then comment out the line which restarts cystic further instead of the line with wfi call please insert the line with chwood start stop mode like h al underscore pwr ex enter stop one mode with an argument of wfi sn entry mode after those modifications please compile the code start the debug session start the code execution and stop debug session again we can connect multimeter or x nucleo lpm 01a board to measure the current consumption please reset at the board and observe the current consumption flow in time using stm32 cube monitor power application on your pc what would be the visible effect after those operations we will enter into selected low power mode for the time where there would be no active task in our example it will be five seconds after this active task will change led state or it will send one over swo and remains active for half a second by calling simple function h al underscore delay you can check the effect using different stop modes stop zero stop one and stop two and compare the results here is the example of stop one mode the picture is coming from stm32 cube monitor power application working with x nucleo lpm 01a board powering nucleo l476 rg board here on the picture we can see an intermediate wake up events within five seconds low power mode after more or less 4194 milliseconds we can see a wake up event which is caused by the protection of the cystic timer from being overflowed i have described it with an observation of slip mode usage within tickless mode few slides before so after complete five seconds of stop mode we can see a wake up event and sending one over swo so it is an execution of task action code within task function body and then after this there is a call to hull delay function with 500 as an argument to keep our active task in run mode for additional half a second then there is a next iteration of the task function and there is a call to all s delay with 5000 as an argument what is sending back the task to blocked state and giving the space for idle task so the tickless mode can be run again for additional five seconds which would be divided again into two parts the first one for after 4194 milliseconds and the second one will be the remaining part of declared 5000 milliseconds here is similar example of stop one mode usage but in this case we are using led instead of swo so just to demonstrate to you that it is important to reconfigure the i o lines before entering the low power mode as i o reconfiguration is not done automatically during or before entering into stop modes it should be done by the user manually so let's come back to the picture we can see here the five seconds of stop one mode again divided into two parts the first one is 4194 milliseconds and it's caused by the protection of the cystic timer against being overflowed and then the remaining part of declared 5000 milliseconds is again the system is again in stop one mode it has been described already with an observation of slip mode to use search with an tickless mode few slides before so after the system is woken up we can see that within the activity of the task the led is turned on and then we can see the cal delay code execution so we can see this highest higher current consumption for more or less half of the second the task is at the time in the let's say run mode the complete system is woken up after this half a second the task is executing again the function os delay with 5000 as an argument so the system is going into the tickless mode again but even if it's declared as a stop one mode we cannot see too much current reduction due to the fact that led is still on so we can see that there is a current drop but not that much so led is still on even if we are in stop mode so again we can see 4194 millisecond part of it then there is intermediate wake up for a while and then there is a continuity to have in total 5000 milliseconds so five seconds of stop one mode with led on after this the task is woken up again by the low power timer we can see that within this task the led is turned off so the current is dropping drastically then there is a hard delay call for half a second so this is why we can see this activity of the task for more or less half a second then after this the task is calling os delay function with 5000 milliseconds again so we can see drastic drop of the current because the system is in a stop mode and the ios are in a safe configuration so there is no high current consumption caused by the io lines here is the comparison of the current consumption across different stop modes while using tickless mode those are the results while the complete system is in a stop mode for stop zero we reached around 600 microamps for stop one it is seven microamps and for stop two it is possible to go down to three microamps let's add some other operating system component like binary semaphore to observe under wake up possibilities as you remember before entering into tickless mode there is an estimation done concerning maximum time we could spend in low power mode of course it is not taking into the consideration asynchronous events like interrupts where we can expect some semaphors or cues actions which may unblock our blocked tasks as well let's modify our example so we can use an existing button blue button in our case in external interrupt mode to give release the semaphore we need to modify our task so instead of os delay with 5000 as an argument we would wait maximum five seconds for the semaphore so instead os delay 5000 we need to use the function os semaphore acquire with the timeout of 5000 this effect final effect would be exactly the same so let's start from the configuration with an stm-32 cube mix or cube ide within the project we just played with we will just configure pc13 as gpio underscore xti 13 just to remind you please click the left mouse button over pc13 pin and select gpio underscore xt13 from the list then within gpio peripherals go to nvictab and enable external line 15 to 10 its interrupts the last step is assigning the interrupt to operating system interrupts which are allowed to execute free rts functions to do this we'll set preemption priority to five for this interrupt to be less or equal to config library max syscall interrupt priority parameter which is set to five within free rts config dot h file next point is to create a simple binary semaphore please go to free rts configuration then please select timers and semaphore tab within binary semaphore group click on add to create a new binary semaphore please keep all default values with a new semaphore creation window to save the time and press ok after this a new binary semaphore should appear on the list within free rts configuration window let's save the project generate the code and open main dot c file within main dot c file we need to add a callback for external interrupt and place there the function to release the semaphore please have a look that within cmcs underscore os there is no visible distinguish between os functions called from the task and called from the interrupts property selection is done within cmcs underscore os layer the prototype of the external interrupt callback can be found within hal underscore gpio module and can be tracked from stm32 l4 xx underscore it dot c file from external interrupt procedure generated by stm32 cube mx or stm32 cube ide the next change is a replacement of the os delay with 5000 as an argument with wait for semaphore function for this we will use os semaphore acquire function first argument is a handler to our newly created semaphore the second argument is a maximum timeout we will wait for this semaphore this function will wait for the semaphore keeping the task in a blocked state for maximum 5000 milliseconds if semaphore would be released earlier function will immediately finish its execution and task function will execute the next line which is task action it can be LED toggling or sending something over swo like in our example if semaphore will be not released within 5000 milliseconds the function will exit with the timeout error code and will execute task action function as well so this is important to monitor the return value of this os semaphore acquire to check whether the semaphore has been acquired or not in our case it doesn't matter because we just need to check the possibilities of waking up the complete system from the interrupt from releasing the semaphore hal delay 500 function at the end of the loop within the task function you see keeping our task in run mode for half a second like before as the regeneration of the code with an stm-32 cube a mixer stm-32 cube ide is removing all of the modifications done outside user code we need to repeat port dot c file modification so again we need to add include main dot h file at the beginning to see the hull functions from this port dot c file then we need to comment out the restart of the cystic and at the end we need to replace the wfi instruction with hir underscore pwr ex ender stop one mode with wfi as an argument so like in our previous example after those modifications please compile the code start debug session start code execution and stop a debug session then we can connect our multimeter or x nucleo lpm 01 board to measure the current consumption while the application is working please reset the board and observe the current consumption flow in time here we can see the situation when we have released the semaphore from the interrupt which is our blue button before the specified time outlapsed at the beginning system is in stop mode and just after nine seconds system is woken up our only active task task one is moved from blocked to run state and this task is woken up as a specified timeout elapsed with an os semaphore acquire function then with an run mode task is sending one over swo and then it is waiting half a second calling function hull delay to be active state for this half a second then there is another iteration of task one function so the task is calling again os semaphore acquire function with 5000 as an argument so this function will be waiting for the semaphore for maximum five seconds as the result of this the task is moved again to the blocked state and the system is put into stop one mode with an idle task code then after the two seconds of waiting we are pressing the blue button so it wakes up the system then within the interrupt routine the semaphore is given the interrupt routine of the front button the semaphore is given what causes unblocking of task one then task one a function body is executed again starting from task action so sending one over swo like before and then hull delay is executed so the task is remains active for another half a second and there is another iteration of this task one function body so there is a call to os semaphore acquire again it causes sending of task one to blocked state again and starting stop one mode please notice that our five seconds wait is divided into two parts like in previous examples due to the fact that there is a protection of cystic timer against being overflowed it has been described already with an observation of sleep mode usage with anti-class mode few slides before so as you can see there are two parts the first one is ending up more or less at a time of 4194 milliseconds which is the maximum timeout of the cystic and then the remaining part is just the difference between expected 5000 milliseconds and this cystic overflow value thank you for watching this video