📄 task.c
字号:
/*********************************************************************
* Copyright (c) 2011-2012,李士伟
* All rights reserved.
*文 件 名:task.c
*描 述:任务创建,删除等操作源文件
*当前版本:V1.00
*作 者:李士伟
*创建日期:2011.09.29
**********************************************************************/
#include <kernel\task.h>
#include <kernel\sched.h>
#include <mm\memory.h>
#include <kernel\flag.h>
#include <kernel\kd.h>
#include <kernel\asm.h>
/*********************************************************************
*函 数 名:OS_CreateTCB
*描 述:创建新任务时调用本函数创建初始化新任务控制块
*输入参数:ptos: 任务栈顶指针
* base: 任务栈基址,删除任务时使用该基址释放任务栈内存
* prio: 新任务优先级
*输出参数:无
*返 回 值:返回TCB指针,返回0表示创建失败
*注 意:只在创建新任务时由创建任务函数调用本函数
**********************************************************************/
OS_TCB *OS_CreateTCB(OS_STK *ptos, OS_STK *base, INT32U prio)
{
OS_TCB *ptcb;
ptcb = (OS_TCB *)malloc(sizeof(OS_TCB));
if (ptcb != NULL)
{
ptcb->StkPtr = ptos;
ptcb->StkBase = base;
ptcb->Delay = 0;
ptcb->Prio = prio;
/* 任务控制块指针为任务ID */
ptcb->TaskID = (INT32U)ptcb;
ptcb->State = OS_TASK_RUNNING;
ptcb->Event = OS_NO_EVENT;
ptcb->MsgPtr = NULL;
ptcb->QHead = NULL;
/* 将新TCB加入到TCB登记链表中 */
OS_ENTER_CRITICAL();
ptcb->Next = OSTCBList;
if(OSTCBList != NULL )
{
OSTCBList->Prev = ptcb;
}
ptcb->Prev = NULL;
OSTCBList = ptcb;
OS_EXIT_CRITICAL();
/* 将新TCB加入到TCB运行队列中 */
OS_EnterRunQ(ptcb);
return ptcb;
}
else
{
return NULL;
}
}
/*********************************************************************
*函 数 名:OS_GetTCBPtr
*描 述:获取TCB指针
*输入参数:taskID:任务ID
*输出参数:无
*返 回 值:任务TCB指针
*注 意:
**********************************************************************/
OS_TCB *OS_GetTCBPtr(INT32U taskID)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBList;
while (ptcb != NULL)
{
if (ptcb->TaskID == taskID)
{
OS_EXIT_CRITICAL();
return ptcb;
}
ptcb = ptcb->Next;
}
OS_EXIT_CRITICAL();
return NULL;
}
/*********************************************************************
*函 数 名:OS_FreeTCB
*描 述:删除任务时将调用本函数释放TCB内存
*输入参数:ptcb: 被删除任务的TCB指针
*输出参数:无
*返 回 值:无
*注 意:只在删除任务时由任务删除函数调用本函数
**********************************************************************/
void OS_FreeTCB(OS_TCB *ptcb)
{
OS_ENTER_CRITICAL();
if (ptcb->Prev == NULL)
{
/* 释放的是任务控制块链表中头结点,更新OSTCBList指针 */
OSTCBList = ptcb->Next;
if (OSTCBList !=NULL)
{
OSTCBList->Prev = NULL;
}
}
else
{
/* 释放的是任务控制块链表中非头结点,更新上一个结点的Next指针 */
(ptcb->Prev)->Next = ptcb->Next;
}
if (ptcb->Next != NULL)
{
/* 释放的是任务控制块链表中非尾结点,更新下一个结点的Prev指针 */
(ptcb->Next)->Prev = ptcb->Prev;
}
/* 从QHead所指向的队列中删除该节点 */
if (ptcb->QHead != NULL)
{
if (ptcb->QPrev == NULL)
{
*(ptcb->QHead) = ptcb->QNext;
if (*(ptcb->QHead) != NULL)
{
(*(ptcb->QHead))->QPrev = NULL;
}
}
else
{
(ptcb->QPrev)->QNext = ptcb->QNext;
}
if (ptcb->QNext != NULL)
{
(ptcb->QNext)->QPrev = ptcb->QPrev;
}
}
OS_EXIT_CRITICAL();
free(ptcb); /* 释放TCB内存块 */
}
/*********************************************************************
*函 数 名:OS_CreateTask
*描 述:创建系统或用户任务函数
*输入参数:task: 新任务主函数入口指针
* pdata: 向新任务主函数传递的参数
* stk_size: 新任务栈大小,Byte单位
* prio: 新任务优先级
* mode: 任务运行模式
*输出参数:无
*返 回 值:返回创建任务的ID , 返回0表示创建失败
*注 意:
**********************************************************************/
INT32U OS_CreateTask(void (*task)(void *pd), void *pdata,
INT32U stk_size, INT32U prio, INT32U mode)
{
OS_STK *psp;
OS_STK *base;
OS_TCB *ptcb = NULL;
base =(OS_STK *)malloc(stk_size ); /* 分配任务栈 */
if (base == NULL)
{
return OS_ERR;
}
/* 满递减栈处理,字对齐处理 */
psp =(INT32U *)(((INT32U)base + stk_size) & 0xfffffffc);
/* 初始化任务堆栈 */
psp = __OS_InitTaskStk(task, pdata, psp, mode);
/* 创建TCB */
ptcb = OS_CreateTCB(psp, base, prio);
if (ptcb != NULL) /* 创建TCB成功 */
{
OS_ENTER_CRITICAL();
OSTaskCounter++;
OS_EXIT_CRITICAL();
if((OSRunning == 1) && (OSIntNesting == 0) )
{
OS_Sched();
}
return ptcb->TaskID;
}
else /* 创建TCB失败 */
{
free(base); /* 释放栈内存 */
}
return 0;
}
/*********************************************************************
*函 数 名:API_CreateArmTask
*描 述:创建Arm用户任务函数
*输入参数:task: 新任务主函数入口指针
* pdata: 向新任务主函数传递的参数
* stk_size: 新任务栈大小,Byte单位
* prio: 新任务优先级
*输出参数:无
*返 回 值:返回创建任务的ID , 返回0表示创建失败
*注 意:
**********************************************************************/
INT32U API_CreateArmTask(void (*task)(void *pd), void *pdata,
INT32U stk_size, INT32U prio)
{
return OS_CreateTask(task, pdata, stk_size, prio, 0x10);
}
/*********************************************************************
*函 数 名:API_CreateThumbTask
*描 述:创建Thumb用户任务函数
*输入参数:task: 新任务主函数入口指针
* pdata: 向新任务主函数传递的参数
* stk_size: 新任务栈大小,Byte单位
* prio: 新任务优先级
*输出参数:无
*返 回 值:返回创建任务的ID , 返回0表示创建失败
*注 意:
**********************************************************************/
INT32U API_CreateThumbTask(void (*task)(void *pd), void *pdata,
INT32U stk_size, INT32U prio)
{
return OS_CreateTask(task, pdata, stk_size, prio, 0x30);
}
/*********************************************************************
*函 数 名:API_DeleteTask
*描 述:强制删除任务
*输入参数:taskID: 被删除任务的ID, taskID ==0 任务删除自身
*输出参数:无
*返 回 值:无
*注 意:被删除的任务要确保删除前释放申请的内存
**********************************************************************/
void API_DeleteTask(INT32U taskID)
{
OS_STK *base;
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
if ((taskID == OSTCBCur->TaskID) || (taskID == OS_TASK_SELF_ID))
{
/* 删除任务自身并切换到高优先级的就绪任务运行 */
base = OSTCBCur->StkBase;
OS_FreeTCB(OSTCBCur); /* 释放任务TCB内存 */
free(base); /* 释放任务栈内存 */
OSTCBHighRdy = OS_FindNextRunTask();
OSTaskCounter--;
if ( OSIntNesting == 0)
{
OS_StartHighRdyTask();
}
}
else
{ /* 删除一个未获处理机的任务 */
ptcb = OS_GetTCBPtr(taskID);
if (ptcb == NULL)
{
OS_EXIT_CRITICAL();
return ;
}
base = ptcb->StkBase;
OS_FreeTCB(ptcb);
free(base);
OSTaskCounter--;
}
OS_EXIT_CRITICAL();
}
/*********************************************************************
*函 数 名:API_GetTaskID
*描 述:获得任务自身ID
*输入参数:无
*输出参数:无
*返 回 值:任务ID
*注 意:
**********************************************************************/
INT32U API_GetTaskID()
{
return OSTCBCur->TaskID;
}
/*********************************************************************
*函 数 名:API_SuspendTask
*描 述:挂起任务
*输入参数:taskID: 被挂起的任务ID
*输出参数:无
*返 回 值:无
*注 意:
**********************************************************************/
void API_SuspendTask(INT32U taskID)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
if (taskID == OS_TASK_SELF_ID)
{
ptcb = OSTCBCur;
}
else
{
ptcb = OS_GetTCBPtr(taskID);
}
if (ptcb !=NULL)
{
ptcb->State |= OS_TASK_SUSPEND;
}
OS_EXIT_CRITICAL();
OS_Sched();
return ;
}
/*********************************************************************
*函 数 名:API_ResumeTask
*描 述:恢复挂起的任务
*输入参数:taskID: 被挂起的任务ID
*输出参数:无
*返 回 值:无
*注 意:
**********************************************************************/
void API_ResumeTask(INT32U taskID)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OS_GetTCBPtr(taskID);
if (ptcb != NULL)
{
ptcb->State &= ~(OS_TASK_SUSPEND);
}
OS_EXIT_CRITICAL();
}
/*********************************************************************
*函 数 名:API_SwapPrio
*描 述:当前运行的任务与一个任务优交换先级
*输入参数:taskID被交换优先级任务的ID
*输出参数:无
*返 回 值:无
*注 意:该函数主要用于防止优先级反转现象
**********************************************************************/
void API_SwapPrio(INT32U taskID)
{
OS_TCB *ptcb;
INT32U prio;
OS_ENTER_CRITICAL();
if (OSIntNesting > 0)
{
OS_EXIT_CRITICAL();
return ;
}
ptcb = OS_GetTCBPtr(taskID);
if (ptcb != NULL)
{
prio = ptcb->Prio;
ptcb->Prio = OSTCBCur->Prio;
OSTCBCur->Prio = prio;
}
OS_EXIT_CRITICAL();
OS_Sched();
}
/*********************************************************************
*函 数 名:API_FindHighestPrio
*描 述:查找所有任务中最高的优先级
*输入参数:无
*输出参数:无
*返 回 值:最高优先级
*注 意:该函数主要用于创建任务取优先级时作为根据
**********************************************************************/
INT32U API_FindHighestPrio(void)
{
INT32U prio=0;
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBList;
while (ptcb != NULL)
{
if (prio < ptcb->Prio)
{
prio = ptcb->Prio;
}
ptcb = ptcb->Next;
}
OS_EXIT_CRITICAL();
return prio;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -