1e41f4b71Sopenharmony_ci# Software Timer 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Basic Concepts 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ciThe 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. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciDue to the limitation in hardware, the number of hardware timers cannot meet users' requirements. The OpenHarmony LiteOS-A kernel provides the software timer function. 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ciThe software timer allows more timing services to be created, increasing the number of timers. 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ciThe software timer supports the following functions: 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci- Disabling the software timer using a macro 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci- Creating a software timer 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci- Starting a software timer 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci- Stopping a software timer 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci- Deleting a software timer 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci- Obtaining the number of remaining ticks of a software timer 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci## Working Principles 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ciThe 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**. 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ciSoftware 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. For the timers set at the same time, the timer with a shorter value is always closer to the queue head than the timer with a longer value, and is preferentially triggered. 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ciThe software timer counts time in ticks. When a software timer is created and started, the OpenHarmony system 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. 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ciWhen 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. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ciWhen the tick interrupt handler is complete, the software timer task (with the highest priority) will be woken up. In this task, the timeout callback for the recorded timer is called. 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ciA software timer can be in any of the following states: 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci- OS_SWTMR_STATUS_UNUSED 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci The timer is not in use. When the timer module is initialized, all timer resources in the system are set to this state. 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci- OS_SWTMR_STATUS_CREATED 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci 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. 48e41f4b71Sopenharmony_ci 49e41f4b71Sopenharmony_ci- OS_SWTMR_STATUS_TICKING 50e41f4b71Sopenharmony_ci 51e41f4b71Sopenharmony_ci The timer is running (counting). When **LOS_SwtmrStart** is called for a newly created timer, the timer enters this state. 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ciOpenHarmony provides three types of software timers: 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci- One-shot timer: Once started, the timer is automatically deleted after triggering only one timer event. 56e41f4b71Sopenharmony_ci- Periodic timer: This type of timer periodically triggers timer events until it is manually stopped. 57e41f4b71Sopenharmony_ci- One-shot timer deleted by calling an API 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci## Development Guidelines 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci### Available APIs 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ciThe following table describes the APIs of the software timer module of the OpenHarmony LiteOS-A kernel. 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci**Table 1** APIs for software timers 68e41f4b71Sopenharmony_ci 69e41f4b71Sopenharmony_ci| Category | Description | 70e41f4b71Sopenharmony_ci| ---------------------- | ------------------------------------------------------------ | 71e41f4b71Sopenharmony_ci| Creating or deleting a timer | **LOS_SwtmrCreate**: creates a software timer.<br>**LOS_SwtmrDelete**: deletes a software timer.| 72e41f4b71Sopenharmony_ci| Starting or stopping a timer | **LOS_SwtmrStart**: starts a software timer.<br>**LOS_SwtmrStop**: stops a software timer.| 73e41f4b71Sopenharmony_ci| Obtaining remaining ticks of a software timer| **LOS_SwtmrTimeGet**: obtains the remaining ticks of a software timer. | 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci### How to Develop 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ciThe typical development process of software timers is as follows: 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci1. Configure the software timer. 81e41f4b71Sopenharmony_ci - Check that **LOSCFG_BASE_CORE_SWTMR** and **LOSCFG_BASE_IPC_QUEUE** are enabled. 82e41f4b71Sopenharmony_ci - Configure **LOSCFG_BASE_CORE_SWTMR_LIMIT** (maximum number of software timers supported by the system). 83e41f4b71Sopenharmony_ci - Configure **OS_SWTMR_HANDLE_QUEUE_SIZE** (maximum length of the software timer queue). 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci2. Call **LOS_SwtmrCreate** to create a software timer. 86e41f4b71Sopenharmony_ci - Create a software timer with the specified timing duration, timeout handling function, and triggering mode. 87e41f4b71Sopenharmony_ci - Return the function execution result (success or failure). 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ci3. Call **LOS_SwtmrStart** to start the software timer. 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci4. Call **LOS_SwtmrTimeGet** to obtain the remaining number of ticks of the software timer. 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci5. Call **LOS_SwtmrStop** to stop the software timer. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci6. Call **LOS_SwtmrDelete** to delete the software timer. 96e41f4b71Sopenharmony_ci 97e41f4b71Sopenharmony_ci> **NOTE**<br> 98e41f4b71Sopenharmony_ci> 99e41f4b71Sopenharmony_ci> - Avoid too many operations in the callback of the software timer. Do not use APIs or perform operations that may cause task suspension or blocking. 100e41f4b71Sopenharmony_ci> 101e41f4b71Sopenharmony_ci> - 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. 102e41f4b71Sopenharmony_ci> 103e41f4b71Sopenharmony_ci> - 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. 104e41f4b71Sopenharmony_ci> 105e41f4b71Sopenharmony_ci> - 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 is invoked. 106e41f4b71Sopenharmony_ci> 107e41f4b71Sopenharmony_ci> - 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. 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci### Development Example 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci**Prerequisites** 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci- In **los_config.h**, **LOSCFG_BASE_CORE_SWTMR** is enabled. 115e41f4b71Sopenharmony_ci- The maximum number of software timers supported by the system (**LOSCFG_BASE_CORE_SWTMR_LIMIT**) is configured. 116e41f4b71Sopenharmony_ci- The maximum length of the software timer queue (**OS_SWTMR_HANDLE_QUEUE_SIZE**) is configured. 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci**Sample Code** 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ci``` 121e41f4b71Sopenharmony_ci#include "los_swtmr.h" 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_civoid Timer1_Callback(uint32_t arg); 124e41f4b71Sopenharmony_civoid Timer2_Callback(uint32_t arg); 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ciUINT32 g_timercount1 = 0; 127e41f4b71Sopenharmony_ciUINT32 g_timercount2 = 0; 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_civoid Timer1_Callback(uint32_t arg) // Callback function 1 130e41f4b71Sopenharmony_ci{ 131e41f4b71Sopenharmony_ci unsigned long tick_last1; 132e41f4b71Sopenharmony_ci g_timercount1++; 133e41f4b71Sopenharmony_ci tick_last1=(UINT32)LOS_TickCountGet(); // Obtain the current number of ticks. 134e41f4b71Sopenharmony_ci PRINTK("g_timercount1=%d\n",g_timercount1); 135e41f4b71Sopenharmony_ci PRINTK("tick_last1=%d\n",tick_last1); 136e41f4b71Sopenharmony_ci} 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_civoid Timer2_Callback(uint32_t arg) // Callback function 2 139e41f4b71Sopenharmony_ci{ 140e41f4b71Sopenharmony_ci unsigned long tick_last2; 141e41f4b71Sopenharmony_ci tick_last2=(UINT32)LOS_TickCountGet(); 142e41f4b71Sopenharmony_ci g_timercount2 ++; 143e41f4b71Sopenharmony_ci PRINTK("g_timercount2=%d\n",g_timercount2); 144e41f4b71Sopenharmony_ci PRINTK("tick_last2=%d\n",tick_last2); 145e41f4b71Sopenharmony_ci} 146e41f4b71Sopenharmony_ci 147e41f4b71Sopenharmony_civoid Timer_example(void) 148e41f4b71Sopenharmony_ci{ 149e41f4b71Sopenharmony_ci UINT16 id1; 150e41f4b71Sopenharmony_ci UINT16 id2; // timer id 151e41f4b71Sopenharmony_ci UINT32 uwTick; 152e41f4b71Sopenharmony_ci 153e41f4b71Sopenharmony_ci /* Create a one-shot software timer, with the number of ticks set to 1000. Callback 1 will be invoked when the number of ticks reaches 1000. */ 154e41f4b71Sopenharmony_ci LOS_SwtmrCreate (1000, LOS_SWTMR_MODE_ONCE, Timer1_Callback, &id1, 1); 155e41f4b71Sopenharmony_ci 156e41f4b71Sopenharmony_ci /* Create a periodic software timer and invoke callback 2 every 100 ticks. */ 157e41f4b71Sopenharmony_ci LOS_SwtmrCreate(100, LOS_SWTMR_MODE_PERIOD, Timer2_Callback, &id2, 1); 158e41f4b71Sopenharmony_ci PRINTK("create Timer1 success\n"); 159e41f4b71Sopenharmony_ci 160e41f4b71Sopenharmony_ci LOS_SwtmrStart(id1); // Start the one-shot software timer. 161e41f4b71Sopenharmony_ci dprintf("start Timer1 success\n"); 162e41f4b71Sopenharmony_ci LOS_TaskDelay(200); // Delay 200 ticks. 163e41f4b71Sopenharmony_ci LOS_SwtmrTimeGet(id1, &uwTick); // Obtain the number of remaining ticks of the one-short software timer. 164e41f4b71Sopenharmony_ci PRINTK("uwTick =%d\n", uwTick); 165e41f4b71Sopenharmony_ci 166e41f4b71Sopenharmony_ci LOS_SwtmrStop(id1); // Stop the software timer. 167e41f4b71Sopenharmony_ci PRINTK("stop Timer1 success\n"); 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci LOS_SwtmrStart(id1); 170e41f4b71Sopenharmony_ci LOS_TaskDelay(1000); 171e41f4b71Sopenharmony_ci LOS_SwtmrDelete(id1); // Delete the software timer. 172e41f4b71Sopenharmony_ci PRINTK("delete Timer1 success\n"); 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci LOS_SwtmrStart(id2); // Start the periodic software timer. 175e41f4b71Sopenharmony_ci PRINTK("start Timer2\n"); 176e41f4b71Sopenharmony_ci 177e41f4b71Sopenharmony_ci LOS_TaskDelay(1000); 178e41f4b71Sopenharmony_ci LOS_SwtmrStop(id2); 179e41f4b71Sopenharmony_ci LOS_SwtmrDelete(id2); 180e41f4b71Sopenharmony_ci} 181e41f4b71Sopenharmony_ci``` 182e41f4b71Sopenharmony_ci 183e41f4b71Sopenharmony_ci**Output** 184e41f4b71Sopenharmony_ci 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci``` 187e41f4b71Sopenharmony_cicreate Timer1 success 188e41f4b71Sopenharmony_cistart Timer1 success 189e41f4b71Sopenharmony_ciuwTick =800 190e41f4b71Sopenharmony_cistop Timer1 success 191e41f4b71Sopenharmony_cig_timercount1=1 192e41f4b71Sopenharmony_citick_last1=1201 193e41f4b71Sopenharmony_cidelete Timer1 success 194e41f4b71Sopenharmony_cistart Timer2 195e41f4b71Sopenharmony_cig_timercount2 =1 196e41f4b71Sopenharmony_citick_last1=1301 197e41f4b71Sopenharmony_cig_timercount2 =2 198e41f4b71Sopenharmony_citick_last1=1401 199e41f4b71Sopenharmony_cig_timercount2 =3 200e41f4b71Sopenharmony_citick_last1=1501 201e41f4b71Sopenharmony_cig_timercount2 =4 202e41f4b71Sopenharmony_citick_last1=1601 203e41f4b71Sopenharmony_cig_timercount2 =5 204e41f4b71Sopenharmony_citick_last1=1701 205e41f4b71Sopenharmony_cig_timercount2 =6 206e41f4b71Sopenharmony_citick_last1=1801 207e41f4b71Sopenharmony_cig_timercount2 =7 208e41f4b71Sopenharmony_citick_last1=1901 209e41f4b71Sopenharmony_cig_timercount2 =8 210e41f4b71Sopenharmony_citick_last1=2001 211e41f4b71Sopenharmony_cig_timercount2 =9 212e41f4b71Sopenharmony_citick_last1=2101 213e41f4b71Sopenharmony_cig_timercount2 =10 214e41f4b71Sopenharmony_citick_last1=2201 215e41f4b71Sopenharmony_ci``` 216