📄 os_core.c
字号:
*
* 输入参数 : 无
*
* 返回值 : 无
*
* 注释 : OSStartHighRdy() 必须是:
* a) 调用 OSTaskSwHook() ,
* b) 设定 OSRunning 为真
* c) 装载由 OSTCBHighRdy 指向的任务寄存器的内容
* d)执行任务
*********************************************************************************************************
*/
void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE)
{
y = OSUnMapTbl[OSRdyGrp]; /* 寻找最高优先级任务的优先级别 */
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* 指向最高优先级的任务准备运行 */
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy(); /* 执行启动任务的指定代码 */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* 统计初始化
*
* 函数描述: 该函数由应用程序调用,通过首先确定32位计数器在1秒内如果没有其他任务运行,它的使用率为多高来
* 建立CPU的使用率。 之后,CPU 使用率由一个较低的任务决定, 该任务每秒跟踪这个32位计数器,当有其
* 他任务运行时除外,CPU 的使用率由下面的公式决定
*
* OSIdleCtr
* CPU Usage (%) = 100 * (1 - ------------)
* OSIdleCtrMax
*
* 输入参数 : 无
*
* 返回值 : 无
*********************************************************************************************************
*/
#if OS_TASK_STAT_EN > 0
void OSStatInit (void)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OSTimeDly(2); /* 和时钟节拍同步 */
OS_ENTER_CRITICAL();
OSIdleCtr = 0L; /* 清零空闲计数器 */
OS_EXIT_CRITICAL();
OSTimeDly(OS_TICKS_PER_SEC); /* 确定1秒内最大空闲计数器的值 */
OS_ENTER_CRITICAL();
OSIdleCtrMax = OSIdleCtr; /* 存储1秒内的最在空闲计数器的值 */
OSStatRdy = TRUE;
OS_EXIT_CRITICAL();
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 处理系统节拍
*
* 函数描述: 该函数用于用信号通知 uC/OS-II 系统节拍的产生(也称为时钟节拍)。该函数应被节拍式的中断服务子程序
* 调用,也能被高优先级任务调用。
*
* 输入参数 : 无
*
* 返回值 : 无
*********************************************************************************************************
*/
void OSTimeTick (void)
{
#if OS_CRITICAL_METHOD == 3 /* 为CPU状态寄存器分配存储变量 */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
OSTimeTickHook(); /* 调用用户定义的钩子函数 */
#if OS_TIME_GET_SET_EN > 0
OS_ENTER_CRITICAL(); /* 更新32位节拍计数器 */
OSTime++;
OS_EXIT_CRITICAL();
#endif
if (OSRunning == TRUE)
{
ptcb = OSTCBList; /* 指向第一个任务控制块*/
while (ptcb->OSTCBPrio != OS_IDLE_PRIO) /* 作完所有的任务控制块*/
{
OS_ENTER_CRITICAL();
if (ptcb->OSTCBDly != 0)
{ /* 用延时等待事件 */
if (--ptcb->OSTCBDly == 0) /* 减少节拍计数到延时结束 */
{
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) /* 任务挂起了吗? */
{
OSRdyGrp |= ptcb->OSTCBBitY; /* 没有,Make task R-to-R (timed out)*/
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
}
else
{ /* 对, 剩下1个节拍保护 ... */
ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
} /* ... 挂起被清除 */
}
}
ptcb = ptcb->OSTCBNext; /* 指向任务控制块列表中的下一个任务控制块 */
OS_EXIT_CRITICAL();
}
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* 得到版本号
*
* 函数描述: 本函数用于返回 uC/OS-II的版本号. 返回值对应着的uC/OS-II的乘以100的版本号。
* 换句话说,版本号为2.00的返回值为200。
*
* 输入参数 : 无
*
* 返回值 : uC/OS-II 的版本号乘以100的值
*********************************************************************************************************
*/
INT16U OSVersion (void)
{
return (OS_VERSION);
}
/*$PAGE*/
/*
*********************************************************************************************************
* 哑函数
*
* 函数描述: 该函数不做任何事情它由 OSTaskDel()调用
*
* 输入参数 : 无
*
* 返回值 : 无
*********************************************************************************************************
*/
#if OS_TASK_DEL_EN > 0
void OS_Dummy (void)
{
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 事件发生使任务就绪运行
*
* 函数描述: 该函数由其他 uC/OS-II 服务函数调用并且用于使等待事件发生的任务就绪以运行。
*
* 输入参数 : pevent 指向对应于事件的事件控制块的指针
*
* msg 指向消息的指针。 该指针用于指向消息服务,如邮箱、队列。不用于其他服务函数。
*
* msk 用于清除任务控制块的状态字节位的掩码. 例如 OSSemPost() 将使用 OS_STAT_SEM
* OSMboxPost()将使用 OS_STAT_MBOX 等
*
* 返回值 : prio 就绪任务的优先级
*
* 注释 : 该函数是 uC/OS-II的内部函数,应用程序不该调用。
*********************************************************************************************************
*/
#if OS_EVENT_EN > 0
INT8U OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)
{
OS_TCB *ptcb;
INT8U x;
INT8U y;
INT8U bitx;
INT8U bity;
INT8U prio;
y = OSUnMapTbl[pevent->OSEventGrp]; /* 寻找等待消息的最高优先级任务 */
bity = OSMapTbl[y];
x = OSUnMapTbl[pevent->OSEventTbl[y]];
bitx = OSMapTbl[x];
prio = (INT8U)((y << 3) + x); /* 找到得到消息的任务的优先级别 */
if ((pevent->OSEventTbl[y] &= ~bitx) == 0x00) /* 从等待列表中删除最高优先级任务 */
{
pevent->OSEventGrp &= ~bity; /* 如果只是任务挂起则清除组位 */
}
ptcb = OSTCBPrioTbl[prio]; /* 指向任务的任务控制块的指针 */
ptcb->OSTCBDly = 0; /* 防止 OSTimeTick() 就绪任务 */
ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* 从该任务中解开事件任务块 */
#if ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) || (OS_MBOX_EN > 0)
ptcb->OSTCBMsg = msg; /* 直接发送消息给等待的任务 */
#else
msg = msg; /* 如果没有使用避免编译器发出警告 */
#endif
ptcb->OSTCBStat &= ~msk; /* 清除相关于事件类型的位 */
if (ptcb->OSTCBStat == OS_STAT_RDY)
{ /* 如果任务就绪 (可能被挂起) */
OSRdyGrp |= bity; /* 把任务放在就绪待运行列表中 */
OSRdyTbl[y] |= bitx;
}
return (prio);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 使任务进入等待事件发生的状态
*
* 函数描述: 该函数由其他 uC/OS-II 服务函数调用,由于没有事件发生,任务被挂起。
*
* 输入函数 : pevent 指向任务等待的事件控制块的指针
*
* 返回值 : 无
*
* 注释 : 该函数为 uC/OS-II的内部函数,应用程序不该调用。
**********************************************************************************************************
*/
#if OS_EVENT_EN > 0
void OS_EventTaskWait (OS_EVENT *pevent)
{
OSTCBCur->OSTCBEventPtr = pevent; /* 存储在任务控制块中指向事件控制块的指针 */
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00) /* 任务脱离就绪 */
{
OSRdyGrp &= ~OSTCBCur->OSTCBBitY; /* 如果仅是任务挂起清除事件组位 */
}
pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX; /* 把任务放到等待列表中 */
pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 由于等待事件超时,使任务处于就绪态
*
* 函数描述: 该函数由于超时发生由其他 uC/OS-II 服务函数调用使任务就绪。
*
* 输入参数 : pevent 指向就绪一个任务的事件控制块的指针
*
* 返回值 : 无
*
* 注释 : 该函数为 uC/OS-II的内部函数,应用程序不该调用。
*********************************************************************************************************
*/
#if OS_EVENT_EN > 0
void OS_EventTO (OS_EVENT *pevent)
{
if ((pevent->OSEventTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0x00)
{
pevent->OSEventGrp &= ~OSTCBCur->OSTCBBitY; /* 从ECB 的任务等待列表中删除该任务 */
}
OSTCBCur->OSTCBStat = OS_STAT_RDY; /* 设定就绪状态 */
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* 任务脱离等待事件 */
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* 初始化事件控制块的等待任务的列表
*
* 函数描述: 该函数由其他的uC/OS-II 服务函数调用以初始化事件等待任务的列表。
*
* 输入参数 : pevent 指向分配给事件的事件控制块的指针
*
* 返回值 : 无
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -