⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 Rabbit 32Bit RTOS源代码
💻 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 + -