1# Software Timer 2 3## Basic Concepts 4 5The software timer is a software-simulated timer based on system tick interrupts. When the preset tick counter value has elapsed, the user-defined callback will be invoked. The timing precision is related to the cycle of the system tick clock. 6 7Due to the limitation in hardware, the number of hardware timers cannot meet users' requirements. Therefore, the OpenHarmony LiteOS-M kernel provides the software timer function. The software timer allows more timing services to be created, increasing the number of timers. 8 9The software timer supports the following functions: 10 11- Disabling the software timer using a macro 12- Creating a software timer 13- Starting a software timer 14- Stopping a software timer 15- Deleting a software timer 16- Obtaining the number of remaining ticks of a software timer 17 18## Working Principles 19 20The software timer is a system resource. When modules are initialized, a contiguous section of memory is allocated for software timers. The maximum number of timers supported by the system is configured by the **LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT** macro in **los\_config.h**. 21 22Software timers use a queue and a task resource of the system. The software timers are triggered based on the First In First Out \(FIFO\) rule. A timer with a shorter value is always closer to the queue head than a timer with a longer value, and is preferentially triggered. 23 24The software timer counts time in ticks. When a software timer is created and started, the OpenHarmony LiteOS-M kernel determines the timer expiry time based on the current system time \(in ticks\) and the timing interval set by the user, and adds the timer control structure to the global timing list. 25 26When a tick interrupt occurs, the tick interrupt handler scans the global timing list for expired timers. If such timers are found, the timers are recorded. 27 28When the tick interrupt handling function is complete, the software timer task \(with the highest priority\) is woken up. In this task, the timeout callback function for the recorded timer is called. 29 30### Timer States 31 32- OS\_SWTMR\_STATUS\_UNUSED 33 34 The timer is not in use. When the timer module is initialized, all timer resources in the system are set to this state. 35 36 37- OS\_SWTMR\_STATUS\_CREATED 38 39 The timer is created but not started or the timer is stopped. When **LOS\_SwtmrCreate** is called for a timer that is not in use or **LOS\_SwtmrStop** is called for a newly started timer, the timer changes to this state. 40 41 42- OS\_SWTMR\_STATUS\_TICKING 43 44 The timer is running \(counting\). When **LOS\_SwtmrStart** is called for a newly created timer, the timer enters this state. 45 46 47### Timer Modes<a name="section137521353175010"></a> 48 49The OpenHarmony LiteOS-M kernel provides three types of software timers: 50 51- One-shot timer: Once started, the timer is automatically deleted after triggering only one timer event. 52- Periodic timer: This type of timer periodically triggers timer events until it is manually stopped. 53- One-shot timer deleted by calling an API 54 55## Available APIs 56 57The following table describes APIs available for the OpenHarmony LiteOS-M software timer module. For more details about the APIs, see the API reference. 58 59**Table 1** Software timer APIs 60 61<a name="table14277123518139"></a> 62<table><thead align="left"><tr id="row152771935131315"><th class="cellrowborder" valign="top" width="17.77177717771777%" id="mcps1.2.4.1.1"><p id="p1127733591316"><a name="p1127733591316"></a><a name="p1127733591316"></a>Function</p> 63</th> 64<th class="cellrowborder" valign="top" width="23.782378237823785%" id="mcps1.2.4.1.2"><p id="p22771357138"><a name="p22771357138"></a><a name="p22771357138"></a>API</p> 65</th> 66<th class="cellrowborder" valign="top" width="58.44584458445845%" id="mcps1.2.4.1.3"><p id="p327714358130"><a name="p327714358130"></a><a name="p327714358130"></a>Description</p> 67</th> 68</tr> 69</thead> 70<tbody><tr id="row159539510586"><td class="cellrowborder" rowspan="2" valign="top" width="17.77177717771777%" headers="mcps1.2.4.1.1 "><p id="p1194410585810"><a name="p1194410585810"></a><a name="p1194410585810"></a>Creating or deleting timers</p> 71</td> 72<td class="cellrowborder" valign="top" width="23.782378237823785%" headers="mcps1.2.4.1.2 "><p id="p10944105115814"><a name="p10944105115814"></a><a name="p10944105115814"></a>LOS_SwtmrCreate</p> 73</td> 74<td class="cellrowborder" valign="top" width="58.44584458445845%" headers="mcps1.2.4.1.3 "><p id="p9944105175818"><a name="p9944105175818"></a><a name="p9944105175818"></a>Creates a software timer.</p> 75</td> 76</tr> 77<tr id="row17953454580"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p094419505814"><a name="p094419505814"></a><a name="p094419505814"></a>LOS_SwtmrDelete</p> 78</td> 79<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p39445585817"><a name="p39445585817"></a><a name="p39445585817"></a>Deletes a software timer.</p> 80</td> 81</tr> 82<tr id="row79531357589"><td class="cellrowborder" rowspan="2" valign="top" width="17.77177717771777%" headers="mcps1.2.4.1.1 "><p id="p139443595820"><a name="p139443595820"></a><a name="p139443595820"></a>Starting or stopping timers</p> 83</td> 84<td class="cellrowborder" valign="top" width="23.782378237823785%" headers="mcps1.2.4.1.2 "><p id="p1894435175815"><a name="p1894435175815"></a><a name="p1894435175815"></a>LOS_SwtmrStart</p> 85</td> 86<td class="cellrowborder" valign="top" width="58.44584458445845%" headers="mcps1.2.4.1.3 "><p id="p1194415518581"><a name="p1194415518581"></a><a name="p1194415518581"></a>Starts a software timer.</p> 87</td> 88</tr> 89<tr id="row1095320545814"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p20944355589"><a name="p20944355589"></a><a name="p20944355589"></a>LOS_SwtmrStop</p> 90</td> 91<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p169441515816"><a name="p169441515816"></a><a name="p169441515816"></a>Stop a software timer.</p> 92</td> 93</tr> 94<tr id="row119525513581"><td class="cellrowborder" valign="top" width="17.77177717771777%" headers="mcps1.2.4.1.1 "><p id="p109442053586"><a name="p109442053586"></a><a name="p109442053586"></a>Obtaining remaining ticks of a software timer</p> 95</td> 96<td class="cellrowborder" valign="top" width="23.782378237823785%" headers="mcps1.2.4.1.2 "><p id="p9944354585"><a name="p9944354585"></a><a name="p9944354585"></a>LOS_SwtmrTimeGet</p> 97</td> 98<td class="cellrowborder" valign="top" width="58.44584458445845%" headers="mcps1.2.4.1.3 "><p id="p39441257586"><a name="p39441257586"></a><a name="p39441257586"></a>Obtaining remaining ticks of a software timer</p> 99</td> 100</tr> 101</tbody> 102</table> 103 104## How to Develop 105 106The typical development process of software timers is as follows: 107 1081. Configure the software timer. 109 - Check that **LOSCFG\_BASE\_CORE\_SWTMR** and **LOSCFG\_BASE\_IPC\_QUEUE** are set to **1**. 110 - Configure **LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT** \(maximum number of software timers supported by the system\). 111 - Configure **OS\_SWTMR\_HANDLE\_QUEUE\_SIZE** \(maximum length of the software timer queue\). 112 1132. Call **LOS\_SwtmrCreate** to create a software timer. 114 - Create a software timer with the specified timing duration, timeout handling function, and triggering mode. 115 - Return the function execution result \(success or failure\). 116 1173. Call **LOS\_SwtmrStart** to start the software timer. 1184. Call **LOS\_SwtmrTimeGet** to obtain the remaining number of ticks of the software timer. 1195. Call **LOS\_SwtmrStop** to stop the software timer. 1206. Call **LOS\_SwtmrDelete** to delete the software timer. 121 122> **NOTE**<br/> 123>- Avoid too many operations in the callback function of the software timer. Do not use APIs or perform operations that may cause task suspension or blocking. 124>- The software timers use a queue and a task resource of the system. The priority of the software timer tasks is set to **0** and cannot be changed. 125>- The number of software timer resources that can be configured in the system is the total number of software timer resources available to the entire system, not the number of software timer resources available to users. For example, if the system software timer occupies one more resource, the number of software timer resources available to users decreases by one. 126>- If a one-shot software timer is created, the system automatically deletes the timer and reclaims resources after the timer times out and the callback function is executed. 127>- For a one-shot software timer that will not be automatically deleted after expiration, you need to call **LOS\_SwtmrDelete** to delete it and reclaim the timer resource to prevent resource leakage. 128 129## Development Example 130 131### Example Description 132 133The following programming example demonstrates how to: 134 1351. Create, start, delete, pause, and restart a software timer. 1362. Use a one-shot software timer and a periodic software timer 137 138### Sample Code 139 140Prerequisites 141 142- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR** is enabled. 143- In **los\_config.h**, **LOSCFG\_BASE\_CORE\_SWTMR\_ALIGN** is disabled. The sample code does not involve timer alignment. 144- The maximum number of software timers supported by the system \(**LOSCFG\_BASE\_CORE\_SWTMR\_LIMIT**\) is configured. 145- The maximum length of the software timer queue \(OS\_SWTMR\_HANDLE\_QUEUE\_SIZE\) is configured. 146 147The sample code is as follows: 148 149``` 150#include "los_swtmr.h" 151 152/* Timer count */ 153UINT32 g_timerCount1 = 0; 154UINT32 g_timerCount2 = 0; 155 156/* Task ID*/ 157UINT32 g_testTaskId01; 158 159void Timer1_Callback(UINT32 arg) //Callback function 1 160{ 161 UINT32 tick_last1; 162 g_timerCount1++; 163 tick_last1 = (UINT32)LOS_TickCountGet(); // Obtain the current number of ticks. 164 printf("g_timerCount1=%d, tick_last1=%d\n", g_timerCount1, tick_last1); 165} 166 167void Timer2_Callback(UINT32 arg) //Callback function 2 168{ 169 UINT32 tick_last2; 170 tick_last2 = (UINT32)LOS_TickCountGet(); 171 g_timerCount2++; 172 printf("g_timerCount2=%d tick_last2=%d\n", g_timerCount2, tick_last2); 173} 174 175void Timer_example(void) 176{ 177 UINT32 ret; 178 UINT32 id1; // timer id1 179 UINT32 id2; // timer id2 180 UINT32 tickCount; 181 182 /* Create a one-shot software timer, with the number of ticks set to 1000. When the number of ticks reaches 1000, callback function 1 is executed. */ 183 LOS_SwtmrCreate(1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); 184 185 /* Create a periodic software timer and execute callback function 2 every 100 ticks. */ 186 LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); 187 printf("create Timer1 success\n"); 188 189 LOS_SwtmrStart(id1); // Start the one-shot software timer. 190 printf("start Timer1 success\n"); 191 192 LOS_TaskDelay(200); // Delay 200 ticks. 193 LOS_SwtmrTimeGet(id1, &tickCount); // Obtain the number of remaining ticks of the one-short software timer. 194 printf("tickCount=%d\n", tickCount); 195 196 LOS_SwtmrStop(id1); // Stop the software timer. 197 printf("stop Timer1 success\n"); 198 199 LOS_SwtmrStart(id1); 200 LOS_TaskDelay(1000); 201 202 LOS_SwtmrStart(id2); // Start the periodic software timer. 203 printf("start Timer2\n"); 204 205 LOS_TaskDelay(1000); 206 LOS_SwtmrStop(id2); 207 ret = LOS_SwtmrDelete(id2); // Delete the software timer. 208 if (ret == LOS_OK) { 209 printf("delete Timer2 success\n"); 210 } 211} 212 213UINT32 Example_TaskEntry(VOID) 214{ 215 UINT32 ret; 216 TSK_INIT_PARAM_S task1; 217 218 /* Lock task scheduling. */ 219 LOS_TaskLock(); 220 221 /* Create task 1. */ 222 (VOID)memset(&task1, 0, sizeof(TSK_INIT_PARAM_S)); 223 task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Timer_example; 224 task1.pcName = "TimerTsk"; 225 task1.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; 226 task1.usTaskPrio = 5; 227 ret = LOS_TaskCreate(&g_testTaskId01, &task1); 228 if (ret != LOS_OK) { 229 printf("TimerTsk create failed.\n"); 230 return LOS_NOK; 231 } 232 233 /* Unlock task scheduling. */ 234 LOS_TaskUnlock(); 235 236 return LOS_OK; 237} 238``` 239 240### Verification 241 242The output is as follows: 243 244``` 245create Timer1 success 246start Timer1 success 247tickCount=798 248stop Timer1 success 249g_timerCount1=1, tick_last1=1208 250delete Timer1 sucess 251start Timer2 252g_timerCount2=1 tick_last2=1313 253g_timerCount2=2 tick_last2=1413 254g_timerCount2=3 tick_last2=1513 255g_timerCount2=4 tick_last2=1613 256g_timerCount2=5 tick_last2=1713 257g_timerCount2=6 tick_last2=1813 258g_timerCount2=7 tick_last2=1913 259g_timerCount2=8 tick_last2=2013 260g_timerCount2=9 tick_last2=2113 261g_timerCount2=10 tick_last2=2213 262delete Timer2 success 263``` 264 265