105#ifdef LOSCFG_BASE_CORE_SWTMR_ENABLE
106#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0)
107#error "swtmr maxnum cannot be zero"
118#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))
119#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))
129#ifdef LOSCFG_SWTMR_DEBUG
130#define OS_SWTMR_PERIOD_TO_CYCLE(period) (((UINT64)(period) * OS_NS_PER_TICK) / OS_NS_PER_CYCLE)
135 if (swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) {
147 if ((swtmrID > LOSCFG_BASE_CORE_SWTMR_LIMIT) || (data == NULL) ||
156 SWTMR_UNLOCK(intSave);
166#ifdef LOSCFG_SWTMR_DEBUG
170 PRINT_ERR(
"SwtmrDebugDataInit malloc failed!\n");
179#ifdef LOSCFG_SWTMR_DEBUG
181 if (data->
period != ticks) {
192#ifdef LOSCFG_SWTMR_DEBUG
202#ifdef LOSCFG_SWTMR_DEBUG
204 swtmrHandler->
swtmrID = swtmrID;
218#ifdef LOSCFG_SWTMR_DEBUG
225#ifdef LOSCFG_SWTMR_DEBUG
231#ifdef LOSCFG_SWTMR_DEBUG
244 SWTMR_UNLOCK(intSave);
253 LOS_ASSERT(swtmrHandler != NULL);
255 OsHookCall(LOS_HOOK_TYPE_SWTMR_EXPIRED, swtmr);
266 if (swtmr->
usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
267 swtmr->
usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT;
269 swtmr->
usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT;
279 SWTMR_UNLOCK(intSave);
303 UINT64 startTime = GET_SORTLIST_VALUE(sortList);
336 SCHEDULER_LOCK(intSave);
338 OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, srq->
swtmrTask);
339 SCHEDULER_UNLOCK(intSave);
363 swtmrTask.
uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
364 swtmrTask.
pcName =
"Swt_Task";
366 swtmrTask.
uwResved = LOS_TASK_STATUS_DETACHED;
367#ifdef LOSCFG_KERNEL_SMP
372 OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
393 for (
UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
406 return LOS_ERRNO_SWTMR_NO_MEMORY;
409 (VOID)memset_s(swtmr, size, 0, size);
412 for (
UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
417 size = LOS_MEMBOX_SIZE(
sizeof(
SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
420 return LOS_ERRNO_SWTMR_NO_MEMORY;
425 return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
428 for (
UINT16 index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
456 ret = LOS_ERRNO_SWTMR_TASK_CREATE_FAILED;
465 PRINT_ERR(
"OsSwtmrInit error! ret = %u\n", ret);
473#ifdef LOSCFG_KERNEL_SMP
482 if (nodeNum > temp) {
487 }
while (cpuid < LOSCFG_KERNEL_CORE_NUM);
499#ifdef LOSCFG_KERNEL_SMP
514 SCHEDULER_LOCK(intSave);
516 SCHEDULER_UNLOCK(intSave);
521 SCHEDULER_UNLOCK(intSave);
526 SCHEDULER_UNLOCK(intSave);
555 if (responseTime < currTime) {
558 responseTime = swtmr->
startTime + period;
559 PRINT_WARN(
"Swtmr already timeout! SwtmrID: %u\n", swtmr->
usTimerID);
575#ifdef LOSCFG_KERNEL_SMP
607 SWTMR_UNLOCK(intSave);
618 while (listNext != listHead) {
637 while (list != listObject) {
639 if (checkFunc((
UINTPTR)listSorted, arg)) {
652 for (
UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
667 SWTMR_UNLOCK(intSave);
680 if (
time > OS_INVALID_VALUE) {
681 time = OS_INVALID_VALUE;
706 if (
time > OS_INVALID_VALUE) {
707 time = OS_INVALID_VALUE;
723 return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED;
728 return LOS_ERRNO_SWTMR_MODE_INVALID;
731 if (handler == NULL) {
732 return LOS_ERRNO_SWTMR_PTR_NULL;
735 if (swtmrID == NULL) {
736 return LOS_ERRNO_SWTMR_RET_PTR_NULL;
741 SWTMR_UNLOCK(intSave);
742 return LOS_ERRNO_SWTMR_MAXSIZE;
746 swtmr = LOS_DL_LIST_ENTRY(sortList,
SWTMR_CTRL_S, stSortList);
748 SWTMR_UNLOCK(intSave);
758 SET_SORTLIST_VALUE(&swtmr->
stSortList, OS_SORT_LINK_INVALID_TIME);
760 OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
771 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
772 return LOS_ERRNO_SWTMR_ID_INVALID;
775 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
780 SWTMR_UNLOCK(intSave);
781 return LOS_ERRNO_SWTMR_ID_INVALID;
786 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
799 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
803 SWTMR_UNLOCK(intSave);
804 OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
815 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
816 return LOS_ERRNO_SWTMR_ID_INVALID;
819 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
824 SWTMR_UNLOCK(intSave);
825 return LOS_ERRNO_SWTMR_ID_INVALID;
830 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
833 ret = LOS_ERRNO_SWTMR_NOT_STARTED;
839 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
843 SWTMR_UNLOCK(intSave);
844 OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
855 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
856 return LOS_ERRNO_SWTMR_ID_INVALID;
860 return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
863 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
868 SWTMR_UNLOCK(intSave);
869 return LOS_ERRNO_SWTMR_ID_INVALID;
873 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
876 ret = LOS_ERRNO_SWTMR_NOT_STARTED;
882 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
885 SWTMR_UNLOCK(intSave);
896 if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
897 return LOS_ERRNO_SWTMR_ID_INVALID;
900 swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
905 SWTMR_UNLOCK(intSave);
906 return LOS_ERRNO_SWTMR_ID_INVALID;
911 ret = LOS_ERRNO_SWTMR_NOT_CREATED;
920 ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
924 SWTMR_UNLOCK(intSave);
925 OsHookCall(LOS_HOOK_TYPE_SWTMR_DELETE, swtmr);
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
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.
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
LITE_OS_SEC_TEXT VOID * LOS_MemboxAlloc(VOID *pool)
从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存.
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
释放指定的一块静态内存块
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
UINT8 * m_aucSysMem1
系统动态内存池地址的起始地址 @note_thinking 能否不要用 0,1来命名核心变量 ???
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
struct tagSwTmrCtrl SWTMR_CTRL_S
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
接口函数 停止定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
接口函数 启动定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
VOID(* SWTMR_PROC_FUNC)(UINTPTR arg)
Define the type of a callback function that handles software timer timeout.
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
接口函数 删除定时器
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, UINT8 mode, SWTMR_PROC_FUNC handler, UINT16 *swtmrID, UINTPTR arg)
创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
@ LOS_SWTMR_MODE_NO_SELFDELETE
struct tagTskInitParam TSK_INIT_PARAM_S
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
VOID LOS_MpSchedule(UINT32 target)
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
VOID OsSchedExpireTimeUpdate(VOID)
STATIC INLINE UINT64 OsGetCurrSchedTimeCycle(VOID)
STATIC INLINE UINT32 OsSchedTimeoutQueueAdjust(LosTaskCB *taskCB, UINT64 responseTime)
BOOL(* SCHED_TL_FIND_FUNC)(UINTPTR, UINTPTR)
STATIC INLINE BOOL OsTaskIsBlocked(const LosTaskCB *taskCB)
VOID OsDeleteFromSortLink(SortLinkAttribute *head, SortLinkList *node)
VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
排序链表初始化
UINT64 OsSortLinkGetTargetExpireTime(UINT64 currTime, const SortLinkList *targetSortList)
STATIC INLINE UINT16 OsGetSortLinkNodeCpuid(const SortLinkList *node)
VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu)
STATIC INLINE VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
STATIC INLINE UINT32 OsGetSortLinkNodeNum(const SortLinkAttribute *head)
UINT64 OsSortLinkGetNextExpireTime(UINT64 currTime, const SortLinkAttribute *sortLinkHeader)
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
VOID LOS_SpinLock(SPIN_LOCK_S *lock)
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
STATIC UINT32 SwtmrBaseInit(VOID)
软时钟初始化 ,注意函数在多CPU情况下会执行多次
LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
Scan a software timer.
BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
STATIC INLINE VOID SwtmrDebugDataClear(UINT32 swtmrID)
STATIC INLINE VOID SwtmrRestart(UINT64 startTime, SortLinkList *sortList, UINT16 cpuid)
STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
STATIC INLINE VOID FindIdleSwtmrRunqueue(UINT16 *idleCpuid)
STATIC INLINE VOID DeSwtmrFromTimeList(SortLinkList *node)
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList
VOID OsSwtmrResponseTimeReset(UINT64 startTime)
UINT32 OsSwtmrTaskIDGetByCpuid(UINT16 cpuid)
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
回收指定进程的软时钟
STATIC INLINE VOID SwtmrDebugDataUpdate(SWTMR_CTRL_S *swtmr, UINT32 ticks, UINT32 times)
STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
STATIC INLINE VOID SwtmrDebugDataStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
STATIC VOID SwtmrTask(VOID)
软时钟的入口函数,拥有任务的最高优先级 0 级!
BOOL OsSwtmrWorkQueueFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg)
LITE_OS_SEC_BSS SWTMR_CTRL_S * g_swtmrCBArray
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
STATIC VOID SwtmrStop(SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID AddSwtmr2TimeList(SortLinkList *node, UINT64 responseTime, UINT16 cpuid)
STATIC INLINE VOID SwtmrHandler(SwtmrHandlerItemPtr swtmrHandle)
UINT32 OsSwtmrDebugDataGet(UINT32 swtmrID, SwtmrDebugData *data, UINT32 len, UINT8 *mode)
STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin)
初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
STATIC VOID SwtmrDebugDataInit(VOID)
STATIC INLINE VOID SwtmrDebugWaitTimeCalculate(UINT32 swtmrID, SwtmrHandlerItemPtr swtmrHandler)
STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM]
STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID SwtmrWake(SwtmrRunqueue *srq, UINT64 startTime, SortLinkList *sortList)
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
LITE_OS_SEC_BSS UINT8 * g_swtmrHandlerPool
BOOL OsSwtmrDebugDataUsed(UINT32 swtmrID)
STATIC SwtmrDebugData * g_swtmrDebugData
LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
STATIC INLINE UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
STATIC VOID SwtmrAdjustCheck(UINT16 cpuid, UINT64 responseTime)
SwtmrHandlerItem * SwtmrHandlerItemPtr
@ OS_SWTMR_STATUS_CREATED
@ OS_SWTMR_STATUS_TICKING
STATIC INLINE LosTaskCB * OsGetTaskCB(UINT32 taskID)
通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块
struct LOS_DL_LIST * pstNext
UINT32(* delay)(LosTaskCB *taskCB, UINT64 waitTime)
延时执行
LOS_DL_LIST sortLink
排序链表,上面挂的任务/软件定时器
LOS_DL_LIST sortLinkNode
排序链表,注意上面挂的是一个个等待被执行的任务/软件定时器
UINT64 responseTime
响应时间,这里提取了最近需要触发的定时器/任务的时间,见于 OsAddNode2SortLink 的实现
LOS_DL_LIST node
挂入定时器超时队列,详见 SwtmrWake( ... )
LOS_DL_LIST swtmrHandlerQueue
SortLinkAttribute swtmrSortLink
SortLinkList stSortList
通过它挂到对应CPU核定时器链表上
SWTMR_PROC_FUNC pfnHandler
TSK_ENTRY_FUNC pfnTaskEntry
clock_t times(struct tms *buf)