main
ruanjiangongcheng 1 year ago
parent ff517ec5e6
commit 0ab5d49361

@ -40,7 +40,7 @@
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
STATIC struct SmpOps *g_smpOps = NULL; STATIC struct SmpOps *g_smpOps = NULL;
/// 多核中次级CPU核初始化,每个核都会调用一次
STATIC VOID OsSmpSecondaryInit(VOID *arg) STATIC VOID OsSmpSecondaryInit(VOID *arg)
{ {
UNUSED(arg); UNUSED(arg);
@ -60,7 +60,7 @@ STATIC VOID OsSmpSecondaryInit(VOID *arg)
OsSchedStart(); OsSchedStart();
} }
/// 设置多核操作接口, 通过外部注册
VOID LOS_SmpOpsSet(struct SmpOps *ops) VOID LOS_SmpOpsSet(struct SmpOps *ops)
{ {
g_smpOps = ops; g_smpOps = ops;

@ -1,4 +1,67 @@
/* /*!
* @file los_swtmr.c
* @brief
* @details
* @attention @verbatim
TickTick
Tick
使
TickHuawei LiteOS
TickTick
TickTick
Tick
OS_SWTMR_STATUS_UNUSED使
OS_SWTMR_STATUS_TICKING
LOS_SwtmrStart
OS_SWTMR_STATUS_CREATED
使
make menuconfig
LOS_SwtmrCreate
LOS_SwtmrStart
TickLOS_SwtmrTimeGet
LOS_SwtmrStop
LOS_SwtmrDelete
使
使
使0
使使
使
Tick
@endverbatim
CSDN
*//*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
* *
@ -54,9 +117,9 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID) LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
{ {
SwtmrHandlerItemPtr swtmrHandlePtr = NULL; SwtmrHandlerItemPtr swtmrHandlePtr = NULL;///< 初始化软时钟自旋锁,只有SMP情况才需要,只要是自旋锁都是用于CPU多核的同步
SwtmrHandlerItem swtmrHandle; SwtmrHandlerItem swtmrHandle;///< 持有软时钟自旋锁
UINT32 ret, swtmrHandlerQueue; UINT32 ret, swtmrHandlerQueue;///< 释放软时钟自旋锁
swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue; swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue;
for (;;) { for (;;) {
@ -71,23 +134,24 @@ LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
} }
} }
} }
///创建软时钟任务,每个cpu core都可以拥有自己的软时钟任务
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID) LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
{ {
UINT32 ret, swtmrTaskID; UINT32 ret, swtmrTaskID;
TSK_INIT_PARAM_S swtmrTask; TSK_INIT_PARAM_S swtmrTask;
UINT32 cpuid = ArchCurrCpuid(); UINT32 cpuid = ArchCurrCpuid();
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); (VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask; swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask;//入口函数
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16K默认内核任务栈
swtmrTask.pcName = "Swt_Task"; swtmrTask.pcName = "Swt_Task";//任务名称
swtmrTask.usTaskPrio = 0; swtmrTask.usTaskPrio = 0;
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED; swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
#ifdef LOSCFG_KERNEL_SMP #ifdef LOSCFG_KERNEL_SMP
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid); swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);//交给当前CPU执行这个任务
#endif #endif
ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask); ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask);//创建任务并申请调度
if (ret == LOS_OK) { if (ret == LOS_OK) {
g_percpu[cpuid].swtmrTaskID = swtmrTaskID; g_percpu[cpuid].swtmrTaskID = swtmrTaskID;
OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK; OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
@ -95,7 +159,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
return ret; return ret;
} }
///回收指定进程的软时钟
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID) LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
{ {
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) { for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
@ -104,7 +168,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
} }
} }
} }
///软时钟初始化 ,注意函数在多CPU情况下会执行多次
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID) LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
{ {
UINT32 size; UINT32 size;
@ -121,16 +185,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
goto ERROR; goto ERROR;
} }
(VOID)memset_s(swtmr, size, 0, size); (VOID)memset_s(swtmr, size, 0, size);//清0
g_swtmrCBArray = swtmr; g_swtmrCBArray = swtmr;//软时钟
LOS_ListInit(&g_swtmrFreeList); LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) { for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
swtmr->usTimerID = index; swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode); LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
} }
//想要用静态内存池管理,就必须要使用LOS_MEMBOX_SIZE来计算申请的内存大小,因为需要点前缀内存承载头部信息.
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE); swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池。
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */ g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */
if (g_swtmrHandlerPool == NULL) { if (g_swtmrHandlerPool == NULL) {
ret = LOS_ERRNO_SWTMR_NO_MEMORY; ret = LOS_ERRNO_SWTMR_NO_MEMORY;
@ -314,7 +377,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
{ {
return OsSortLinkGetTargetExpireTime(&swtmr->stSortList); return OsSortLinkGetTargetExpireTime(&swtmr->stSortList);
} }
///创建定时器设置定时器的定时时长、定时器模式、回调函数并返回定时器ID
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval, LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode, UINT8 mode,
SWTMR_PROC_FUNC handler, SWTMR_PROC_FUNC handler,
@ -354,19 +417,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
SWTMR_UNLOCK(intSave); SWTMR_UNLOCK(intSave);
swtmr->uwOwnerPid = OsCurrProcessGet()->processID; swtmr->uwOwnerPid = OsCurrProcessGet()->processID;
swtmr->pfnHandler = handler; swtmr->pfnHandler = handler;//时间到了的回调函数
swtmr->ucMode = mode; swtmr->ucMode = mode; //定时器模式
swtmr->uwOverrun = 0; swtmr->uwOverrun = 0;
swtmr->uwInterval = interval; swtmr->uwInterval = interval; //周期性超时间隔
swtmr->uwExpiry = interval; swtmr->uwExpiry = interval; //一次性超时间隔
swtmr->uwArg = arg; swtmr->uwArg = arg; //回调函数的参数
swtmr->ucState = OS_SWTMR_STATUS_CREATED; swtmr->ucState = OS_SWTMR_STATUS_CREATED; //已创建状态
SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME); SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
*swtmrID = swtmr->usTimerID; *swtmrID = swtmr->usTimerID;
OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr); OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
return LOS_OK; return LOS_OK;
} }
///接口函数 启动定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID) LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
{ {
SWTMR_CTRL_S *swtmr = NULL; SWTMR_CTRL_S *swtmr = NULL;
@ -379,24 +442,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
} }
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID; swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave); SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) { if (swtmr->usTimerID != swtmrID) {//ID必须一样
SWTMR_UNLOCK(intSave); SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID; return LOS_ERRNO_SWTMR_ID_INVALID;
} }
switch (swtmr->ucState) { switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED: case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED; ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break; break;
/* /*如果定时器的状态为启动中,应先停止定时器再重新启动
* If the status of swtmr is timing, it should stop the swtmr first, * If the status of swtmr is timing, it should stop the swtmr first,
* then start the swtmr again. * then start the swtmr again.
*/ */
case OS_SWTMR_STATUS_TICKING: case OS_SWTMR_STATUS_TICKING://正在计数的定时器
OsSwtmrStop(swtmr); OsSwtmrStop(swtmr);//先停止定时器,注意这里没有break;,在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CREATED 接下来就是执行启动了
/* fall-through */ /* fall-through */
case OS_SWTMR_STATUS_CREATED: case OS_SWTMR_STATUS_CREATED:
swtmr->startTime = OsGetCurrSchedTimeCycle(); swtmr->startTime = OsGetCurrSchedTimeCycle();
@ -411,7 +474,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr); OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
return ret; return ret;
} }
///接口函数 停止定时器 参数定时任务ID
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID) LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
{ {
SWTMR_CTRL_S *swtmr = NULL; SWTMR_CTRL_S *swtmr = NULL;
@ -424,7 +487,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
} }
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT; swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID; swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave); SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) { if (swtmr->usTimerID != swtmrID) {
@ -432,15 +495,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID; return LOS_ERRNO_SWTMR_ID_INVALID;
} }
switch (swtmr->ucState) { switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED: case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED; ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建
break; break;
case OS_SWTMR_STATUS_CREATED: case OS_SWTMR_STATUS_CREATED:
ret = LOS_ERRNO_SWTMR_NOT_STARTED; ret = LOS_ERRNO_SWTMR_NOT_STARTED;//返回没有开始
break; break;
case OS_SWTMR_STATUS_TICKING: case OS_SWTMR_STATUS_TICKING:/
OsSwtmrStop(swtmr); SwtmrStop(swtmr);//执行正在停止定时器操作
break; break;
default: default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID; ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -451,7 +514,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr); OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
return ret; return ret;
} }
///接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick) LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
{ {
SWTMR_CTRL_S *swtmr = NULL; SWTMR_CTRL_S *swtmr = NULL;
@ -492,7 +555,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
SWTMR_UNLOCK(intSave); SWTMR_UNLOCK(intSave);
return ret; return ret;
} }
///接口函数 删除定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID) LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
{ {
SWTMR_CTRL_S *swtmr = NULL; SWTMR_CTRL_S *swtmr = NULL;
@ -517,7 +580,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
case OS_SWTMR_STATUS_UNUSED: case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED; ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break; break;
case OS_SWTMR_STATUS_TICKING: case OS_SWTMR_STATUS_TICKING://正在计数就先停止再删除,这里没有break;
OsSwtmrStop(swtmr); OsSwtmrStop(swtmr);
/* fall-through */ /* fall-through */
case OS_SWTMR_STATUS_CREATED: case OS_SWTMR_STATUS_CREATED:

Loading…
Cancel
Save