📄 os_task.c
字号:
}
else
{
err = OS_TASK_NOT_EXIST; /* 任务被删除 */
}
OS_EXIT_CRITICAL();
return (err);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 恢复一个挂起的任务
*
* 函数描述: 该函数恢复以前被挂起的任务。被挂起的任务只能通过调用函数恢复。
*
* 输入函数 : prio 待恢复任务的优先级
*
* 返回值 : OS_NO_ERR 请求的任务被恢复
* OS_PRIO_INVALID 指定的优先级是否高于允许的最大值。
* (例如 >= OS_LOWEST_PRIO)
* OS_TASK_RESUME_PRIO 待恢复的任务优先级并不存在
* OS_TASK_NOT_SUSPENDED 待恢复的任务没有被挂起
*********************************************************************************************************
*/
#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskResume (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio >= OS_LOWEST_PRIO)
{ /* 任务优先级是否有效 ? */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0)
{ /* 被挂起的任务是否存在? */
OS_EXIT_CRITICAL();
return (OS_TASK_RESUME_PRIO);
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY)
{ /* 任务是否被挂起 */
if (((ptcb->OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) && /* 清除ptcb->OSTCBStat中 */
(ptcb->OSTCBDly == 0)) /* 的OS_STAT_SUSPEND 位 */
{ /* 没有延时 */
OSRdyGrp |= ptcb->OSTCBBitY; /* 使任务就绪 */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OS_Sched(); // 有延时则消除延时后,就绪!
}
else
{
OS_EXIT_CRITICAL();
}
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_SUSPENDED);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 堆栈检验
*
* 函数描述: 该函数用于检验指定的任务堆栈中空余存储单元的数量。
*
*
* 输入参数 : prio 任务的优先级
*
* pdata 指向 OS_STK_DATA型的数据结构.
*
* 返回值 : OS_NO_ERR 成功
* OS_PRIO_INVALID 如果优先级高于许可的最大值
* (例如 > OS_LOWEST_PRIO) 或没有指定 OS_PRIO_SELF.
* OS_TASK_NOT_EXIST 期望的任务没创建
* OS_TASK_OPT_ERR 任务创建时未指定 OS_TASK_OPT_STK_CHK
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
OS_STK *pchk;
INT32U free;
INT32U size;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
{ /* 确认优先级未被其他任务占用 */
return (OS_PRIO_INVALID);
}
#endif
pdata->OSFree = 0; /* 如果失败,设定为0尺寸 */
pdata->OSUsed = 0;
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF)
{ /* 赋给自身的优先级 */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0)
{ /* 确认任务存在 */
OS_EXIT_CRITICAL();
return (OS_TASK_NOT_EXIST);
}
if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0)
{ /* 确认堆栈检验选择是否设定 */
OS_EXIT_CRITICAL();
return (OS_TASK_OPT_ERR);
}
free = 0;
size = ptcb->OSTCBStkSize;
pchk = ptcb->OSTCBStkBottom;
OS_EXIT_CRITICAL();
#if OS_STK_GROWTH == 1
while (*pchk++ == (OS_STK)0) { /* 计算堆栈中0的个数 */
free++;
}
#else
while (*pchk-- == (OS_STK)0) {
free++;
}
#endif
pdata->OSFree = free * sizeof(OS_STK); /* 计算堆栈中空余字节的数量 */
pdata->OSUsed = (size - free) * sizeof(OS_STK); /* 计算堆栈中已用字节的数量 */
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 挂起一个任务以等待
*
* 函数描述: 该函数用于挂起一个任务。任务可以挂起自身或者其他任务。
*
* 输入函数: prio 待挂起的任务。如果指定为 OS_PRIO_SELF,调用任务将挂起自身,重新调度将发生。
*
* 返回值 : OS_NO_ERR 请求任务被挂起
* OS_TASK_SUSPEND_IDLE 不允许挂起空闲任务
* OS_PRIO_INVALID 如果优先级高于许可的最大值
* (例如 > OS_LOWEST_PRIO) 或没有指定 OS_PRIO_SELF.
* OS_TASK_SUSPEND_PRIO 被挂起的任务不存在
*
* 注释 : 使用该函数要慎重。如果要挂起的任务在等待事件(例如消息、信号量、队列等),当事件到达时,将
* 阻碍任务运行。
*********************************************************************************************************
*/
#if OS_TASK_SUSPEND_EN > 0
INT8U OSTaskSuspend (INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
BOOLEAN self;
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio == OS_IDLE_PRIO)
{ /* 不许挂起空闲任务 */
return (OS_TASK_SUSPEND_IDLE);
}
if (prio >= OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
{ /* 任务优先级是否有效 ? */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF)
{ /* 赋给自身的优先级 */
prio = OSTCBCur->OSTCBPrio;
self = TRUE;
}
else if (prio == OSTCBCur->OSTCBPrio)
{ /* 判断优先级 */
self = TRUE;
}
else
{
self = FALSE; /* 没有挂起其他任务 */
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0)
{ /* 被挂起的任务是否存在? */
OS_EXIT_CRITICAL();
return (OS_TASK_SUSPEND_PRIO);
}
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
{ /* 让任务脱离就绪 */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
ptcb->OSTCBStat |= OS_STAT_SUSPEND; /* 任务挂起的状态 */
OS_EXIT_CRITICAL();
if (self == TRUE)
{ /* 只有SELF为真时,发生任务切换 */
OS_Sched();
}
return (OS_NO_ERR);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 获得任务信息
*
* 函数描述: 该函数用于获得任务的控制块信息。
*
* 输入参数 : prio 所需信息对应任务的优先级
*
* 返回值 : OS_NO_ERR 请求的任务是否被挂起
* OS_PRIO_INVALID 如果优先级高于许可的最大值
* (例如 > OS_LOWEST_PRIO) 或没有指定 OS_PRIO_SELF.
* OS_PRIO_ERR 所期望的任务不存在
*********************************************************************************************************
*/
#if OS_TASK_QUERY_EN > 0
INT8U OSTaskQuery (INT8U prio, OS_TCB *pdata)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO && prio != OS_PRIO_SELF)
{ /* 任务优先级是否有效 ? */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF)
{ /* 赋给自身的优先级 */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0)
{ /* 请求的任务是否存在? */
OS_EXIT_CRITICAL();
return (OS_PRIO_ERR);
}
memcpy(pdata, ptcb, sizeof(OS_TCB)); /* 复制任务控制块到用户存储区 */
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -