Abstract: This article through the analysis of hongmeng light kernel timer module source code, master the difference in the use of timer.

This article is shared from huawei cloud community “Hongmeng light kernel M core source code analysis series 14 software timer Swtmr”, author: Zhushy.

SoftwareTimer is a timer based on the interruption of system Tick clock and simulated by software. When the specified Tick number is passed, user-defined callback functions are triggered. Hardware timers are limited by hardware, and the number of timers is insufficient to meet user requirements. Hongmeng light kernel provides software timer function can provide more timers to meet user needs.

This article through the analysis of hongmeng light kernel timer module source code, master the difference in the use of timer. The source code in this article, using the OpenHarmonyLitEOS-M kernel as an example, is available on the open source site gitee.com/openharmony… To obtain.

Next, we look at the timer structure, timer initialization, timer common operation of the source code.

1. Timer structure definition and common macro definition

1.1 Timer Structure Definition

The timer control block structure defined in kernel\include\los_swtmr.h is SWTMR_CTRL_S. The structure source code is as follows. Timer status: ucState Specifies the value OS_SWTMR_STATUS_UNUSED, OS_SWTMR_STATUS_CREATED, or OS_SWTMR_STATUS_TICKING, Timer mode Mode Value LOS_SWTMR_MODE_ONCE, LOS_SWTMR_MODE_PERIOD, or LOS_SWTMR_MODE_NO_SELFDELETE. Other structure members are explained in the comments section.

typedef struct tagSwTmrCtrl { struct tagSwTmrCtrl *pstNext; */ UINT8 ucState; /* Timer state, enumerated value SwtmrState */ UINT8 ucMode; / / #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) UINT8 ucRouses; /* UINT8 ucSensitive; /* Alignment switch */ # ENDIF UINT32 usTimerID; /* Timer Id */ UINT32 uwCount; /* Number of timer times */ UINT32 uwInterval; /* Period timer timeout interval (unit: tick) */ UINT32 uwArg; /* Timer timeout callback */ SWTMR_PROC_FUNC pfnHandler; /* Timer timeout callback */ SortLinkList stSortList; /* timer sort list */} SWTMR_CTRL_S;Copy the code

In addition, we define a separate structure SwtmrHandlerItem for the callback function and its parameters, as follows:

typedef struct { SWTMR_PROC_FUNC handler; /**< UINTPTR arg; /**< timer timeout callback parameter */} SwtmrHandlerItem;Copy the code

1.2 Common macro definitions for timers

OS_SWT_FROM_SID specifies the macros to obtain the timer control block from the kernel/include/los_swtmr.h file.

#define OS_SWT_FROM_SID(swtmrId)    ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrId) % LOSCFG_BASE_CORE_SWTMR_LIMIT))
Copy the code

There are several enumerations of timers defined in the header:

Enum SwtmrState {OS_SWTMR_STATUS_UNUSED, /**< Timer unused */ OS_SWTMR_STATUS_CREATED, Have created * * * < / timer/OS_SWTMR_STATUS_TICKING / * * < timer timing * /}; #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) enum enSwTmrRousesType { OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ROUSES_ALLOW, OS_SWTMR_ROUSES_ALLOW, Enum ENSWTMRALIGN_SENSITIVE {OS_SWTMR_ALIGN_SENSITIVE, /* Timers are insensitive */ OS_SWTMR_ALIGN_SENSITIVE, /* Timers are insensitive */}; # enDIf enum EnSwTmrType {LOS_SWTMR_MODE_ONCE, /* Timer, the value is 0. */ LOS_SWTMR_MODE_PERIOD, /* Timer, The value is 1. */ LOS_SWTMR_MODE_NO_SELFDELETE, /* The one-time timer will not be self-deleted. The value is 2 */ LOS_SWTMR_MODE_OPP, /* After the one-time timer is complete, the periodic timer is enabled. This mode is not supported. The value is 3 */};Copy the code

2. Initialize the timer

Timers are enabled by default in the kernel and can be disabled by using the macro LOSCFG_BASE_CORE_SWTMR. When the timer is enabled, OsSwtmrInit() is called in kernel\ SRC \los_init.c to initialize the timer module during system startup. Next, let’s take a look at the timer initialization code.

At ⑴ if timer alignment macro LOSCFG_BASE_CORE_SWTMR_ALIGN is enabled, clear g_swtmrAlignID array. The number of timers is defined by the macro LOSCFG_BASE_CORE_SWTMR_LIMIT (2), which calculates the amount of memory required by the timer pool, and then allocates memory for the timer. If the request fails, an error is returned. Initialize g_swtmrFreeList, maintain unused timers. Cycle each timer to initialize, specify the index timerId for each timer node, and the timer control block points to the next timer control block.

OS_SWTMR_HANDLE_QUEUE_SIZE specifies the number of timers LOSCFG_BASE_CORE_SWTMR_LIMIT. The maximum sizeof the message contents is sizeof(SwtmrHandlerItem). The timer queue reads the write message to see what the message is. The OsSwtmrTaskCreate() function is called at ⑸ to create the timer task. The timer task has the highest priority. The entry function of the task is OsSwtmrTask(), which will be analyzed later. ⑹ initialization timer sort linked list, source analysis series before the article analysis, you can read the next sort of linked list data structure chapter. ⑺ Registers the timer scan function OsSwtmrScan.

LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) { UINT32 size; UINT16 index; UINT32 ret; #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) // Ignore the return code when matching CSEC rule 6.6(1). ⑴ (VOID)memset_s(VOID)  *)g_swtmrAlignID, sizeof(SwtmrAlignData) * LOSCFG_BASE_CORE_SWTMR_LIMIT, 0, sizeof(SwtmrAlignData) * LOSCFG_BASE_CORE_SWTMR_LIMIT); #endif ⑵ size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT; SWTMR_CTRL_S *swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); if (swtmr == NULL) { return LOS_ERRNO_SWTMR_NO_MEMORY; } // Ignore the return code when matching CSEC rule 6.6(3). (VOID)memset_s((VOID *) SWTMR, size, 0, size); g_swtmrCBArray = swtmr; (3) g_swtmrFreeList = SWTMR; swtmr->usTimerID = 0; SWTMR_CTRL_S *temp = swtmr; swtmr++; for (index = 1; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { swtmr->usTimerID = index; temp->pstNext = swtmr; temp = swtmr; } ⑷ ⑷ ret = LOS_QueueCreate((CHAR *)NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_SWTMRHandLERQueue, 0, sizeof(SwtmrHandlerItem)); if (ret ! = LOS_OK) { (VOID)LOS_MemFree(m_aucSysMem0, swtmr); return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED; } ⑸ ⑸ ret = OsSwtmrTaskCreate(); if (ret ! = LOS_OK) { (VOID)LOS_MemFree(m_aucSysMem0, swtmr); return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED; } g_swtmrSortLinkList = OsGetSortLinkAttribute(OS_SORT_LINK_SWTMR); if (g_swtmrSortLinkList == NULL) { (VOID)LOS_MemFree(m_aucSysMem0, swtmr); return LOS_NOK; } ret = OsSortLinkInit(g_swtmrSortLinkList); if (ret ! = LOS_OK) { (VOID)LOS_MemFree(m_aucSysMem0, swtmr); return LOS_NOK; } ⑺ ret = OsSchedSwtmrScanRegister((SchedScan)OsSwtmrScan); if (ret ! = LOS_OK) { (VOID)LOS_MemFree(m_aucSysMem0, swtmr); return LOS_NOK; } return LOS_OK; }Copy the code

Again, the entry function for the timer task is OsSwtmrTask(). ⑴ For permanent loop, queue can not read data will block, because the priority is relatively high, timer queue data when the task will be executed. Put pointer address &swtmrHandle, read sizeof(SwtmrHandlerItem). After a successful read, the timer callback function and its parameters are obtained, and then the timer callback function is executed at ⑵. Record the execution time of the timer callback function, and judge whether the execution time times out. If it does, print a warning message.

LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) { SwtmrHandlerItem swtmrHandle; UINT32 readSize; UINT32 ret; UINT64 tick; readSize = sizeof(SwtmrHandlerItem); for (;;) {⑴ ret = LOS_QueueReadCopy(g_swtmrHandlerQueue, &swtMRHandle, &readSize, LOS_WAIT_FOREVER); if ((ret == LOS_OK) && (readSize == sizeof(SwtmrHandlerItem))) { if (swtmrHandle.handler == NULL) { continue; } tick = LOS_TickCountGet(); 2 swtmrHandle. Handler (swtmrHandle. Arg); tick = LOS_TickCountGet() - tick; If (tick >= SWTMR_MAX_RUNNING_TICKS) {PRINT_WARN("timer_handler(%p) cost too many ms(%d)\n", swtmrHandle.handler, (UINT32)((tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND)); }}}}Copy the code

3. Common operation of timer

3.1 Creating timers

Let’s examine the code that creates the timer function LOS_SwtmrCreate(). Forget about timer alignment with LOSCFG_BASE_CORE_SWTMR_ALIGN. Interval is the timer interval, mode is the created timer mode, handler and arg are the timer callback functions and their parameters. SwtmrId is the timer number.

(1) Verify the timer timeout interval, timer mode, callback function and timer number of the incoming parameters. (2) Check whether the idle timer pool is empty. If it is empty, an error message is displayed and the timer cannot be created. ⑶ if the timer is not empty, the timer control block SWTMR is obtained. (4) initialize the timer control block information. At ⑸ initialize the responseTime of the timer sequencing linked list node to -1.

#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT32 *swtmrId, UINT32 arg, UINT8 rouses, UINT8 sensitive) #else LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT32 *swtmrId, UINT32 arg) #endif { SWTMR_CTRL_S *swtmr = NULL; UINT32 intSave; ⑴ if (interval == 0) {return los_errno_swtMR_interval_not_vice president; } if ((mode ! = LOS_SWTMR_MODE_ONCE) && (mode ! = LOS_SWTMR_MODE_PERIOD) && (mode ! = LOS_SWTMR_MODE_NO_SELFDELETE)) { return LOS_ERRNO_SWTMR_MODE_INVALID; } if (handler == NULL) { return LOS_ERRNO_SWTMR_PTR_NULL; } if (swtmrId == NULL) { return LOS_ERRNO_SWTMR_RET_PTR_NULL; } #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) if ((rouses ! = OS_SWTMR_ROUSES_IGNORE) && (rouses ! = OS_SWTMR_ROUSES_ALLOW)) { return OS_ERRNO_SWTMR_ROUSES_INVALID; } if ((sensitive ! = OS_SWTMR_ALIGN_INSENSITIVE) && (sensitive ! = OS_SWTMR_ALIGN_SENSITIVE)) { return OS_ERRNO_SWTMR_ALIGN_INVALID; } #endif intSave = LOS_IntLock(); ⑵ if (g_swtmrFreeList == NULL) {LOS_IntRestore(intSave); return LOS_ERRNO_SWTMR_MAXSIZE; } ⑶ SWTMR = g_swtmrFreeList; g_swtmrFreeList = swtmr->pstNext; LOS_IntRestore(intSave); (4) SWTMR - > pfnHandler = handler; swtmr->ucMode = mode; swtmr->uwInterval = interval; swtmr->pstNext = (SWTMR_CTRL_S *)NULL; swtmr->uwCount = 0; swtmr->uwArg = arg; #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) swtmr->ucRouses = rouses; swtmr->ucSensitive = sensitive; #endif swtmr->ucState = OS_SWTMR_STATUS_CREATED; *swtmrId = swtmr->usTimerID; 5] SET_SORTLIST_VALUE (& SWTMR - > stSortList, OS_SORT_LINK_INVALID_TIME); return LOS_OK; }Copy the code

3.2 Deleting a Timer

We can use the function LOS_SwtmrDelete(UINT32swtmrId) to delete the timer.

Check whether timer swtmrId exceeds OS_SWTMR_MAX_TIMERID. If yes, an error code is displayed. If the timer number is correct, obtain the timer control block LosSwtmrCB* SWTMR. (2) Determine whether the timer swtmrId to be deleted matches, and return an error code if it does not. ⑶ Judge the state of the timer, if the timer timer is not created, can not be deleted. If the timer is running, stop OsSwtmrStop(SWTMR) and then delete OsSwtmrDelete(SWTMR).

LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT32 swtmrId) { SWTMR_CTRL_S *swtmr = NULL; UINT32 intSave; UINT32 ret = LOS_OK; UINT16 swtmrCbId; ⑴ if (swtmrId >= OS_SWTMR_MAX_TIMERID) {return LOS_ERRNO_SWTMR_ID_INVALID; } intSave = LOS_IntLock(); swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; swtmr = g_swtmrCBArray + swtmrCbId; 2 the if (SWTMR - > usTimerID! = swtmrId) { LOS_IntRestore(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } ⑶ switch (SWTMR ->ucState) {case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; case OS_SWTMR_STATUS_TICKING: OsSwtmrStop(swtmr); /* fall through */ case OS_SWTMR_STATUS_CREATED: OsSwtmrDelete(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; break; } LOS_IntRestore(intSave); return ret; }Copy the code

Next, let’s look at how to call the function OsSwtmrDelete(SWTMR) to delete the timer. The function is very simple, put the timer in the head of the free timer chain g_swtmrFreeList, and then change the timer state to unused to complete the deletion.

STATIC_INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr)
{
    /* insert to free list */
    swtmr->pstNext = g_swtmrFreeList;
    g_swtmrFreeList = swtmr;
    swtmr->ucState = OS_SWTMR_STATUS_UNUSED;


#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
    (VOID)memset_s((VOID *)&g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT],
                   sizeof(SwtmrAlignData), 0, sizeof(SwtmrAlignData));
#endif
}
Copy the code

3.3 Timer Startup

LOS_SwtmrStart(UINT32swtmrId)

Check whether timer swtmrId exceeds OS_SWTMR_MAX_TIMERID. If yes, an error code is displayed. If the timer number is correct, obtain the timer control block LosSwtmrCB* SWTMR. (2) Determine whether the timer swtmrId to be started matches, and return an error code if it does not. ⑶ Judge the state of the timer, if the timer timer is not created, can not start. If the timer is running, stop OsSwtmrStop(SWTMR) and then start OsSwtmrStart(SWTMR).

LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT32 swtmrId) { UINT32 intSave; UINT32 ret = LOS_OK; ⑴ if (swtmrId >= OS_SWTMR_MAX_TIMERID) {return LOS_ERRNO_SWTMR_ID_INVALID; } intSave = LOS_IntLock(); SWTMR_CTRL_S *swtmr = g_swtmrCBArray + swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; 2 the if (SWTMR - > usTimerID! = swtmrId) { LOS_IntRestore(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) if ((swtmr->ucSensitive == OS_SWTMR_ALIGN_INSENSITIVE) && (swtmr->ucMode == LOS_SWTMR_MODE_PERIOD)) { UINT32 swtmrAlignIdIndex = swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT; g_swtmrAlignID[swtmrAlignIdIndex].canAlign = 1; if ((swtmr->uwInterval % LOS_COMMON_DIVISOR) == 0) { g_swtmrAlignID[swtmrAlignIdIndex].canMultiple = 1; g_swtmrAlignID[swtmrAlignIdIndex].times = swtmr->uwInterval / LOS_COMMON_DIVISOR; }} #endif ⑶ switch (SWTMR ->ucState) {case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; case OS_SWTMR_STATUS_TICKING: OsSwtmrStop(swtmr); /* fall through */ case OS_SWTMR_STATUS_CREATED: OsSwtmrStart(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; break; } LOS_IntRestore(intSave); return ret; }Copy the code

Next, let’s look at how to call the function OsSwtmrStart(SWTMR) to start the timer. The function is particularly simple, ⑴ set the timer waiting timeout time, and change the timer state to timing. (2) insert the timer into the timeout sort list. If task scheduling is enabled, change the expiration time.

LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr) { UINT64 currTime = OsGetCurrSchedTimeCycle(); (1) SWTMR - > uwCount = SWTMR - > uwInterval; swtmr->ucState = OS_SWTMR_STATUS_TICKING; #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) if ((g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].canAlign ==  1) && (g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned == 0)) { g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 1; OsSwtmrFindAlignPos(currTime, swtmr); } #endif ⑵ OsAdd2SortLink(currTime, SWTMR ->uwCount, OS_SORT_LINK_SWTMR); If (LOS_TaskIsRunning()) {⑶ OsSchedUpdateExpireTime(currTime); }}Copy the code

3.4 Timer Stop

We can use the function LOS_SwtmrStop(UINT32swtmrId) to stop timers.

Check whether timer swtmrId exceeds OS_SWTMR_MAX_TIMERID. If yes, an error code is displayed. If the timer number is correct, obtain the timer control block LosSwtmrCB* SWTMR. (2) Determine whether the timer swtmrId to be started matches, and return an error code if it does not. ⑶ Judge the state of the timer, if the timer timer is not created, not started, can not stop. If the timer is running, OsSwtmrStop(SWTMR) is called to stop the timer.

LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT32 swtmrId) { SWTMR_CTRL_S *swtmr = NULL; UINT32 intSave; UINT16 swtmrCbId; UINT32 ret = LOS_OK; ⑴ if (swtmrId >= OS_SWTMR_MAX_TIMERID) {return LOS_ERRNO_SWTMR_ID_INVALID; } intSave = LOS_IntLock(); swtmrCbId = swtmrId % LOSCFG_BASE_CORE_SWTMR_LIMIT; swtmr = g_swtmrCBArray + swtmrCbId; 2 the if (SWTMR - > usTimerID! = swtmrId) { LOS_IntRestore(intSave); return LOS_ERRNO_SWTMR_ID_INVALID; } ⑶ switch (SWTMR ->ucState) {case OS_SWTMR_STATUS_UNUSED: ret = LOS_ERRNO_SWTMR_NOT_CREATED; break; case OS_SWTMR_STATUS_CREATED: ret = LOS_ERRNO_SWTMR_NOT_STARTED; break; case OS_SWTMR_STATUS_TICKING: OsSwtmrStop(swtmr); break; default: ret = LOS_ERRNO_SWTMR_STATUS_INVALID; break; } LOS_IntRestore(intSave); return ret; }Copy the code

Next, let’s look at how to call the function OsSwtmrStop(SWTMR) to stop the timer. Function is particularly simple, ⑴ from the sort list to delete the timer sort list node, change the timer state. 2. If task scheduling is enabled, change the expiration time.

LITE_OS_SEC_TEXT VOID OsSwtmrStop(SWTMR_CTRL_S * SWTMR) {⑴ OsDeleteSortLink(& SWTMR ->stSortList, OS_SORT_LINK_SWTMR); swtmr->ucState = OS_SWTMR_STATUS_CREATED; ⑵ OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle()); #if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1) g_swtmrAlignID[swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT].isAligned = 0; #endif } }Copy the code

4. Relationship between timer and Tick time

After a timer is added to the timeout sequence list, you need to check whether the timer expires. As mentioned in previous articles, the system calls OsTickHandler() every time a tick passes, which calls OsSwtmrScan() to scan and update the timer time. Let’s look at the code for OsSwtmrScan().

(2) Determine whether the sorted list is empty. If it is empty, return. Fetch the next list node sortList. (4) If the response time of the linked list node is less than or equal to the current time, the timer expires and the timer callback function needs to be processed. ⑸ delete the timeout nodes from the timeout sequencing linked list, ⑹ obtain timer control block SWTMR_CTRL_S* SWTMR, call the function OsSwtmrTimeoutHandle(SWTMR) to execute the timer callback function, and set the marker needSchedule to be scheduled. ⑺ Terminates the loop if the timeout sort linked list is empty.

STATIC BOOL OsSwtmrScan(VOID) { BOOL needSchedule = FALSE; ⑴ LOS_DL_LIST *listObject = &g_swtMRSortLinkList ->sortLink; ⑵ if (LOS_ListEmpty(listObject)) {return needSchedule; } ⑶ SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); UINT64 currTime = OsGetCurrSchedTimeCycle(); ⑷ while (* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ⑹ SWTMR_CTRL_S * SWTMR = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList); OsSwtmrTimeoutHandle(swtmr); needSchedule = TRUE; ⑺ if (LOS_ListEmpty(listObject)) {break; } sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode); } return needSchedule; }Copy the code

Let’s finally look at the function OsSwtmrTimeoutHandle(). Write the timer callback function into the timer queue at ⑴. (2) If it is a one-time timer, the timer is deleted and recycled to the idle timer chain list. The state is set to unused, and then the timer number is updated. If the timer is a periodic timer, restart the timer. (4) If it is a one-time timer but not deleted, set the timer state to create state.

STATIC VOID OsSwtmrTimeoutHandle(SWTMR_CTRL_S *swtmr) { SwtmrHandlerItem swtmrHandler; swtmrHandler.handler = swtmr->pfnHandler; swtmrHandler.arg = swtmr->uwArg; ⑴ (VOID)LOS_QueueWriteCopy(g_swtmrHandlerQueue, &swtMRHandler, sizeof(SwtmrHandlerItem), LOS_NO_WAIT); ⑵ if (SWTMR ->ucMode == LOS_SWTMR_MODE_ONCE) {OsSwtmrDelete(SWTMR); if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) { swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT; } else { swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT; } else if (SWTMR ->ucMode == LOS_SWTMR_MODE_PERIOD) {OsSwtmrStart(SWTMR); } else if (SWTMR ->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) {SWTMR ->ucState = OS_SWTMR_STATUS_CREATED; }}Copy the code

summary

This article led us to analyze the hongmeng light kernel timer module source code, including timer structure, timer pool initialization, timer creation, deletion, start stop and so on. Thanks for reading. If you have any questions or suggestions, please leave a comment at gitee.com/openharmony… . To make it easier to find the light kernel repository, visit gitee.com/openharmony… “, follow Watch, like Star, and Fork to your account, thank you.

Click to follow, the first time to learn about Huawei cloud fresh technology ~