📄 os_tasking.c
字号:
/*
*******************************************************************************
*
* MicroROS
*
* Copyright (C) 2007 <amwox@163.com>
*
* Description : 任务
*
* File : os_tasking.c
* Author : amwox
* Edition : V0.10
* History : 2007-10-29 created
* 2008-01-28 添加_AppendEvent,_RemoveEvent,_WakeupEvent
* 删除_SerachEvent
*******************************************************************************
*/
#include "..\include\MicroROS.h"
#include "..\include\os_cpu.h"
KernelData os_kernel;
#if (SEMAPHORE_EN > 0) || (MAILBOX_EN > 0) || (MUTEX_EN > 0)
/*
* Description : 在指定列表中追加一事件
* Arguments : pList 列表
* pEvent 追加事件的进程指针
* Returns :
*/
void _AppendEvent(pPID *pList, pPID pEvent)
{
pPID pTmp = *pList;
pPID pPrev = NULL;
while (pTmp != NULL) { /*找到列表尾部*/
pPrev = pTmp;
pTmp = pTmp->pEventNext;
}
if (pPrev == NULL) { /*当前列表是一个空表*/
*pList = pEvent; /*将列表的首指针指向新的事件*/
}
else {
pPrev->pEventNext = pEvent; /*追加*/
}
}
/*
* Description : 在指定列表中删除一事件
* Arguments : pList 列表
* pEvent 要删除事件的进程指针
* Returns : 返回是否删除成功
*/
BOOL _RemoveEvent(pPID *pList, pPID pEvent)
{
pPID pTmp = *pList;
pPID pPrev = NULL;
while (pTmp != NULL) {
if (pTmp == pEvent) { /*找到列表中的事件*/
break;
}
pPrev = pTmp;
pTmp = pTmp->pEventNext;
}
if (pTmp == NULL) /*不存在当前列表中*/
return FALSE;
if (pPrev == NULL) {
*pList = pEvent->pEventNext; /*当前节点是首节点*/
}
else {
pPrev->pEventNext = pEvent->pEventNext; /*删除当前节点*/
}
pEvent->pEventNext = NULL;
return TRUE;
}
/*
* Description : 唤醒列表中的所有事件
* Arguments : pList 列表
* Returns :
*/
void _WakeupEvent(pPID pList)
{
CPU_SREG cpu_sreg;
while (pList != NULL) {
OS_ENTER_CRITICAL();
if (pList->TimerCnt != LIMITLESS) /*无限制地等待是不处于定时器队列的*/
_RemoveTimer(pList);
OS_TaskResume(pList); /*唤醒*/
OS_EXIT_CRITICAL();
pList = pList->pEventNext;
}
}
#endif
/*
* Description : 删除运行队列中的进程
* Arguments : pProcess 要删除的进程
* Returns : 返回是否删除成功
*/
BOOL _RemovePID(pPID pProcess)
{
pPID pPrev,pTmp;
pPrev = NULL;
pTmp = os_kernel.pRunList ;
while (pTmp != NULL) {
if (pTmp == pProcess)
break;
pPrev = pTmp;
pTmp = pTmp->pNext;
}
if (pTmp == NULL)
return FALSE;
if (pPrev == NULL) /*找到的是首节点*/
os_kernel.pRunList = os_kernel.pRunList->pNext;
else
pPrev->pNext = pProcess->pNext;
pProcess->pNext = NULL;
return TRUE;
}
/*
* Description : 按Priority插入指定节点
* Arguments : pList 已按Priority排序的列表,0在前,255在后,相同的按FCFS原则排序
* pProcess 要插入的节点
* Returns :
*/
void _QueuePID(pPID pProcess)
{
pPID pPrev,pTmp;
pPrev = NULL;
pTmp = os_kernel.pRunList;
while (pTmp != NULL) {
if (pTmp->Priority > pProcess->Priority)
break;
pPrev = pTmp;
pTmp = pTmp->pNext;
}
if (pPrev == NULL) {
pProcess->pNext = os_kernel.pRunList ;
os_kernel.pRunList = pProcess;
}
else {
pProcess->pNext = pPrev->pNext;
pPrev->pNext = pProcess;
}
}
/*
* Description : 只是调用_Epilog,所以标注为NAKED,减少开消.如果加入了其它的在启
* 动时处理,应该去掉NAKED
* Arguments :
* Returns :
*/
NAKED void OS_Start(void)
{
os_kernel.SysLevel = 0;
os_kernel.pRunning = NULL;
_Schedule();
OS_IdleTask();
}
/*
* Description : 创建任务
* Arguments :
* Returns :
*/
void OS_TaskCreate(pPID pProcess)
{
pProcess->pCP = OS_TaskInit(pProcess->pTaskName,pProcess->pCP);
OS_TaskResume(pProcess);
}
/*
* Description : 任务恢复到运行列表,按规则排队,等待运行
* 注意:仅仅是恢复到运行列表,并不会调用任务切换
* Arguments :
* Returns :
*/
void OS_TaskResume(pPID pProcess)
{
pProcess->State |= BV(PID_READY);
_QueuePID(pProcess);
}
/*
* Description : 任务挂起
* Arguments :
* Returns :
*/
void OS_TaskSuspend(pPID pProcess)
{
pProcess->State |= BV(PID_SUSPEND);
_RemovePID(pProcess);
}
/*
* Description : 任务睡眠,不能通过任务恢复来结束睡眠时间
* Arguments :
* Returns :
*/
void OS_TaskSleep(WORD ticks)
{
CPU_SREG cpu_sreg;
OS_ENTER_CRITICAL();
pPID pTimer = os_kernel.pRunning;
OS_TaskSuspend(pTimer);
pTimer->TimerCnt = ticks;
pTimer->State |= BV(PID_IDLE);
_QueueTimer(pTimer);
OS_EXIT_CRITICAL();
_Schedule();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -