📄 os_task.c
字号:
/*
*********************************************************************************************************
* uC/OS-II 实时内核
* 任务管理
*
* (c) 版权 1992-2002, 所有版权归Jean J. Labrosse, Weston, FL
*
*
* 文件名称 : OS_TASK.C
* 程序作者 : Jean J. Labrosse
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include "..\test\SRC\includes.h"
#endif
/*
*********************************************************************************************************
* 改变任务的优先级
*
* 程序描述: 本函数可以动态地改变任务的优先级。但是,新改变的优先级必须有效。
*
* 输入参数: oldp 旧的优先级
*
* newp 新的优先级
*
* 返回值: OS_NO_ERR 调用成功
* OS_PRIO_INVALID 如果定义的优先级高于最大的许可范围,则返回该参数
* (例如 >= OS_LOWEST_PRIO)
* OS_PRIO_EXIST 如果新的优先级已经存在,则返回该参数
* OS_PRIO_ERR 找不到旧的优先级对应的任务,则返回该参数 (例如 旧优先级的任务已不存在)
*
*********************************************************************************************************
*/
#if OS_TASK_CHANGE_PRIO_EN > 0
INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)
{
#if OS_CRITICAL_METHOD == 3 /* 给CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
#if OS_EVENT_EN > 0
OS_EVENT *pevent;
#endif
OS_TCB *ptcb;
INT8U x;
INT8U y;
INT8U bitx;
INT8U bity;
#if OS_ARG_CHK_EN > 0
if ((oldprio >= OS_LOWEST_PRIO && oldprio != OS_PRIO_SELF) ||
newprio >= OS_LOWEST_PRIO)
{
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[newprio] != (OS_TCB *)0)
{ /* 新优先级是否已经存在? */
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
else
{
OSTCBPrioTbl[newprio] = (OS_TCB *)1; /* 保留该优先级避免其他处理 */
OS_EXIT_CRITICAL();
y = newprio >> 3; /* 预先计算减少中断隐患 */
bity = OSMapTbl[y];
x = newprio & 0x07;
bitx = OSMapTbl[x];
OS_ENTER_CRITICAL();
if (oldprio == OS_PRIO_SELF)
{ /* 是否改变自身? */
oldprio = OSTCBCur->OSTCBPrio; /* 是,得到优先级 */
}
ptcb = OSTCBPrioTbl[oldprio];
if (ptcb != (OS_TCB *)0)
{ /* 待改变优先级的任务是否存在? */
OSTCBPrioTbl[oldprio] = (OS_TCB *)0; /* 从旧优先级中去除任务控制块 */
if ((OSRdyTbl[ptcb->OSTCBY] & ptcb->OSTCBBitX) != 0x00) /* 如果任务就绪,让其脱离就绪。 */
{
if ((OSRdyTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0x00)
{
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
OSRdyGrp |= bity; /* 让新的优先级就绪 */
OSRdyTbl[y] |= bitx;
#if OS_EVENT_EN > 0
}
else
{
pevent = ptcb->OSTCBEventPtr;
if (pevent != (OS_EVENT *)0)
{ /* 从事件等待列表中移除旧的优先级 */
if ((pevent->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0)
{
pevent->OSEventGrp &= ~ptcb->OSTCBBitY;
}
pevent->OSEventGrp |= bity; /* 让新的优先级加入等待列表 */
pevent->OSEventTbl[y] |= bitx;
}
#endif
}
OSTCBPrioTbl[newprio] = ptcb; /* 设置指向新优先级任务控制块的指针 */
ptcb->OSTCBPrio = newprio; /* 设置新的任务优先级 */
ptcb->OSTCBY = y;
ptcb->OSTCBX = x;
ptcb->OSTCBBitY = bity;
ptcb->OSTCBBitX = bitx;
OS_EXIT_CRITICAL();
OS_Sched(); /* 运行就绪的最高优先级的任务 */
return (OS_NO_ERR);
}
else
{
OSTCBPrioTbl[newprio] = (OS_TCB *)0; /* 释放保留的优先级 */
OS_EXIT_CRITICAL();
return (OS_PRIO_ERR); /* 改变任务的优先级不存在 */
}
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 创建任务
*
* 函数描述: 该函数用于 uC/OS-II 管理任务的执行。任务可在启动多任务之前建立,也可在运行中的任务中建立。
* 任务不能在中断服务子程序中建立。
*
* 输入参数 : task 指向任务代码的指针
*
* pdata 当任务首先执行时,指向能把可选数据地址内的参数传递给任务的指针。 被调用和传递
* 参数如下:
*
* void Task (void *pdata)
* {
* for (;;) {
* Task code;
* }
* }
*
* ptos 指向任务堆栈栈顶的指针。 如果配置常量OS_STK_GROWTH设为1,堆栈向下增长(从高
* 存储地址到低存储地址)。因此,'pstk' 将指向堆栈的最高的有效的存储位置。如果
* OS_STK_GROWTH 设为0,'pstk' 将指向堆栈的最低的存储位置。并且,堆栈将向上增长。 memory locations.
*
* prio 任务的优先级别。每一个任务需分配不同的优先级。数字越小,优先级别越高。
*
* 返回值 : OS_NO_ERR 函数建立成功
* OS_PRIO_EXIT 任务优先级已经存在
* OS_PRIO_INVALID 指定的优先级高于允许的最大值
* (例如 >= OS_LOWEST_PRIO)
*********************************************************************************************************
*/
#if OS_TASK_CREATE_EN > 0
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;
#if OS_ARG_CHK_EN > 0
if (prio > OS_LOWEST_PRIO)
{ /* 确认优先级在许可范围之内 */
return (OS_PRIO_INVALID);
}
#endif
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) /* 确认优先级未被其他任务占用 */
{
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* 保留该优先级避免其他处理 ... */
/* ... 直到任务建立. */
OS_EXIT_CRITICAL();
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* 初始化任务堆栈 */
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
if (err == OS_NO_ERR)
{
OS_ENTER_CRITICAL();
OSTaskCtr++; /* 增加任务计数器 */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE)
{ /* 如果多任务启动寻找最高优先级任务 */
OS_Sched();
}
}
else
{
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* 放弃该优先级 */
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 创建任务 (扩展函数)
*
* 函数描述: 该函数用于 uC/OS-II 管理任务的执行。任务可在启动多任务之前建立,也可在运行中的任务中建立。
* 任务不能在中断服务子程序中建立。该函数近似于 OSTaskCreate(),除了允许指定任务的一些补充信息。
*
* 输入参数 : task 指向任务代码的指针
*
* pdata 当任务首先执行时,指向能把可选数据地址内的参数传递给任务的指针。 被调用和传递
* 参数如下:
*
* void Task (void *pdata)
* {
* for (;;) {
* Task code;
* }
* }
*
* ptos 指向任务堆栈栈顶的指针。 如果配置常量OS_STK_GROWTH设为1,堆栈向下增长(从高
* 存储地址到低存储地址)。因此,'pstk' 将指向堆栈的最高的有效的存储位置。如果
* OS_STK_GROWTH 设为0,'pstk' 将指向堆栈的最低的存储位置。并且,堆栈将向上增长。
* 'pstk' 一定指向一个有效的空余数据单元。
*
* prio 任务的优先级别。每一个任务需分配不同的优先级。数字越小,优先级别越高。
*
*
* id 任务的识别号 (0..65535)
*
* pbos 指向任务栈底的指针。如果配置常量OS_STK_GROWTH 设为1,堆栈向下增长(从高
* 存储地址到低存储地址)。因此,‘pbos' 将指向堆栈的最低的存储位置(有效)。如果
* OS_STK_GROWTH 设为0, 'pbos'将指向堆栈的最高的存储位置。堆栈从低向高增长。
* 'pbos' 一定指向一个有效的空余数据单元。
*
* stk_size 指定堆栈的容量。如果 OS_STK 设定为 INT8U,则'stk_size'则包含该数量个字节,如果
* OS_STK 定义为 INT16U,则包含该数量个半字,如果OS_STK 设定为 INT32U,则'stk_size'
* 包含该数量个字。
*
* pext 指向用户附加的数据域的指针,用来扩展任务中任务控制块。
* 例如,这个用户存储器在任务切换中能保持浮点寄存器,每个任务的执行时间,任务切换次数。
*
* opt 包含补充信息。当高8位应用时,低8位由 uC/OS-II 保留。见uCOS-II.H文件中OS_TASK_OPT_???
*
* 返回值 : OS_NO_ERR 函数建立成功
* OS_PRIO_EXIT 任务优先级已经存在
* OS_PRIO_INVALID 指定的优先级高于允许的最大值
* (例如 >= OS_LOWEST_PRIO)
*********************************************************************************************************
*/
/*$PAGE*/
#if OS_TASK_CREATE_EXT_EN > 0
INT8U OSTaskCreateExt (void (*task)(void *pd),
void *pdata,
OS_STK *ptos,
INT8U prio,
INT16U id,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -