动手写简单的嵌入式操作系统一
作者:网络转载 发布时间:[ 2013/8/14 11:30:19 ] 推荐标签:
任务创建是基于一个有序表。这种方法虽然简单直观,但也有很大缺点。比如如果建立了100个任务,又准备建立第101个任务,且第101个任务优先级是高的。那么创建任务很慢,需要前面一百个任务依次都向后移,第101个任务放在数组的前面。这是十分耗时的操作,随着任务数的增加,创建任务的时间也随着增加。后面还要讲到,这种方法建立的任务查找高优先级时,需要遍历数组,在效率上也是不快的,尤其是任务数目多时。任务创建之后,接下来的事情是何时需要任务切换,如何查找高优先级了。先说下何时需要任务切换,每个任务都是一个while(1)死循环,在里面执行到OSTimedly()时会挂起当前任务,查找高优先级的任务。每个任务的控制块中都有个延时时间的变量,当这个延时时间变量大于0,说明这个任务还处于睡眠或挂起状态,不能够被执行。因此还需要一个系统时钟函数,作为整个系统的调度中心,每到一个系统时钟中断,让所有任务的延时时间减一。
/*
*系统时钟函数,在时钟中断中调用
*/
void OSTimeTick (void)
{
int8 index;
TCB *pTCB;
uint8 flagFirstTask=0;
OS_CPU_SR cpu_sr = 0;
OS_ENTER_CRITICAL();
/*初始化*/
OSNewTCB = NULL;
/*禁止调度*/
if (OSScheLock != 0)
{
OS_EXIT_CRITICAL();
return;
}
for (index = 0;index < TaskNUM;index++)
{
pTCB = OSTCBTable+index;
/*该任务在睡眠状态,必须将所有时延都--*/
if (pTCB->TCBDelay > 0)
{
pTCB->TCBDelay--;
continue;
}
/*该任务被挂起*/
if (pTCB->TaskStat == OS_Task_Pend)
{
continue;
}
/*任务优先级查找算法,以后考虑改进查找速度*/
/* 是否找到了应该调度进去的绪任务*/
if (flagFirstTask==0)
{
/*找到了高优先级的任务,
并且比当前任务优先级高*/
if (OSCurTCB->CurPriority < pTCB->CurPriority)
{
flagFirstTask = 1;
OSNewTCB = pTCB;
continue;
}
/*找到了比当前优先级低的任务*/
if (OSCurTCB->CurPriority > pTCB->CurPriority)
{
if (OSNewTCB == NULL)
{
flagFirstTask = 1;
OSNewTCB = pTCB;
continue ;
}
else
{
flagFirstTask = 1;
continue ;
}
}
/*找到了高优先级的任务,
并且跟当前任务优先级相等*/
if (OSCurTCB->CurPriority == pTCB->CurPriority)
{
/*该任务在当前任务之后*/
if ((pTCB > OSCurTCB)||(pTCB == OSCurTCB))
{
flagFirstTask = 1;
OSNewTCB = pTCB;
continue ;
}
/*在当前任务之前或者是当前任务
则还需要继续向后搜索第一个同优先级的任务*/
if ((pTCB < OSCurTCB)&&(OSNewTCB == NULL))
{
OSNewTCB = pTCB;
continue;
}
}
continue;
}
}
OS_EXIT_CRITICAL();
}
在时钟中断里,需要调用这个函数,这个函数的作用很简单,一方面让每个任务的延时时间减一,一方面查找高优先级的任务,找到了高优先级的任务时,把 OSNewTCB = pTCB;把高优先级的任务堆栈指针赋给 OSNewTCB 。
void SysTick_Handler(void)
{
OSIntEnter(); //进入中断
OSTimeTick();
OSIntExit(); //触发任务切换软中断
}
/*
*记录中断嵌套层数
*/
void OSIntEnter (void)
{
if (NULL != OSCurTCB)
{
if (OSIntNesting < 255u)
{
OSIntNesting++; /* Increment ISR nesting level */
}
}
}
/*
*中断退出时调用,触发中断级任务切换
*/
void OSIntExit (void)
{
OS_CPU_SR cpu_sr = 0u;
if (NULL!= OSCurTCB)
{
OS_ENTER_CRITICAL();
if (OSIntNesting > 0u)
{
OSIntNesting--;
}
if (OSIntNesting == 0u)
{
/* 当所有的中断完成候再判断是否调度 */
if (OSNewTCB != OSCurTCB)
{
/* 中断级任务切换 */
OSIntCtxSw();
}
}
OS_EXIT_CRITICAL();
}
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11