更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_swtmr.c
浏览该文件的文档.
1/*!
2* @file los_swtmr.c
3* @brief 软定时器主文件
4* @details
5* @attention @verbatim
6基本概念
7 软件定时器,是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick数后,会触发用户自定义的回调函数。
8 硬件定时器受硬件的限制,数量上不足以满足用户的实际需求。因此为了满足用户需求,提供更多的定时器,
9 软件定时器功能,支持如下特性:
10 创建软件定时器。
11 启动软件定时器。
12 停止软件定时器。
13 删除软件定时器。
14 获取软件定时器剩余Tick数。
15 可配置支持的软件定时器个数。
16
17 运作机制
18 软件定时器是系统资源,在模块初始化的时候已经分配了一块连续内存。
19 软件定时器使用了系统的一个队列和一个任务资源,软件定时器的触发遵循队列规则,
20 先进先出。定时时间短的定时器总是比定时时间长的靠近队列头,满足优先触发的准则。
21 软件定时器以Tick为基本计时单位,当创建并启动一个软件定时器时,Huawei LiteOS会根据
22 当前系统Tick时间及设置的定时时长确定该定时器的到期Tick时间,并将该定时器控制结构挂入计时全局链表。
23 当Tick中断到来时,在Tick中断处理函数中扫描软件定时器的计时全局链表,检查是否有定时器超时,
24 若有则将超时的定时器记录下来。Tick中断处理函数结束后,软件定时器任务(优先级为最高)
25 被唤醒,在该任务中调用已经记录下来的定时器的回调函数。
26
27 定时器状态
28 OS_SWTMR_STATUS_UNUSED(定时器未使用)
29 系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。
30
31 OS_SWTMR_STATUS_TICKING(定时器处于计数状态)
32 在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。
33
34 OS_SWTMR_STATUS_CREATED(定时器创建后未启动,或已停止)
35 定时器创建后,不处于计数状态时,定时器将变成该状态。
36
37 软件定时器提供了三类模式:
38 单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动删除。
39 周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动停止定时器,否则将永远持续执行下去。
40 单次触发定时器,但这类定时器超时触发后不会自动删除,需要调用定时器删除接口删除定时器。
41
42 使用场景
43 创建一个单次触发的定时器,超时后执行用户自定义的回调函数。
44 创建一个周期性触发的定时器,超时后执行用户自定义的回调函数。
45
46 软件定时器的典型开发流程
47 通过make menuconfig配置软件定时器
48 创建定时器LOS_SwtmrCreate,设置定时器的定时时长、定时器模式、超时后的回调函数。
49 启动定时器LOS_SwtmrStart。
50 获得软件定时器剩余Tick数LOS_SwtmrTimeGet。
51 停止定时器LOS_SwtmrStop。
52 删除定时器LOS_SwtmrDelete。
53
54 注意事项
55 软件定时器的回调函数中不应执行过多操作,不建议使用可能引起任务挂起或者阻塞的接口或操作,
56 如果使用会导致软件定时器响应不及时,造成的影响无法确定。
57 软件定时器使用了系统的一个队列和一个任务资源。软件定时器任务的优先级设定为0,且不允许修改 。
58 系统可配置的软件定时器个数是指:整个系统可使用的软件定时器总个数,并非用户可使用的软件定时器个数。
59 例如:系统多占用一个软件定时器,那么用户能使用的软件定时器资源就会减少一个。
60 创建单次不自删除属性的定时器,用户需要自行调用定时器删除接口删除定时器,回收定时器资源,避免资源泄露。
61 软件定时器的定时精度与系统Tick时钟的周期有关。
62 @endverbatim
63*/
64
65/*
66 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
67 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
68 *
69 * Redistribution and use in source and binary forms, with or without modification,
70 * are permitted provided that the following conditions are met:
71 *
72 * 1. Redistributions of source code must retain the above copyright notice, this list of
73 * conditions and the following disclaimer.
74 *
75 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
76 * of conditions and the following disclaimer in the documentation and/or other materials
77 * provided with the distribution.
78 *
79 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
80 * to endorse or promote products derived from this software without specific prior written
81 * permission.
82 *
83 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
84 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
85 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
86 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
87 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
88 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
89 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
90 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
91 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
92 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
93 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94 */
95
96#include "los_swtmr_pri.h"
97#include "los_init.h"
98#include "los_process_pri.h"
99#include "los_queue_pri.h"
100#include "los_sched_pri.h"
101#include "los_sortlink_pri.h"
102#include "los_task_pri.h"
103#include "los_hook.h"
104
105#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
106#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0)
107#error "swtmr maxnum cannot be zero"
108#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */
109
110STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr);
111STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid);
112LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /**< First address in Timer memory space \n 定时器池 */
113LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /**< Pool of Swtmr Handler \n 用于注册软时钟的回调函数 */
114LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /**< Free list of Software Timer \n 空闲定时器链表 */
115
116/* spinlock for swtmr module, only available on SMP mode */
117LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
118#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))///< 持有软时钟自旋锁
119#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))///< 释放软时钟自旋锁
120
121typedef struct {
123 LosTaskCB *swtmrTask; /* software timer task id | 定时器任务ID */
124 LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id | 定时器超时队列*/
126
127STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM];
128
129#ifdef LOSCFG_SWTMR_DEBUG
130#define OS_SWTMR_PERIOD_TO_CYCLE(period) (((UINT64)(period) * OS_NS_PER_TICK) / OS_NS_PER_CYCLE)
132
134{
135 if (swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) {
136 return FALSE;
137 }
138
139 return g_swtmrDebugData[swtmrID].swtmrUsed;
140}
141
143{
144 UINT32 intSave;
145 errno_t ret;
146
147 if ((swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) || (data == NULL) ||
148 (mode == NULL) || (len < sizeof(SwtmrDebugData))) {
149 return LOS_NOK;
150 }
151
152 SWTMR_CTRL_S *swtmr = &g_swtmrCBArray[swtmrID];
153 SWTMR_LOCK(intSave);
154 ret = memcpy_s(data, len, &g_swtmrDebugData[swtmrID], sizeof(SwtmrDebugData));
155 *mode = swtmr->ucMode;
156 SWTMR_UNLOCK(intSave);
157 if (ret != EOK) {
158 return LOS_NOK;
159 }
160 return LOS_OK;
161}
162#endif
163
164STATIC VOID SwtmrDebugDataInit(VOID)
165{
166#ifdef LOSCFG_SWTMR_DEBUG
167 UINT32 size = sizeof(SwtmrDebugData) * LOSCFG_BASE_CORE_SWTMR_LIMIT;
169 if (g_swtmrDebugData == NULL) {
170 PRINT_ERR("SwtmrDebugDataInit malloc failed!\n");
171 return;
172 }
173 (VOID)memset_s(g_swtmrDebugData, size, 0, size);
174#endif
175}
176
177STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks, UINT32 times)
178{
179#ifdef LOSCFG_SWTMR_DEBUG
181 if (data->period != ticks) {
182 (VOID)memset_s(&data->base, sizeof(SwtmrDebugBase), 0, sizeof(SwtmrDebugBase));
183 data->period = ticks;
184 }
185 data->base.startTime = swtmr->startTime;
186 data->base.times += times;
187#endif
188}
189
190STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
191{
192#ifdef LOSCFG_SWTMR_DEBUG
194 data->swtmrUsed = TRUE;
195 data->handler = swtmr->pfnHandler;
196 data->cpuid = cpuid;
197#endif
198}
199
200STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 swtmrID, SwtmrHandlerItemPtr swtmrHandler)
201{
202#ifdef LOSCFG_SWTMR_DEBUG
203 SwtmrDebugBase *data = &g_swtmrDebugData[swtmrID].base;
204 swtmrHandler->swtmrID = swtmrID;
205 UINT64 currTime = OsGetCurrSchedTimeCycle();
206 UINT64 waitTime = currTime - data->startTime;
207 data->waitTime += waitTime;
208 if (waitTime > data->waitTimeMax) {
209 data->waitTimeMax = waitTime;
210 }
211 data->readyStartTime = currTime;
212 data->waitCount++;
213#endif
214}
215
216STATIC INLINE VOID SwtmrDebugDataClear(UINT32 swtmrID)
217{
218#ifdef LOSCFG_SWTMR_DEBUG
219 (VOID)memset_s(&g_swtmrDebugData[swtmrID], sizeof(SwtmrDebugData), 0, sizeof(SwtmrDebugData));
220#endif
221}
222
223STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle)
224{
225#ifdef LOSCFG_SWTMR_DEBUG
226 UINT32 intSave;
227 SwtmrDebugBase *data = &g_swtmrDebugData[swtmrHandle->swtmrID].base;
228 UINT64 startTime = OsGetCurrSchedTimeCycle();
229#endif
230 swtmrHandle->handler(swtmrHandle->arg);
231#ifdef LOSCFG_SWTMR_DEBUG
232 UINT64 runTime = OsGetCurrSchedTimeCycle() - startTime;
233 SWTMR_LOCK(intSave);
234 data->runTime += runTime;
235 if (runTime > data->runTimeMax) {
236 data->runTimeMax = runTime;
237 }
238 runTime = startTime - data->readyStartTime;
239 data->readyTime += runTime;
240 if (runTime > data->readyTimeMax) {
241 data->readyTimeMax = runTime;
242 }
243 data->runCount++;
244 SWTMR_UNLOCK(intSave);
245#endif
246}
247
248STATIC INLINE VOID SwtmrWake(SwtmrRunqueue *srq, UINT64 startTime, SortLinkList *sortList)
249{
250 UINT32 intSave;
251 SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
253 LOS_ASSERT(swtmrHandler != NULL);
254
255 OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);
256
257 SWTMR_LOCK(intSave);
258 swtmrHandler->handler = swtmr->pfnHandler;
259 swtmrHandler->arg = swtmr->uwArg;
260 LOS_ListTailInsert(&srq->swtmrHandlerQueue, &swtmrHandler->node);
261 SwtmrDebugWaitTimeCalculate(swtmr->usTimerID, swtmrHandler);
262
263 if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) {
264 SwtmrDelete(swtmr);
265
266 if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
267 swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT;
268 } else {
269 swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT;
270 }
271 } else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) {
273 } else {
274 swtmr->uwOverrun++;
275 swtmr->startTime = startTime;
276 (VOID)SwtmrToStart(swtmr, ArchCurrCpuid());
277 }
278
279 SWTMR_UNLOCK(intSave);
280}
281
282STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
283{
284 UINT32 intSave;
285 SortLinkAttribute *swtmrSortLink = &srq->swtmrSortLink;
286 LOS_DL_LIST *listObject = &swtmrSortLink->sortLink;
287
288 /*
289 * it needs to be carefully coped with, since the swtmr is in specific sortlink
290 * while other cores still has the chance to process it, like stop the timer.
291 */
292 LOS_SpinLockSave(&swtmrSortLink->spinLock, &intSave);
293
294 if (LOS_ListEmpty(listObject)) {
295 LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
296 return;
297 }
298 SortLinkList *sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
299
300 UINT64 currTime = OsGetCurrSchedTimeCycle();
301 while (sortList->responseTime <= currTime) {
302 sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
303 UINT64 startTime = GET_SORTLIST_VALUE(sortList);
304 OsDeleteNodeSortLink(swtmrSortLink, sortList);
305 LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
306
307 SwtmrWake(srq, startTime, sortList);
308
309 LOS_SpinLockSave(&swtmrSortLink->spinLock, &intSave);
310 if (LOS_ListEmpty(listObject)) {
311 break;
312 }
313
314 sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
315 }
316
317 LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
318 return;
319}
320/**
321 * @brief 软时钟的入口函数,拥有任务的最高优先级 0 级!
322 *
323 * @return LITE_OS_SEC_TEXT
324 */
325STATIC VOID SwtmrTask(VOID)
326{
327 SwtmrHandlerItem swtmrHandle;
328 UINT32 intSave;
329 UINT64 waitTime;
330
332 LOS_DL_LIST *head = &srq->swtmrHandlerQueue;
333 for (;;) {//死循环获取队列item,一直读干净为止
335 if (waitTime != 0) {
336 SCHEDULER_LOCK(intSave);
337 srq->swtmrTask->ops->delay(srq->swtmrTask, waitTime);
338 OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, srq->swtmrTask);
339 SCHEDULER_UNLOCK(intSave);
340 }
341
343
344 while (!LOS_ListEmpty(head)) {
345 SwtmrHandlerItemPtr swtmrHandlePtr = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(head), SwtmrHandlerItem, node);
346 LOS_ListDelete(&swtmrHandlePtr->node);
347
348 (VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem));
349 (VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存
350 SwtmrHandler(&swtmrHandle);
351 }
352 }
353 }
354
355///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
356STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
357{
358 UINT32 ret;
359 TSK_INIT_PARAM_S swtmrTask;
360
361 (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
362 swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数
363 swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈
364 swtmrTask.pcName = "Swt_Task";//任务名称
365 swtmrTask.usTaskPrio = 0;//哇塞! 逮到一个最高优先级的任务 @note_thinking 这里应该用 OS_TASK_PRIORITY_HIGHEST 表示
366 swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;//分离模式
367#ifdef LOSCFG_KERNEL_SMP
368 swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务
369#endif
370 ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度
371 if (ret == LOS_OK) {
372 OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是一个系统任务
373 }
374
375 return ret;
376}
377
379{
380 return g_swtmrRunqueue[cpuid].swtmrTask->taskID;
381}
382
384{
385 if (taskCB->taskEntry == (TSK_ENTRY_FUNC)SwtmrTask) {
386 return TRUE;
387 }
388 return FALSE;
389}
390///回收指定进程的软时钟
391LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
392{
393 for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器
394 if (g_swtmrCBArray[index].uwOwnerPid == processID) {//找到一个
395 LOS_SwtmrDelete(index);//删除定时器
396 }
397 }
398}
399///软时钟初始化 ,注意函数在多CPU情况下会执行多次
401{
402 UINT32 ret;
403 UINT32 size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;
404 SWTMR_CTRL_S *swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */
405 if (swtmr == NULL) {
406 return LOS_ERRNO_SWTMR_NO_MEMORY;
407 }
408
409 (VOID)memset_s(swtmr, size, 0, size);//清0
410 g_swtmrCBArray = swtmr;//软时钟
411 LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表
412 for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
413 swtmr->usTimerID = index;//按顺序赋值
414 LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
415 }
416 //想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息.
417 size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池。
418 g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */
419 if (g_swtmrHandlerPool == NULL) {
420 return LOS_ERRNO_SWTMR_NO_MEMORY;
421 }
422
424 if (ret != LOS_OK) {
425 return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
426 }
427
428 for (UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
429 SwtmrRunqueue *srq = &g_swtmrRunqueue[index];
430 /* The linked list of all cores must be initialized at core 0 startup for load balancing */
433 srq->swtmrTask = NULL;
434 }
435
437
438 return LOS_OK;
439}
440
441LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
442{
443 UINT32 ret;
444 UINT32 cpuid = ArchCurrCpuid();
445 UINT32 swtmrTaskID;
446
447 if (cpuid == 0) {
448 ret = SwtmrBaseInit();
449 if (ret != LOS_OK) {
450 goto ERROR;
451 }
452 }
453
454 ret = SwtmrTaskCreate(cpuid, &swtmrTaskID);
455 if (ret != LOS_OK) {
456 ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED;
457 goto ERROR;
458 }
459
460 SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid];
461 srq->swtmrTask = OsGetTaskCB(swtmrTaskID);
462 return LOS_OK;
463
464ERROR:
465 PRINT_ERR("OsSwtmrInit error! ret = %u\n", ret);
467 g_swtmrCBArray = NULL;
469 g_swtmrHandlerPool = NULL;
470 return ret;
471}
472
473#ifdef LOSCFG_KERNEL_SMP
474STATIC INLINE VOID FindIdleSwtmrRunqueue(UINT16 *idleCpuid)
475{
476 SwtmrRunqueue *idleRq = &g_swtmrRunqueue[0];
477 UINT32 nodeNum = OsGetSortLinkNodeNum(&idleRq->swtmrSortLink);
478 UINT16 cpuid = 1;
479 do {
480 SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid];
482 if (nodeNum > temp) {
483 *idleCpuid = cpuid;
484 nodeNum = temp;
485 }
486 cpuid++;
487 } while (cpuid < LOSCFG_KERNEL_CORE_NUM);
488}
489#endif
490
491STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid)
492{
493 SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid];
494 OsAdd2SortLink(&srq->swtmrSortLink, node, responseTime, cpuid);
495}
496
497STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node)
498{
499#ifdef LOSCFG_KERNEL_SMP
500 UINT16 cpuid = OsGetSortLinkNodeCpuid(node);
501#else
502 UINT16 cpuid = 0;
503#endif
504 SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid];
506 return;
507}
508
509STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime)
510{
511 UINT32 ret;
512 UINT32 intSave;
513 SwtmrRunqueue *srq = &g_swtmrRunqueue[cpuid];
514 SCHEDULER_LOCK(intSave);
515 if ((srq->swtmrTask == NULL) || !OsTaskIsBlocked(srq->swtmrTask)) {
516 SCHEDULER_UNLOCK(intSave);
517 return;
518 }
519
520 if (responseTime >= GET_SORTLIST_VALUE(&srq->swtmrTask->sortList)) {
521 SCHEDULER_UNLOCK(intSave);
522 return;
523 }
524
525 ret = OsSchedTimeoutQueueAdjust(srq->swtmrTask, responseTime);
526 SCHEDULER_UNLOCK(intSave);
527 if (ret != LOS_OK) {
528 return;
529 }
530
531 if (cpuid == ArchCurrCpuid()) {
533 } else {
534 LOS_MpSchedule(CPUID_TO_AFFI_MASK(cpuid));
535 }
536}
537
539{
540 UINT32 ticks;
541 UINT32 times = 0;
542
543 if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
544 (swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
545 (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器
546 ticks = swtmr->uwExpiry; //获取时间间隔
547 } else {
548 ticks = swtmr->uwInterval;//获取周期性定时器时间间隔
549 }
550 swtmr->ucState = OS_SWTMR_STATUS_TICKING;//计数状态
551
552 UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;
553 UINT64 responseTime = swtmr->startTime + period;
554 UINT64 currTime = OsGetCurrSchedTimeCycle();
555 if (responseTime < currTime) {
556 times = (UINT32)((currTime - swtmr->startTime) / period);
557 swtmr->startTime += times * period;
558 responseTime = swtmr->startTime + period;
559 PRINT_WARN("Swtmr already timeout! SwtmrID: %u\n", swtmr->usTimerID);
560 }
561
562 AddSwtmr2TimeList(&swtmr->stSortList, responseTime, cpuid);
563 SwtmrDebugDataUpdate(swtmr, ticks, times);
564 return responseTime;
565}
566
567/*
568 * Description: Start Software Timer
569 * Input : swtmr --- Need to start software timer
570 */
571STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
572{
573 UINT64 responseTime;
574 UINT16 idleCpu = 0;
575#ifdef LOSCFG_KERNEL_SMP
576 FindIdleSwtmrRunqueue(&idleCpu);
577#endif
579 responseTime = SwtmrToStart(swtmr, idleCpu);
580
581 SwtmrDebugDataStart(swtmr, idleCpu);
582
583 SwtmrAdjustCheck(idleCpu, responseTime);
584}
585
586/*
587 * Description: Delete Software Timer
588 * Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL.
589 */
590STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
591{
592 /* insert to free list */
593 LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用
594 swtmr->ucState = OS_SWTMR_STATUS_UNUSED;//又干净着呢
595 swtmr->uwOwnerPid = 0;//谁拥有这个定时器? 是 0号进程
597}
598
599STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 cpuid)
600{
601 UINT32 intSave;
602
603 SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
604 SWTMR_LOCK(intSave);
605 swtmr->startTime = startTime;
606 (VOID)SwtmrToStart(swtmr, cpuid);
607 SWTMR_UNLOCK(intSave);
608}
609
611{
612 UINT16 cpuid = ArchCurrCpuid();
613 SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[cpuid].swtmrSortLink;
614 LOS_DL_LIST *listHead = &swtmrSortLink->sortLink;
615 LOS_DL_LIST *listNext = listHead->pstNext;
616
617 LOS_SpinLock(&swtmrSortLink->spinLock);
618 while (listNext != listHead) {
619 SortLinkList *sortList = LOS_DL_LIST_ENTRY(listNext, SortLinkList, sortLinkNode);
620 OsDeleteNodeSortLink(swtmrSortLink, sortList);
621 LOS_SpinUnlock(&swtmrSortLink->spinLock);
622
623 SwtmrRestart(startTime, sortList, cpuid);
624
625 LOS_SpinLock(&swtmrSortLink->spinLock);
626 listNext = listNext->pstNext;
627 }
628 LOS_SpinUnlock(&swtmrSortLink->spinLock);
629}
630
631STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
632{
633 LOS_DL_LIST *listObject = &swtmrSortLink->sortLink;
634 LOS_DL_LIST *list = listObject->pstNext;
635
636 LOS_SpinLock(&swtmrSortLink->spinLock);
637 while (list != listObject) {
638 SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);
639 if (checkFunc((UINTPTR)listSorted, arg)) {
640 LOS_SpinUnlock(&swtmrSortLink->spinLock);
641 return TRUE;
642 }
643 list = list->pstNext;
644 }
645
646 LOS_SpinUnlock(&swtmrSortLink->spinLock);
647 return FALSE;
648}
649
651{
652 for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
654 if (SwtmrRunqueueFind(swtmrSortLink, checkFunc, arg)) {
655 return TRUE;
656 }
657 }
658 return FALSE;
659}
660
662{
663 UINT32 intSave;
664
665 SWTMR_LOCK(intSave);
666 BOOL find = SwtmrTimeListFind(checkFunc, arg);
667 SWTMR_UNLOCK(intSave);
668 return find;
669}
670
671/*
672 * Description: Get next timeout
673 * Return : Count of the Timer list
674 */
675LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
676{
677 UINT64 currTime = OsGetCurrSchedTimeCycle();
679 UINT64 time = (OsSortLinkGetNextExpireTime(currTime, &srq->swtmrSortLink) / OS_CYCLE_PER_TICK);
680 if (time > OS_INVALID_VALUE) {
681 time = OS_INVALID_VALUE;
682 }
683 return (UINT32)time;
684}
685
686/*
687 * Description: Stop of Software Timer interface
688 * Input : swtmr --- the software timer control handler
689 */
690STATIC VOID SwtmrStop(SWTMR_CTRL_S *swtmr)
691{
693 swtmr->uwOverrun = 0;
694
696}
697
698/*
699 * Description: Get next software timer expiretime
700 * Input : swtmr --- the software timer control handler
701 */
702LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
703{
704 UINT64 currTime = OsGetCurrSchedTimeCycle();
705 UINT64 time = (OsSortLinkGetTargetExpireTime(currTime, &swtmr->stSortList) / OS_CYCLE_PER_TICK);
706 if (time > OS_INVALID_VALUE) {
707 time = OS_INVALID_VALUE;
708 }
709 return (UINT32)time;
710}
711///创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
712LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
713 UINT8 mode,
714 SWTMR_PROC_FUNC handler,
715 UINT16 *swtmrID,
716 UINTPTR arg)
717{
718 SWTMR_CTRL_S *swtmr = NULL;
719 UINT32 intSave;
720 SortLinkList *sortList = NULL;
721
722 if (interval == 0) {
723 return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED;
724 }
725
726 if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) &&
728 return LOS_ERRNO_SWTMR_MODE_INVALID;
729 }
730
731 if (handler == NULL) {
732 return LOS_ERRNO_SWTMR_PTR_NULL;
733 }
734
735 if (swtmrID == NULL) {
736 return LOS_ERRNO_SWTMR_RET_PTR_NULL;
737 }
738
739 SWTMR_LOCK(intSave);
740 if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲链表不能为空
741 SWTMR_UNLOCK(intSave);
742 return LOS_ERRNO_SWTMR_MAXSIZE;
743 }
744
745 sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode);
746 swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
747 LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));//
748 SWTMR_UNLOCK(intSave);
749
750 swtmr->uwOwnerPid = OsCurrProcessGet()->processID;//定时器进程归属设定
751 swtmr->pfnHandler = handler;//时间到了的回调函数
752 swtmr->ucMode = mode; //定时器模式
753 swtmr->uwOverrun = 0;
754 swtmr->uwInterval = interval; //周期性超时间隔
755 swtmr->uwExpiry = interval; //一次性超时间隔
756 swtmr->uwArg = arg; //回调函数的参数
757 swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态
758 SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
759 *swtmrID = swtmr->usTimerID;
760 OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
761 return LOS_OK;
762}
763///接口函数 启动定时器 参数定时任务ID
764LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
765{
766 SWTMR_CTRL_S *swtmr = NULL;
767 UINT32 intSave;
768 UINT32 ret = LOS_OK;
769 UINT16 swtmrCBID;
770
771 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
772 return LOS_ERRNO_SWTMR_ID_INVALID;
773 }
774
775 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
776 swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
777
778 SWTMR_LOCK(intSave);
779 if (swtmr->usTimerID != swtmrID) {//ID必须一样
780 SWTMR_UNLOCK(intSave);
781 return LOS_ERRNO_SWTMR_ID_INVALID;
782 }
783
784 switch (swtmr->ucState) {//判断定时器状态
786 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
787 break;
788 /* 如果定时器的状态为启动中,应先停止定时器再重新启动
789 * If the status of swtmr is timing, it should stop the swtmr first,
790 * then start the swtmr again.
791 */
792 case OS_SWTMR_STATUS_TICKING://正在计数的定时器
793 SwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了
794 /* fall-through */
795 case OS_SWTMR_STATUS_CREATED://已经创建好了
796 SwtmrStart(swtmr);
797 break;
798 default:
799 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
800 break;
801 }
802
803 SWTMR_UNLOCK(intSave);
804 OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
805 return ret;
806}
807///接口函数 停止定时器 参数定时任务ID
808LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
809{
810 SWTMR_CTRL_S *swtmr = NULL;
811 UINT32 intSave;
812 UINT32 ret = LOS_OK;
813 UINT16 swtmrCBID;
814
815 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
816 return LOS_ERRNO_SWTMR_ID_INVALID;
817 }
818
819 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
820 swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
821 SWTMR_LOCK(intSave);
822
823 if (swtmr->usTimerID != swtmrID) {//ID必须一样
824 SWTMR_UNLOCK(intSave);
825 return LOS_ERRNO_SWTMR_ID_INVALID;
826 }
827
828 switch (swtmr->ucState) {//判断定时器状态
830 ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建
831 break;
833 ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始
834 break;
835 case OS_SWTMR_STATUS_TICKING://正在计数
836 SwtmrStop(swtmr);//执行正在停止定时器操作
837 break;
838 default:
839 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
840 break;
841 }
842
843 SWTMR_UNLOCK(intSave);
844 OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
845 return ret;
846}
847///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
848LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
849{
850 SWTMR_CTRL_S *swtmr = NULL;
851 UINT32 intSave;
852 UINT32 ret = LOS_OK;
853 UINT16 swtmrCBID;
854
855 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
856 return LOS_ERRNO_SWTMR_ID_INVALID;
857 }
858
859 if (tick == NULL) {
860 return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
861 }
862
863 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
864 swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
865 SWTMR_LOCK(intSave);
866
867 if (swtmr->usTimerID != swtmrID) {//ID必须一样
868 SWTMR_UNLOCK(intSave);
869 return LOS_ERRNO_SWTMR_ID_INVALID;
870 }
871 switch (swtmr->ucState) {
873 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
874 break;
876 ret = LOS_ERRNO_SWTMR_NOT_STARTED;
877 break;
878 case OS_SWTMR_STATUS_TICKING://正在计数的定时器
879 *tick = OsSwtmrTimeGet(swtmr);//获取
880 break;
881 default:
882 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
883 break;
884 }
885 SWTMR_UNLOCK(intSave);
886 return ret;
887}
888///接口函数 删除定时器
889LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
890{
891 SWTMR_CTRL_S *swtmr = NULL;
892 UINT32 intSave;
893 UINT32 ret = LOS_OK;
894 UINT16 swtmrCBID;
895
896 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
897 return LOS_ERRNO_SWTMR_ID_INVALID;
898 }
899
900 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
901 swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
902 SWTMR_LOCK(intSave);
903
904 if (swtmr->usTimerID != swtmrID) {//ID必须一样
905 SWTMR_UNLOCK(intSave);
906 return LOS_ERRNO_SWTMR_ID_INVALID;
907 }
908
909 switch (swtmr->ucState) {
911 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
912 break;
913 case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break;
914 SwtmrStop(swtmr);
915 /* fall-through */
916 case OS_SWTMR_STATUS_CREATED://再删除定时器
917 SwtmrDelete(swtmr);
918 break;
919 default:
920 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
921 break;
922 }
923
924 SWTMR_UNLOCK(intSave);
925 OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr);
926 return ret;
927}
928
929#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
930
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
LITE_OS_SEC_TEXT VOID * LOS_MemboxAlloc(VOID *pool)
从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存.
Definition: los_membox.c:150
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
释放指定的一块静态内存块
Definition: los_membox.c:174
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小
Definition: los_membox.c:106
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
Definition: los_memory.c:108
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
struct tagSwTmrCtrl SWTMR_CTRL_S
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
接口函数 停止定时器 参数定时任务ID
Definition: los_swtmr.c:808
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
接口函数 启动定时器 参数定时任务ID
Definition: los_swtmr.c:764
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
Definition: los_swtmr.c:848
VOID(* SWTMR_PROC_FUNC)(UINTPTR arg)
Define the type of a callback function that handles software timer timeout.
Definition: los_swtmr.h:260
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
接口函数 删除定时器
Definition: los_swtmr.c:889
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT16 *swtmrID, UINTPTR arg)
创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
Definition: los_swtmr.c:712
@ LOS_SWTMR_MODE_PERIOD
Definition: los_swtmr.h:233
@ LOS_SWTMR_MODE_OPP
Definition: los_swtmr.h:235
@ LOS_SWTMR_MODE_ONCE
Definition: los_swtmr.h:232
@ LOS_SWTMR_MODE_NO_SELFDELETE
Definition: los_swtmr.h:234
struct tagTskInitParam TSK_INIT_PARAM_S
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
Definition: los_task.c:718
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
Definition: los_hw_cpu.h:168
VOID LOS_MpSchedule(UINT32 target)
Definition: los_mp.c:76
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
VOID OsSchedExpireTimeUpdate(VOID)
Definition: los_sched.c:88
STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID)
Definition: los_sched_pri.h:75
STATIC INLINE UINT32 OsSchedTimeoutQueueAdjust(LosTaskCB *taskCB, UINT64 responseTime)
BOOL(* SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR)
Definition: los_sched_pri.h:73
STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB)
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
Definition: los_spinlock.c:108
VOID LOS_SpinLock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:50
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
Definition: los_spinlock.c:98
VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:84
STATIC UINT32 SwtmrBaseInit(VOID)
软时钟初始化 ,注意函数在多CPU情况下会执行多次
Definition: los_swtmr.c:400
LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
Scan a software timer.
Definition: los_swtmr.c:675
BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
Definition: los_swtmr.c:383
STATIC INLINE VOID SwtmrDebugDataClear(UINT32 swtmrID)
Definition: los_swtmr.c:216
STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 cpuid)
Definition: los_swtmr.c:599
STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
Definition: los_swtmr.c:282
STATIC INLINE VOID FindIdleSwtmrRunqueue(UINT16 *idleCpuid)
Definition: los_swtmr.c:474
STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node)
Definition: los_swtmr.c:497
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList
Definition: los_swtmr.c:114
VOID OsSwtmrResponseTimeReset(UINT64 startTime)
Definition: los_swtmr.c:610
UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid)
Definition: los_swtmr.c:378
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
回收指定进程的软时钟
Definition: los_swtmr.c:391
STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks, UINT32 times)
Definition: los_swtmr.c:177
STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
Definition: los_swtmr.c:650
STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
Definition: los_swtmr.c:190
STATIC VOID SwtmrTask(VOID)
软时钟的入口函数,拥有任务的最高优先级 0 级!
Definition: los_swtmr.c:325
BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
Definition: los_swtmr.c:661
STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
Definition: los_swtmr.c:631
LITE_OS_SEC_BSS SWTMR_CTRL_S * g_swtmrCBArray
Definition: los_swtmr.c:112
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
Definition: los_swtmr.c:590
STATIC VOID SwtmrStop(SWTMR_CTRL_S *swtmr)
Definition: los_swtmr.c:690
STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid)
Definition: los_swtmr.c:491
STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle)
Definition: los_swtmr.c:223
UINT32 OsSwtmrDebugDataGet(UINT32 swtmrID, SwtmrDebugData *data, UINT32 len, UINT8 *mode)
Definition: los_swtmr.c:142
STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
Definition: los_swtmr.c:356
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin)
初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
STATIC VOID SwtmrDebugDataInit(VOID)
Definition: los_swtmr.c:164
STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 swtmrID, SwtmrHandlerItemPtr swtmrHandler)
Definition: los_swtmr.c:200
STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]
Definition: los_swtmr.c:127
STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
Definition: los_swtmr.c:571
STATIC INLINE VOID SwtmrWake(SwtmrRunqueue *srq, UINT64 startTime, SortLinkList *sortList)
Definition: los_swtmr.c:248
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
Definition: los_swtmr.c:441
LITE_OS_SEC_BSS UINT8 * g_swtmrHandlerPool
Definition: los_swtmr.c:113
BOOL OsSwtmrDebugDataUsed(UINT32 swtmrID)
Definition: los_swtmr.c:133
STATIC SwtmrDebugData * g_swtmrDebugData
Definition: los_swtmr.c:131
LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
Definition: los_swtmr.c:702
STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
Definition: los_swtmr.c:538
STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime)
Definition: los_swtmr.c:509
SwtmrHandlerItem * SwtmrHandlerItemPtr
Definition: los_swtmr_pri.h:79
@ OS_SWTMR_STATUS_UNUSED
Definition: los_swtmr_pri.h:56
@ OS_SWTMR_STATUS_CREATED
Definition: los_swtmr_pri.h:57
@ OS_SWTMR_STATUS_TICKING
Definition: los_swtmr_pri.h:58
SPIN_LOCK_S g_swtmrSpin
STATIC INLINE LosTaskCB * OsGetTaskCB(UINT32 taskID)
通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块
Definition: los_task_pri.h:250
unsigned short UINT16
Definition: los_typedef.h:56
long unsigned int UINT64
Definition: los_typedef.h:66
unsigned char UINT8
Definition: los_typedef.h:55
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
size_t BOOL
Definition: los_typedef.h:88
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
UINT32 processID
UINT32(* delay)(LosTaskCB *taskCB, UINT64 waitTime)
延时执行
UINT64 readyStartTime
SWTMR_PROC_FUNC handler
SwtmrDebugBase base
LOS_DL_LIST node
挂入定时器超时队列,详见 SwtmrWake( ... )
Definition: los_swtmr_pri.h:69
SWTMR_PROC_FUNC handler
Definition: los_swtmr_pri.h:66
LosTaskCB * swtmrTask
Definition: los_swtmr.c:123
LOS_DL_LIST swtmrHandlerQueue
Definition: los_swtmr.c:124
SortLinkAttribute swtmrSortLink
Definition: los_swtmr.c:122
TSK_ENTRY_FUNC taskEntry
UINT32 taskID
SortLinkList sortList
const SchedOps * ops
UINT8 ucState
Definition: los_swtmr.h:269
UINT16 usTimerID
Definition: los_swtmr.h:271
UINTPTR uwArg
Definition: los_swtmr.h:276
UINT32 uwOverrun
Definition: los_swtmr.h:272
UINT8 ucMode
Definition: los_swtmr.h:270
UINT32 uwOwnerPid
Definition: los_swtmr.h:279
UINT64 startTime
Definition: los_swtmr.h:280
UINT32 uwInterval
Definition: los_swtmr.h:274
UINT32 uwExpiry
Definition: los_swtmr.h:275
SortLinkList stSortList
通过它挂到对应CPU核定时器链表上
Definition: los_swtmr.h:268
SWTMR_PROC_FUNC pfnHandler
Definition: los_swtmr.h:278
UINT16 usTaskPrio
Definition: los_task.h:505
UINT16 usCpuAffiMask
Definition: los_task.h:511
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UINT32 uwResved
Definition: los_task.h:513
clock_t times(struct tms *buf)
Definition: time.c:1107
time_t time(time_t *t)
Definition: time.c:1224