main
ruanjiangongcheng 1 year ago
parent ff517ec5e6
commit 0ab5d49361

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

Loading…
Cancel
Save