Merge pull request 'core' (#21) from danwanhao_branch into main

pull/23/head
piyl8cs5f 1 year ago
commit 0d4f941974

File diff suppressed because it is too large Load Diff

@ -28,12 +28,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*!
* @file los_swtmr.c
* @brief
* @details
* @attention @verbatim
/*基本概念
TickTick
@ -88,9 +83,7 @@
使使
使
Tick
@endverbatim
*/
Tick*/
#include "los_swtmr_pri.h"
#include "los_init.h"
#include "los_process_pri.h"
@ -113,14 +106,14 @@ LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Han
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
/* spinlock for swtmr module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);//初始化软件钟自旋锁只有SMP情况才需要只要是自旋锁都是由于CPU多核的同步
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))//持有软时钟自旋锁
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))//释放软时钟自旋锁
typedef struct {
SortLinkAttribute swtmrSortLink;
LosTaskCB *swtmrTask; /* software timer task id */
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */
LosTaskCB *swtmrTask; /* software timer task id *///定时器任务ID
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id *///定时器超时队列
} SwtmrRunqueue;
STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM];
@ -316,7 +309,7 @@ STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
return;
}
//软时钟的入口函数拥有任务的最高优先级0级
STATIC VOID SwtmrTask(VOID)
{
SwtmrHandlerItem swtmrHandle;
@ -325,7 +318,7 @@ STATIC VOID SwtmrTask(VOID)
SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()];
LOS_DL_LIST *head = &srq->swtmrHandlerQueue;
for (;;) {
for (;;) {//死循环获取队列item一直读干净为止
waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink);
if (waitTime != 0) {
SCHEDULER_LOCK(intSave);
@ -341,29 +334,30 @@ STATIC VOID SwtmrTask(VOID)
LOS_ListDelete(&swtmrHandlePtr->node);
(VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem));
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存
SwtmrHandler(&swtmrHandle);
}
}
}
//创建软时钟任务每个cpu core都可以拥有自己的软时钟任务
STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
{
UINT32 ret;
TSK_INIT_PARAM_S swtmrTask;
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
swtmrTask.pcName = "Swt_Task";
swtmrTask.usTaskPrio = 0;
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数
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) {
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是个任务系统
}
return ret;
@ -381,16 +375,16 @@ BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
}
return FALSE;
}
//回收指定进程的软时钟
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
{
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {//一个进程往往会有多个定时器
if (g_swtmrCBArray[index].uwOwnerPid == ownerID) {
LOS_SwtmrDelete(index);
LOS_SwtmrDelete(index);//删除定时器
}
}
}
//软时钟初始化注意函数在多CPU情况下会执行多次
STATIC UINT32 SwtmrBaseInit(VOID)
{
UINT32 ret;
@ -400,15 +394,15 @@ STATIC UINT32 SwtmrBaseInit(VOID)
return LOS_ERRNO_SWTMR_NO_MEMORY;
}
(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 (UINT16 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将节点挂到空闲链表
}
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
//想要用静态内存池管理就必须要使用LOS_MEMBOX_SIZE来计算申请列表的内存大小因为需要点前缀内存承载头部信息
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */
if (g_swtmrHandlerPool == NULL) {
return LOS_ERRNO_SWTMR_NO_MEMORY;
@ -536,14 +530,14 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {
ticks = swtmr->uwExpiry;
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器
ticks = swtmr->uwExpiry;//获取定时间隔
} else {
ticks = swtmr->uwInterval;
}
swtmr->ucState = OS_SWTMR_STATUS_TICKING;
swtmr->ucState = OS_SWTMR_STATUS_TICKING;//获取周期性定时器时间间隔
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;//计数状态
UINT64 responseTime = swtmr->startTime + period;
UINT64 currTime = OsGetCurrSchedTimeCycle();
if (responseTime < currTime) {
@ -584,7 +578,7 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
{
/* insert to free list */
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用
swtmr->ucState = OS_SWTMR_STATUS_UNUSED;
swtmr->uwOwnerPid = OS_INVALID_VALUE;
@ -703,7 +697,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
}
return (UINT32)time;
}
//创建定时器设置定时器的定时时长、定时模式、回调函数、并返回定时器ID
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
@ -732,7 +726,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
}
SWTMR_LOCK(intSave);
if (LOS_ListEmpty(&g_swtmrFreeList)) {
if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲列表不能为空
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_MAXSIZE;
}
@ -743,19 +737,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
SWTMR_UNLOCK(intSave);
swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet();
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;
@ -767,27 +761,27 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
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:
SwtmrStop(swtmr);
case OS_SWTMR_STATUS_TICKING://正在计数的定时器
SwtmrStop(swtmr);//先停止定时器注意这里没有break在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CRWEATED接下来就是执行启动了
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
case OS_SWTMR_STATUS_CREATED://已经创建好了
SwtmrStart(swtmr);
break;
default:
@ -799,7 +793,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;
@ -811,24 +805,24 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
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;
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:
SwtmrStop(swtmr);
case OS_SWTMR_STATUS_TICKING://正在计数
SwtmrStop(swtmr);//执行正在停止计时器操作
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -839,7 +833,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;
@ -855,11 +849,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
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;
}
@ -870,8 +864,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
case OS_SWTMR_STATUS_CREATED:
ret = LOS_ERRNO_SWTMR_NOT_STARTED;
break;
case OS_SWTMR_STATUS_TICKING:
*tick = OsSwtmrTimeGet(swtmr);
case OS_SWTMR_STATUS_TICKING://正在计数的定时器
*tick = OsSwtmrTimeGet(swtmr);//获取
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -880,7 +874,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;
@ -892,11 +886,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
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;
}
@ -905,10 +899,10 @@ 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
SwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
case OS_SWTMR_STATUS_CREATED://再删除定时器
SwtmrDelete(swtmr);
break;
default:

@ -68,13 +68,83 @@
#if (LOSCFG_BASE_CORE_TSK_LIMIT <= 0)
#error "task maxnum cannot be zero"
#endif /* LOSCFG_BASE_CORE_TSK_LIMIT <= 0 */
LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;
LITE_OS_SEC_BSS UINT32 g_taskMaxNum;
/*
使CPU
使
线
32[0-31]031
ReadyCPU
Running
Blockedsuspenddelay
退Dead
退
退退退
InvalidInvalid退
退
退
ID
IDID
ID
使
Huawei LiteOS便
TCB
(TCB)TCBstack pointer
IDTCB
*/
LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个
LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表
LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecycleList;//回收任务链表
LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数
LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores */
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;
LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件
/* spinlock for task module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin);
@ -82,7 +152,7 @@ STATIC VOID OsConsoleIDSetHook(UINT32 param1,
UINT32 param2) __attribute__((weakref("OsSetConsoleID")));
/* temp task blocks for booting procedure */
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];
LITE_OS_SEC_BSS STATIC LosTaskCB g_mainTask[LOSCFG_KERNEL_CORE_NUM];//启动引导过程中使用的临时任务
LosTaskCB *OsGetMainTask(VOID)
{
@ -92,23 +162,23 @@ LosTaskCB *OsGetMainTask(VOID)
VOID OsSetMainTask(VOID)
{
UINT32 i;
CHAR *name = "osMain";
CHAR *name = "osMain";//任务名称
SchedParam schedParam = { 0 };
schedParam.policy = LOS_SCHED_RR;
schedParam.basePrio = OS_PROCESS_PRIORITY_HIGHEST;
schedParam.priority = OS_TASK_PRIORITY_LOWEST;
//为每个CPU core 设置mainTask
for (i = 0; i < LOSCFG_KERNEL_CORE_NUM; i++) {
g_mainTask[i].taskStatus = OS_TASK_STATUS_UNUSED;
g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;
g_mainTask[i].taskID = LOSCFG_BASE_CORE_TSK_LIMIT;//128
g_mainTask[i].processCB = OS_KERNEL_PROCESS_GROUP;
#ifdef LOSCFG_KERNEL_SMP_LOCKDEP
g_mainTask[i].lockDep.lockDepth = 0;
g_mainTask[i].lockDep.waitLock = NULL;
#endif
(VOID)strncpy_s(g_mainTask[i].taskName, OS_TCB_NAME_LEN, name, OS_TCB_NAME_LEN - 1);
LOS_ListInit(&g_mainTask[i].lockList);
LOS_ListInit(&g_mainTask[i].lockList);//初始化任务锁链表,上面挂的是任务已申请到的互斥锁
(VOID)OsSchedParamInit(&g_mainTask[i], schedParam.policy, &schedParam, NULL);
}
}
@ -122,31 +192,34 @@ VOID OsSetMainTaskProcess(UINTPTR processCB)
#endif
}
}
//空闲任务每个CPU都有自己的空闲任务
LITE_OS_SEC_TEXT WEAK VOID OsIdleTask(VOID)
{
while (1) {
WFI;
while (1) {//只有一个死循环
WFI;//WFI指令arm core立即进入low-power standly state,进入休眠模式,等待中断
}
}
VOID OsTaskInsertToRecycleList(LosTaskCB *taskCB)
{
LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);
LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);//将任务挂入回收链表,等待回收
}
/*
taskOS_TCB_FROM_PENDLISTLOS_DL_LISTLosTaskCB,
task
*/
LITE_OS_SEC_TEXT_INIT VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
if (!LOS_ListEmpty(&taskCB->joinList)) {
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));
OsTaskWakeClearPendMask(resumedTask);
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join任务处理
if (!LOS_ListEmpty(&taskCB->joinList)) {//joinList中的节点身上都有阻塞标签
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));//通过贴有JOIN标签链表的第一个节点找到Task
OsTaskWakeClearPendMask(resumedTask);//清除任务的挂起标记
resumedTask->ops->wake(resumedTask);
}
}
taskCB->taskStatus |= OS_TASK_STATUS_EXIT;
taskCB->taskStatus |= OS_TASK_STATUS_EXIT;//贴上任务退出标签
}
//挂起任务任务进入等待链表Join代表是支持通过的第一个任务去唤醒其他的任务
LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_STATUS_INIT) {
@ -165,13 +238,13 @@ LITE_OS_SEC_TEXT UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
return LOS_EINVAL;
}
//任务设置分离模式Deatch和JOIN是一对有你没我的状态
LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {
if (LOS_ListEmpty(&(taskCB->joinList))) {
LOS_ListDelete(&(taskCB->joinList));
taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;
if (taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN) {//join状态时
if (LOS_ListEmpty(&(taskCB->joinList))) {//joinlist中没有数据了
LOS_ListDelete(&(taskCB->joinList));//所谓删除就是自己指向自己
taskCB->taskStatus &= ~OS_TASK_FLAG_PTHREAD_JOIN;//去掉JOIN标签
return LOS_OK;
}
/* This error code has a special purpose and is not allowed to appear again on the interface */
@ -181,39 +254,40 @@ LITE_OS_SEC_TEXT UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
return LOS_EINVAL;
}
//初始化任务模块
LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(UINTPTR processCB)
{
UINT32 index;
UINT32 size;
UINT32 ret;
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);
g_taskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT;//任务池中最多默认128个可谓铁打的任务池流水的线程
size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);//计算需分配内存总大小
/*
* This memory is resident memory and is used to save the system resources
* of task control block and will not be freed.
*/
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);
g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);//任务池常驻内存,不被释放
if (g_taskCBArray == NULL) {
ret = LOS_ERRNO_TSK_NO_MEMORY;
goto EXIT;
}
(VOID)memset_s(g_taskCBArray, size, 0, size);
LOS_ListInit(&g_losFreeTask);
LOS_ListInit(&g_taskRecycleList);
for (index = 0; index < g_taskMaxNum; index++) {
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
g_taskCBArray[index].taskID = index;
LOS_ListInit(&g_losFreeTask);//初始化空闲任务链表
LOS_ListInit(&g_taskRecycleList);//初始化回收任务链表
for (index = 0; index < g_taskMaxNum; index++) {//任务挨个初始化
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;//默认未使用,
g_taskCBArray[index].taskID = index;//任务ID[0~g_taskMaxNum-1]
g_taskCBArray[index].processCB = processCB;
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);
}
LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);//通过pendlist节点插入空闲任务列表
}//注意这里挂的是pendList节点可以取TCB也要通过OS_TCB_FROM-PENDLIST取
g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
g_taskCBArray[index].taskID = index;
g_taskCBArray[index].processCB = processCB;
ret = OsSchedInit();
ret = OsSchedInit();//调度器初始化
EXIT:
if (ret != LOS_OK) {
@ -221,41 +295,41 @@ EXIT:
}
return ret;
}
//获取IdletaskId每个CPU核都对Task进行了内部管理做到真正的并行处理
UINT32 OsGetIdleTaskId(VOID)
{
return OsSchedRunqueueIdleGet()->taskID;
}
//创建一个空闲任务
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(UINTPTR processID)
{
UINT32 ret;
TSK_INIT_PARAM_S taskInitParam;
UINT32 idleTaskID;
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;
taskInitParam.pcName = "Idle";
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清零
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;//任务栈大小 2K
taskInitParam.pcName = "Idle";//任务名称叫pcNAME
taskInitParam.policy = LOS_SCHED_IDLE;
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;
taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;//默认最低优先级31
taskInitParam.processID = processID;
#ifdef LOSCFG_KERNEL_SMP
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid());//每个idle任务只在单独的CPU上运行
#endif
ret = LOS_TaskCreateOnly(&idleTaskID, &taskInitParam);
if (ret != LOS_OK) {
return ret;
}
LosTaskCB *idleTask = OS_TCB_FROM_TID(idleTaskID);
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
idleTask->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//标记为系统任务idle任务是给CPU休息用的当然是个系统任务
OsSchedRunqueueIdleInit(idleTask);
return LOS_TaskResume(idleTaskID);
}
/*
* Description : get id of current running task.
* Description : get id of current running task. |CPUID
* Return : task id
*/
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
@ -267,7 +341,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
}
return runTask->taskID;
}
//创建指定任务同步信号量
STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -280,7 +354,7 @@ STATIC INLINE UINT32 TaskSyncCreate(LosTaskCB *taskCB)
#endif
return LOS_OK;
}
//销毁指定任务同步信号量
STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -291,6 +365,7 @@ STATIC INLINE VOID OsTaskSyncDestroy(UINT32 syncSignal)
}
#ifdef LOSCFG_KERNEL_SMP
//任务同步等待,通过信号量保持同步
STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -316,7 +391,7 @@ STATIC INLINE UINT32 OsTaskSyncWait(const LosTaskCB *taskCB)
#endif
}
#endif
//同步唤醒
STATIC INLINE VOID OsTaskSyncWake(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
@ -338,14 +413,14 @@ STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
taskCB->taskStatus = OS_TASK_STATUS_UNUSED;
LOS_ListAdd(&g_losFreeTask, &taskCB->pendList);
}
//释放任务在内核状态下占用的资源
STATIC VOID OsTaskKernelResourcesToFree(UINT32 syncSignal, UINTPTR topOfStack)
{
OsTaskSyncDestroy(syncSignal);
OsTaskSyncDestroy(syncSignal);//任务销毁,同步信息
(VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);
(VOID)LOS_MemFree((VOID *)m_aucSysMem1, (VOID *)topOfStack);//释放内核态空间
}
//释放任务资源
STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
{
UINT32 syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
@ -353,7 +428,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
UINTPTR topOfStack;
#ifdef LOSCFG_KERNEL_VM
if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {
if ((taskCB->taskStatus & OS_TASK_FLAG_USER_MODE) && (taskCB->userMapBase != 0)) {//释放用户态栈
SCHEDULER_LOCK(intSave);
UINT32 mapBase = (UINTPTR)taskCB->userMapBase;
UINT32 mapSize = taskCB->userMapSize;
@ -363,7 +438,7 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
LosProcessCB *processCB = OS_PCB_FROM_TCB(taskCB);
LOS_ASSERT(!(OsProcessVmSpaceGet(processCB) == NULL));
UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);
UINT32 ret = OsUnMMap(OsProcessVmSpaceGet(processCB), (UINTPTR)mapBase, mapSize);//解除映射
if ((ret != LOS_OK) && (mapBase != 0) && !OsProcessIsInit(processCB)) {
PRINT_ERR("process(%u) unmmap user task(%u) stack failed! mapbase: 0x%x size :0x%x, error: %d\n",
processCB->processID, taskCB->taskID, mapBase, mapSize, ret);
@ -375,36 +450,36 @@ STATIC VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
}
#endif
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务还未使用情况
topOfStack = taskCB->topOfStack;
taskCB->topOfStack = 0;
#ifdef LOSCFG_KERNEL_SMP_TASK_SYNC
syncSignal = taskCB->syncSignal;
taskCB->syncSignal = LOSCFG_BASE_IPC_SEM_LIMIT;
#endif
OsTaskKernelResourcesToFree(syncSignal, topOfStack);
OsTaskKernelResourcesToFree(syncSignal, topOfStack);//释放内核所占内存,即内核栈的栈空间
SCHEDULER_LOCK(intSave);
#ifdef LOSCFG_KERNEL_VM
OsClearSigInfoTmpList(&(taskCB->sig));
OsClearSigInfoTmpList(&(taskCB->sig));//归还信号控制块的内存
#endif
OsInsertTCBToFreeList(taskCB);
SCHEDULER_UNLOCK(intSave);
}
return;
}
//批量回收任务
LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void)
{
UINT32 intSave;
SCHEDULER_LOCK(intSave);
while (!LOS_ListEmpty(&g_taskRecycleList)) {
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));
LOS_ListDelete(&taskCB->pendList);
while (!LOS_ListEmpty(&g_taskRecycleList)) {//遍历回收链表
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));//取出任务
LOS_ListDelete(&taskCB->pendList);//重置节点
SCHEDULER_UNLOCK(intSave);
OsTaskResourcesToFree(taskCB);
OsTaskResourcesToFree(taskCB);//释放任务所占资源
SCHEDULER_LOCK(intSave);
}
@ -414,7 +489,7 @@ LITE_OS_SEC_TEXT VOID OsTaskCBRecycleToFree(void)
/*
* Description : All task entry
* Input : taskID --- The ID of the task to be run
*/
*///所有任务的入口函数OsTaskEntry是new task OsTaskStackInit时指定的
LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
{
LOS_ASSERT(!OS_TID_CHECK_INVALID(taskID));
@ -424,19 +499,19 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
* from interrupt and other cores. release task spinlock and enable
* interrupt in sequence at the task entry.
*/
LOS_SpinUnlock(&g_taskSpin);
(VOID)LOS_IntUnLock();
LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁
(VOID)LOS_IntUnLock();//恢复中断
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],
taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调出任务的入口函数
taskCB->args[2], taskCB->args[3]); /* 2 & 3: just for args array index */
if (!(taskCB->taskStatus & OS_TASK_FLAG_PTHREAD_JOIN)) {
taskCB->joinRetval = 0;
taskCB->joinRetval = 0;//结合数为0
}
OsRunningTaskToExit(taskCB, 0);
}
//任务创建参数检查
STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 poolSize = OS_SYS_MEM_SIZE;
@ -455,30 +530,30 @@ STATIC UINT32 TaskCreateParamCheck(const UINT32 *taskID, TSK_INIT_PARAM_S *initP
}
}
if (initParam->pfnTaskEntry == NULL) {
if (initParam->pfnTaskEntry == NULL) {//入口函数不能为空
return LOS_ERRNO_TSK_ENTRY_NULL;
}
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {
if (initParam->usTaskPrio > OS_TASK_PRIORITY_LOWEST) {//优先级必须大于31
return LOS_ERRNO_TSK_PRIOR_ERROR;
}
if (initParam->uwStackSize > poolSize) {
if (initParam->uwStackSize > poolSize) {//希望申请的栈大小不能大于总池子
return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
}
if (initParam->uwStackSize == 0) {
if (initParam->uwStackSize == 0) {//任何任务都必须由内核态栈所以uwStackSize不能为0
initParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
}
initParam->uwStackSize = (UINT32)ALIGN(initParam->uwStackSize, LOSCFG_STACK_POINT_ALIGN_SIZE);
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {
if (initParam->uwStackSize < LOS_TASK_MIN_STACK_SIZE) {//运行栈空间不能低于最低值
return LOS_ERRNO_TSK_STKSZ_TOO_SMALL;
}
return LOS_OK;
}
//任务栈内核态内存分配由内核态进程空间提供即KProcess进程空间
STATIC VOID TaskCBDeInit(LosTaskCB *taskCB)
{
UINT32 intSave;
@ -531,13 +606,13 @@ STATIC VOID TaskCBBaseInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
LOS_ListInit(&taskCB->joinList);
}
LOS_ListInit(&taskCB->lockList);
LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表
SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
#ifdef LOSCFG_KERNEL_VM
taskCB->futex.index = OS_INVALID_VALUE;
#endif
}
//任务初始化
STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
{
UINT32 ret;
@ -546,7 +621,7 @@ STATIC UINT32 TaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam)
LosSchedParam initSchedParam = {0};
UINT16 policy = (initParam->policy == LOS_SCHED_NORMAL) ? LOS_SCHED_RR : initParam->policy;
TaskCBBaseInit(taskCB, initParam);
TaskCBBaseInit(taskCB, initParam);//初始化任务的基本信息task->stackPointer指向内核态栈sp位置该位置存着任务初始上下文
schedParam.policy = policy;
ret = OsProcessAddNewTask(initParam->processID, taskCB, &schedParam, &numCount);
@ -598,25 +673,27 @@ STATIC UINT32 TaskStackInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam
#endif
return LOS_OK;
}
//获取一个空闲TCB
STATIC LosTaskCB *GetFreeTaskCB(VOID)
{
UINT32 intSave;
SCHEDULER_LOCK(intSave);
if (LOS_ListEmpty(&g_losFreeTask)) {
if (LOS_ListEmpty(&g_losFreeTask)) {//全局空闲task为空
SCHEDULER_UNLOCK(intSave);
PRINT_ERR("No idle TCB in the system!\n");
return NULL;
}
LosTaskCB *taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask));
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));//从g_losFreeTask链表中摘除自己
SCHEDULER_UNLOCK(intSave);
return taskCB;
}
/*
使suspendLOS_TaskResume使ready
*/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 errRet = TaskCreateParamCheck(taskID, initParam);
@ -656,7 +733,7 @@ DEINIT_TCB:
TaskCBDeInit(taskCB);
return errRet;
}
//创建任务并使该任务进入ready状态如果就绪队列中没有更高优先级的任务则运行该任务
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
{
UINT32 ret;
@ -670,7 +747,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
return LOS_ERRNO_TSK_YIELD_IN_INT;
}
if (OsProcessIsUserMode(OsCurrProcessGet())) {
if (OsProcessIsUserMode(OsCurrProcessGet())) {//当前进程为用户进程
initParam->processID = (UINTPTR)OsGetKernelInitProcess();
} else {
initParam->processID = (UINTPTR)OsCurrProcessGet();
@ -696,7 +773,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in
return LOS_OK;
}
//恢复挂起的任务是该任务进入ready状态
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
{
UINT32 intSave;
@ -711,7 +788,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
SCHEDULER_LOCK(intSave);
/* clear pending signal */
taskCB->signal &= ~SIGNAL_SUSPEND;
taskCB->signal &= ~SIGNAL_SUSPEND;//清楚挂起信号
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
errRet = LOS_ERRNO_TSK_NOT_CREATED;
@ -737,13 +814,13 @@ LOS_ERREND:
}
/*
* Check if needs to do the suspend operation on the running task.
* Return TRUE, if needs to do the suspension.
* Return FALSE, if meets following circumstances:
* 1. Do the suspension across cores, if SMP is enabled
* 2. Do the suspension when preemption is disabled
* 3. Do the suspension in hard-irq
* then LOS_TaskSuspend will directly return with 'ret' value.
* Check if needs to do the suspend operation on the running task.//检查是否需要对正在运行的任务执行挂起操作。
* Return TRUE, if needs to do the suspension. //如果需要暂停返回TRUE。
* Return FALSE, if meets following circumstances: //如果满足一下情况则返回FALSE
* 1. Do the suspension across cores, if SMP is enabled //1.如果启用了SMP则跨CPU核执行挂起操作
* 2. Do the suspension when preemption is disabled //2.当禁用抢占时则挂起
* 3. Do the suspension in hard-irq //3.在硬中断时则挂起
* then LOS_TaskSuspend will directly return with 'ret' value. //那么LOS_taskssuspend将直接返回ret值。
*/
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
@ -752,20 +829,20 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
#ifdef LOSCFG_KERNEL_SMP
/* ASYNCHRONIZED. No need to do task lock checking */
if (taskCB->currCpu != ArchCurrCpuid()) {
if (taskCB->currCpu != ArchCurrCpuid()) {//跨CPU核的情况
taskCB->signal = SIGNAL_SUSPEND;
LOS_MpSchedule(taskCB->currCpu);
LOS_MpSchedule(taskCB->currCpu);//task所属CPU执行调度
return FALSE;
}
#endif
if (!OsPreemptableInSched()) {
if (!OsPreemptableInSched()) {//不能抢占时
/* Suspending the current core's running task */
*ret = LOS_ERRNO_TSK_SUSPEND_LOCKED;
return FALSE;
}
if (OS_INT_ACTIVE) {
if (OS_INT_ACTIVE) {//正在硬抢断时
/* suspend running task in interrupt */
taskCB->signal = SIGNAL_SUSPEND;
return FALSE;
@ -773,7 +850,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
return TRUE;
}
//任务暂停参数可以不是当前任务也就是说A任务可以让B任务处于阻塞状态挂起指定的任务然后切换任务
LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
{
UINT32 errRet;
@ -786,14 +863,14 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsTaskSuspend(LosTaskCB *taskCB)
return LOS_ERRNO_TSK_ALREADY_SUSPENDED;
}
if ((tempStatus & OS_TASK_STATUS_RUNNING) &&
!OsTaskSuspendCheckOnRun(taskCB, &errRet)) {
if ((tempStatus & OS_TASK_STATUS_RUNNING) &&//如果参数任务正在运行注意多Cpu core情况贴着正在运行标签的任务并不一定是当前CPU的执行任务
!OsTaskSuspendCheckOnRun(taskCB, &errRet)) {//很有可能是别的CPU core在跑的任务
return errRet;
}
return taskCB->ops->suspend(taskCB);
}
//外部接口对OsTaskSuspend的封装
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
{
UINT32 intSave;
@ -813,7 +890,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//设置任务为不使用状态
STATIC INLINE VOID OsTaskStatusUnusedSet(LosTaskCB *taskCB)
{
taskCB->taskStatus |= OS_TASK_STATUS_UNUSED;
@ -959,7 +1036,7 @@ LOS_ERREND:
}
return ret;
}
//任务延时等待释放CPU等待时间到期后该任务会重新进入ready状态
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
{
UINT32 intSave;
@ -989,7 +1066,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
SCHEDULER_UNLOCK(intSave);
return ret;
}
//获取任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
{
UINT32 intSave;
@ -1010,7 +1087,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
SCHEDULER_UNLOCK(intSave);
return param.priority;
}
//设置指定任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
{
UINT32 intSave;
@ -1048,12 +1125,12 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
}
return LOS_OK;
}
//设置当前任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
{
return LOS_TaskPriSet(OsCurrTaskGet()->taskID, taskPrio);
}
//当前任务释放CPU并将其移到具有相同优先级的就绪任务队列的末尾。
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
{
UINT32 intSave;
@ -1099,7 +1176,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
LOS_Schedule();
}
}
//获取任务信息给shell使用的
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
{
UINT32 intSave;
@ -1129,8 +1206,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
taskCB->ops->schedParamGet(taskCB, &param);
taskInfo->usTaskStatus = taskCB->taskStatus;
taskInfo->usTaskPrio = param.priority;
taskInfo->uwStackSize = taskCB->stackSize;
taskInfo->uwTopOfStack = taskCB->topOfStack;
taskInfo->uwStackSize = taskCB->stackSize;//内核态栈大小
taskInfo->uwTopOfStack = taskCB->topOfStack;//内核态栈顶位置
taskInfo->uwEventMask = taskCB->eventMask;
taskInfo->taskEvent = taskCB->taskEvent;
taskInfo->pTaskMux = taskCB->taskMux;
@ -1141,16 +1218,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
}
taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0';
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),
taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈顶地址是高于栈顶
OS_TASK_STACK_ADDR_ALIGN);
taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);
taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前任务栈已使用了多少
taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,
taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,//获取栈的使用情况
(const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed);
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
//CPU亲和性affinity将任务绑定在指定CPU上用于多核CPU情况该函数仅在SMP模式下支持
LITE_OS_SEC_TEXT BOOL OsTaskCpuAffiSetUnsafe(UINT32 taskID, UINT16 newCpuAffiMask, UINT16 *oldCpuAffiMask)
{
#ifdef LOSCFG_KERNEL_SMP
@ -1176,17 +1253,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
UINT32 intSave;
UINT16 currCpuMask;
if (OS_TID_CHECK_INVALID(taskID)) {
if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效task由task池分配鸿蒙默认128个任务 ID范围[0:127]
return LOS_ERRNO_TSK_ID_INVALID;
}
if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {
if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {//检测cpu亲和力
return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR;
}
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//贴有未使用标签的处理
SCHEDULER_UNLOCK(intSave);
return LOS_ERRNO_TSK_NOT_CREATED;
}
@ -1194,13 +1271,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa
SCHEDULER_UNLOCK(intSave);
if (needSched && OS_SCHEDULER_ACTIVE) {
LOS_MpSchedule(currCpuMask);
LOS_Schedule();
LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标cpu
LOS_Schedule();//申请调度
}
return LOS_OK;
}
//查询任务被绑在哪个cpu上
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
{
#ifdef LOSCFG_KERNEL_SMP
@ -1214,18 +1291,18 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务必须在使用
SCHEDULER_UNLOCK(intSave);
return INVALID_CPU_AFFI_MASK;
}
cpuAffiMask = taskCB->cpuAffiMask;
cpuAffiMask = taskCB->cpuAffiMask;//获取亲和力掩码
SCHEDULER_UNLOCK(intSave);
return cpuAffiMask;
#else
(VOID)taskID;
return 1;
return 1;//单核情况直接返回10号cpu对应0x01
#endif
}
@ -1235,14 +1312,14 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID)
LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
{
UINT32 ret;
//私有且不可中断无需保护。这个任务在其他cpu核看到它时总是在运行所以它在执行代码的同时也可以继续接收信号
/*
* private and uninterruptable, no protection needed.
* while this task is always running when others cores see it,
* so it keeps receiving signals while follow code executing.
*/
LosTaskCB *runTask = OsCurrTaskGet();
if (runTask->signal == SIGNAL_NONE) {
if (runTask->signal == SIGNAL_NONE) {//意思是其他cpu发起了要干掉你的信号
return;
}
@ -1250,23 +1327,23 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskProcSignal(VOID)
/*
* clear the signal, and do the task deletion. if the signaled task has been
* scheduled out, then this deletion will wait until next run.
*/
runTask->signal = SIGNAL_NONE;
*///如果发出信号的任务以出调度就绪队列,则此删除将等待下次运行
runTask->signal = SIGNAL_NONE;//清除信号
ret = LOS_TaskDelete(runTask->taskID);
if (ret != LOS_OK) {
PRINT_ERR("Task proc signal delete task(%u) failed err:0x%x\n", runTask->taskID, ret);
}
} else if (runTask->signal & SIGNAL_SUSPEND) {
runTask->signal &= ~SIGNAL_SUSPEND;
} else if (runTask->signal & SIGNAL_SUSPEND) {//意思是其他cpu发起了要挂起你的信号
runTask->signal &= ~SIGNAL_SUSPEND;//任务贴在被其他cpu挂起的标签
/* suspend killed task may fail, ignore the result */
(VOID)LOS_TaskSuspend(runTask->taskID);
#ifdef LOSCFG_KERNEL_SMP
} else if (runTask->signal & SIGNAL_AFFI) {
runTask->signal &= ~SIGNAL_AFFI;
} else if (runTask->signal & SIGNAL_AFFI) {//意思是下次调度其他cpu要媾和你
runTask->signal &= ~SIGNAL_AFFI;//任务贴上被其他CPU媾和的标签
/* priority queue has updated, notify the target cpu */
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);
LOS_MpSchedule((UINT32)runTask->cpuAffiMask);//发生调度,此任务将移交给媾和CPU运行.
#endif
}
}
@ -1339,7 +1416,7 @@ INT32 OsUserProcessOperatePermissionsCheck(const LosTaskCB *taskCB, UINTPTR proc
return LOS_OK;
}
//创建任务之前,检查用户态任务栈的参数,是否地址在用户空间
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, TSK_INIT_PARAM_S *param)
{
UserTaskParam *userParam = NULL;
@ -1349,25 +1426,25 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID,
}
userParam = &param->userParam;
if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {
if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {//堆地址必须在用户空间
return OS_INVALID_VALUE;
}
if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {
if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间
return OS_INVALID_VALUE;
}
//堆栈必须在用户空间
if (userParam->userMapBase && !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) {
return OS_INVALID_VALUE;
}
//检查堆,栈范围
if (!LOS_IsUserAddress(userParam->userSP)) {
return OS_INVALID_VALUE;
}
return LOS_OK;
}
//创建一个用户态任务
LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_S *initParam)
{
UINT32 taskID;
@ -1376,18 +1453,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
INT32 policy;
SchedParam param;
ret = OsCreateUserTaskParamCheck(processID, initParam);
ret = OsCreateUserTaskParamCheck(processID, initParam);//检查参数,堆栈,入口地址必须在用户空间
if (ret != LOS_OK) {
return ret;
}
//这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小)
initParam->uwStackSize = OS_USER_TASK_SYSCALL_STACK_SIZE;
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;
if (processID == OS_INVALID_VALUE) {
initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级31级
if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理
SCHEDULER_LOCK(intSave);
LosProcessCB *processCB = OsCurrProcessGet();
initParam->processID = (UINTPTR)processCB;
initParam->consoleID = processCB->consoleID;
initParam->consoleID = processCB->consoleID;//任务控制台ID归属
SCHEDULER_UNLOCK(intSave);
ret = LOS_GetProcessScheduler(processCB->processID, &policy, NULL);
if (ret != LOS_OK) {
@ -1400,20 +1477,20 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsCreateUserTask(UINTPTR processID, TSK_INIT_PARAM_
initParam->deadlineUs = param.deadlineUs;
initParam->periodUs = param.periodUs;
}
} else {
initParam->policy = LOS_SCHED_RR;
initParam->processID = processID;
initParam->consoleID = 0;
} else {//进程已经创建
initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式
initParam->processID = processID;//进程ID赋值
initParam->consoleID = 0;//默认0号控制台
}
ret = LOS_TaskCreateOnly(&taskID, initParam);
ret = LOS_TaskCreateOnly(&taskID, initParam);//只创建task实体不申请调度
if (ret != LOS_OK) {
return OS_INVALID_VALUE;
}
return taskID;
}
//获取任务的调度方式
LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
{
UINT32 intSave;
@ -1426,7 +1503,7 @@ LITE_OS_SEC_TEXT INT32 LOS_GetTaskScheduler(INT32 taskID)
LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
SCHEDULER_LOCK(intSave);
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//任务不能是没有在使用
policy = -LOS_EINVAL;
OS_GOTO_ERREND();
}
@ -1438,7 +1515,7 @@ LOS_ERREND:
SCHEDULER_UNLOCK(intSave);
return policy;
}
//设置任务的调度信息
LITE_OS_SEC_TEXT INT32 LOS_SetTaskScheduler(INT32 taskID, UINT16 policy, UINT16 priority)
{
SchedParam param = { 0 };
@ -1582,12 +1659,12 @@ UINT32 LOS_TaskDetach(UINT32 taskID)
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//获取最大任务数
LITE_OS_SEC_TEXT UINT32 LOS_GetSystemTaskMaximum(VOID)
{
return g_taskMaxNum;
}
//任务池中最后一个
LosTaskCB *OsGetDefaultTaskCB(VOID)
{
return &g_taskCBArray[g_taskMaxNum];
@ -1602,44 +1679,44 @@ LITE_OS_SEC_TEXT VOID OsWriteResourceEventUnsafe(UINT32 events)
{
(VOID)OsEventWriteUnsafe(&g_resourceEvent, events, FALSE, NULL);
}
//资源回收任务
STATIC VOID OsResourceRecoveryTask(VOID)
{
UINT32 ret;
while (1) {
while (1) {//死循环,回收资源不存在退出情况,只要系统在运行资源就需要回收
ret = LOS_EventRead(&g_resourceEvent, OS_RESOURCE_EVENT_MASK,
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);//读取资源事件
if (ret & (OS_RESOURCE_EVENT_FREE | OS_RESOURCE_EVENT_OOM)) {//收到资源释放或内存异常情况
OsTaskCBRecycleToFree();
OsProcessCBRecycleToFree();
OsProcessCBRecycleToFree();//回收进程到空闲进程池
}
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
if (ret & OS_RESOURCE_EVENT_OOM) {
(VOID)OomCheckProcess();
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK//内存溢出检测任务开关
if (ret & OS_RESOURCE_EVENT_OOM) {//触发了这个事件
(VOID)OomCheckProcess();//检查进程的内存溢出情况
}
#endif
}
}
//创建一个回收资源的任务
LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
{
UINT32 ret;
UINT32 taskID;
TSK_INIT_PARAM_S taskInitParam;
ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);
ret = LOS_EventInit((PEVENT_CB_S)&g_resourceEvent);//初始化资源事件
if (ret != LOS_OK) {
return LOS_NOK;
}
(VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;
taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsResourceRecoveryTask;//入口函数
taskInitParam.uwStackSize = OS_TASK_RESOURCE_STATIC_SIZE;
taskInitParam.pcName = "ResourcesTask";
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;
taskInitParam.usTaskPrio = OS_TASK_RESOURCE_FREE_PRIORITY;//5优先级很高
ret = LOS_TaskCreate(&taskID, &taskInitParam);
if (ret == LOS_OK) {
OS_TCB_FROM_TID(taskID)->taskStatus |= OS_TASK_FLAG_NO_DELETE;
@ -1647,5 +1724,5 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
return ret;
}
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化

@ -37,30 +37,30 @@
#endif
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale;
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; //系统时钟,绝大部分部件工作的时钟源,以及所有外设的始终来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; //每秒Tick数harmony默认为每秒100次即10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //将周期转为纳秒级
/* spinlock for task module */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin);
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁
/*
* Description : Tick interruption handler
*/
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)//节拍中断处理函数harmony默认1ms触发一次
{
#ifdef LOSCFG_SCHED_TICK_DEBUG
OsSchedDebugRecordData();
#endif
#ifdef LOSCFG_KERNEL_VDSO
OsVdsoTimevalUpdate();
OsVdsoTimevalUpdate(); //更新vdso数据页时间vsdo可以直接在用户进程空间绕过系统调用获取系统时间
#endif
#ifdef LOSCFG_BASE_CORE_TICK_HW_TIME
HalClockIrqClear(); /* diff from every platform */
#endif
OsSchedTick();
OsSchedTick();//由时钟发起的调度
}

Loading…
Cancel
Save