• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>![](../public_sys-resources/icon-note.gif) **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