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

📄 arm_00_os_core.c

📁 看看ARM菜鸟在ARM7上写的操作系统——ARM圈圈操作系统 最近在ADuC7027上写了一个ARM_00_OS
💻 C
📖 第 1 页 / 共 4 页
字号:
  {
   CopyOfIRQEN=IRQEN;  //则将IRQEN跟FIQEN的值保存到备份中
   CopyOfFIQEN=FIQEN;
   FIQCLR=0xFFFFFFFF;
   IRQCLR=0xFFFFFFFF;  //将FIQEN跟IQREN清除
  }
 OSEnCrCount++;  //进入临界段次数加1
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:退出临界段
入口参数:无。
返回:无。
备注:无。
**********************************************************************************************/
void OSExitCritical(void)
{
 if(OSEnCrCount>=1)  //如果进入临界段的次数大于等于1次
  {
   OSEnCrCount--;    //则次数减1
   if(OSEnCrCount==0)  //如果减次数减到0,则要开中断
    {
     FIQEN=CopyOfFIQEN;  //设置所需要开的中断
     IRQEN=CopyOfIRQEN;
    }
  }
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务从延时列表中删除
入口参数1:pcb。被指定的任务。
返回:0:删除失败。非0:删除成功。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
uint32 DeleteFromDelayList(OSpcb *pcb)
{
 if(pcb->Next==0){return 0;}   //如果被删除的任务为表底,则不能删除,返回删除失败
 if(pcb==OSDelayList)   //如果被删除的pcb处于表头
  {
   OSDelayList=pcb->Next;  //则延时表指向被删除任务pcb的下一个
   OSDelayList->Prior=OSDelayList;  //延时表的前趋指向它本身
  }
 else  //如果被删除的任务pcb处于中间,则
  {
   pcb->Prior->Next=pcb->Next;   //pcb的前趋的后趋,设置为pcb的后趋
   pcb->Next->Prior=pcb->Prior;  //pcb的后趋的前趋,设置为pcb的前趋
  }
 return (uint32)pcb;   //返回被删除的任务pcb
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务从就绪态列表中删除
入口参数1:pcb。被指定的任务。
返回:0:删除失败。非0:删除成功。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
uint32 DeleteFromReadyList(OSpcb * pcb)
{
 if(pcb->Next==0)return 0;  //如果被删除的任务为表底,则不能删除,返回删除失败
 if(pcb==OSReadyList)       //如果被删除的pcb处于表头
  {
   OSReadyList=pcb->Next;   //则就绪表指向被删除任务pcb的下一个
   OSReadyList->Prior=OSReadyList;  //就绪表的前趋指向它本身
  }
 else              //如果被删除的任务pcb处于中间,则
  {
   pcb->Prior->Next=pcb->Next;   //pcb的前趋的后趋,设置为pcb的后趋
   pcb->Next->Prior=pcb->Prior;   //pcb的后趋的前趋,设置为pcb的前趋
  }
 return (uint32)pcb;   //返回被删除的任务pcb
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务从挂起列表中删除
入口参数1:pcb。被指定的任务。
返回:0:删除失败。非0:删除成功。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
uint32 DeleteFromSuspendList(OSpcb *pcb)
{
 if(pcb->Next==0)return 0;  //如果被删除的任务为表底,则不能删除,返回删除失败
 if(pcb==OSSuspendList)       //如果被删除的pcb处于表头
  {
   OSSuspendList=pcb->Next;   //则挂起态表指向被删除任务pcb的下一个
   OSSuspendList->Prior=OSSuspendList;  //挂起态表的前趋指向它本身
  }
 else              //如果被删除的任务pcb处于中间,则
  {
   pcb->Prior->Next=pcb->Next;   //pcb的前趋的后趋,设置为pcb的后趋
   pcb->Next->Prior=pcb->Prior;   //pcb的后趋的前趋,设置为pcb的前趋
  }
 return (uint32)pcb;   //返回被删除的任务pcb
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务插入到挂起列表中
入口参数1:pcb。被指定的任务。
返回:无。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
void InsertToSuspendList(OSpcb * pcb)
{
 pcb->Status=OSInSuspendStatus;  //指定任务的状态设置为挂起状态
 pcb->Next=OSSuspendList;           //指定任务的后趋指向挂起态列表的表头
 OSSuspendList->Prior=pcb;          //挂起态任务列表的前趋指向指定任务pcb
 OSSuspendList=pcb;                 //挂起态列表的表头设置为刚插入的指定任务
 OSSuspendList->Prior=OSSuspendList; //挂起态列表表头的前趋指向它本身
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务插入到延时列表中
入口参数1:pcb。被指定的任务。
返回:无。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
void InsertToDelayList(OSpcb * pcb)
{
 pcb->Status=OSInDelayStatus;   //指定任务的状态设置为延时状态
 pcb->Next=OSDelayList;         //指定任务的后趋指向延时态列表的表头
 OSDelayList->Prior=pcb;        //延时态任务列表的前趋指向指定任务pcb
 OSDelayList=pcb;               //延时态列表的表头设置为刚插入的指定任务
 OSDelayList->Prior=OSDelayList; //延时态列表表头的前趋指向它本身
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:将pcb指向的任务插入到就绪表中
入口参数1:pcb。被指定的任务。
返回:无。
备注:该函数使用前,应先进入临界段。
**********************************************************************************************/
void InsertToReadyList(OSpcb *pcb)
{
 OSpcb * TempPcb;   //用来查找就绪表,确定该插入到何处
 
 pcb->Status=OSInReadyStatus;     //指定任务的状态设置为就绪态
 
 TempPcb=OSReadyList;   //设置为就绪表表头

 do
  {
   if((pcb->Priority)<=(TempPcb->Priority))   //如果要插入的任务优先级高于或者等于被查找到的任务,则将其插入
    {
     if(TempPcb==OSReadyList)     //如果被插在表头位置
      {
       pcb->Next=OSReadyList;           //指定任务的后趋指向就绪态列表的表头
       OSReadyList->Prior=pcb;          //就绪态列表的前趋指向指定任务pcb
       OSReadyList=pcb;                 //就绪态列表的表头设置为刚插入的指定任务
       OSReadyList->Prior=OSReadyList;  //就绪态列表表头的前趋指向它本身	  
      }
     else   //如果不是在表头
      {
       pcb->Next=TempPcb;       //要插入的pcb的后趋为TempPcb
       pcb->Prior=TempPcb->Prior; //要插入的pcb的前趋为TempPcb的前趋
       TempPcb->Prior->Next=pcb;  //TempPcb的前趋的后趋为pcb
       TempPcb->Prior=pcb;       //TempPcb的后趋为pcb
      }
     return;  //返回
    }
   TempPcb=TempPcb->Next;   //移到下一个
  }while(TempPcb->Next);  //直到就绪表表底为止

//如果到表低还未找到足够低的优先级,则将其插入到系统空闲任务的前面  
 pcb->Next=TempPcb;           //要插入的pcb的后趋为TempPcb
 pcb->Prior=TempPcb->Prior;    //要插入的pcb的前趋为TempPcb的前趋
 TempPcb->Prior->Next=pcb;      //TempPcb的前趋的后趋为pcb
 TempPcb->Prior=pcb;          //TempPcb的后趋为pcb
 return;
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:创建一个任务。
入口参数1:TaskEntryAddr。任务入口地址。
入口参数2:StackLength。任务的堆栈长度。一个任务的进程控制块需要68字节,保护工作寄存器需要64字节,
           另外还有函数调用等,因此一个任务至少需要140字节以上的堆栈空间。
入口参数3:Priority。任务优先级。值越小,优先级越高。系统保留0、1及0xFFFFFFF号优先级,用户不能使用这些优先级。
人口参数4:Mode。任务的代码模式。可选择为OS_ARM_MODE跟OS_THUMB_MODE。
入口参数5:TaskName。指向被创建任务的名字的字符指针。
返回:64位无符号整数。当任务创建成功时,低32位为任务堆栈的起始地址,也即是任务的PID号。高32为0。
                      当任务创建失败时,高32位不为0,可以判断任务创建失败的原因。
备注:无。
**********************************************************************************************/
uint64 OSTaskCreat(uint32 TaskEntryAddr,uint32 StackLength,uint32 Priority,uint32 Mode,uint8 *TaskName)
{
 OSpcb * TempPcb;
 uint32 StackAddr;
 uint32 i;
 
 OSEnterCritical();   //进入临界段
 StackAddr=OSMalloc(StackLength); //根据需要的长度,申请一块内存
 if(StackAddr==0)   //如果申请内存失败
  {
   return OSMemoryLack;   //返回错误号:内存不足
  }

 TempPcb=(OSpcb *)StackAddr;        //TempPcb为堆栈起始地址
 TempPcb->StackLength=StackLength;  //保存任务堆栈长度
 TempPcb->Priority=Priority;        //设置任务优先级
 TempPcb->Status=OSInDelayStatus;   //设置任务状态。新创建的任务,总是处于延时态。延时时间为1个时钟节拍。
 TempPcb->Delay=1;                  //任务延时为1个时钟节拍。任务创建后,一个时钟节拍后被转为就绪态
 TempPcb->PID=StackAddr;            //任务的PID被设置为任务的堆栈起始地址
 TempPcb->TotalRunTime=0;           //总运行时间为0
 TempPcb->RunTimeInThisRefreshPeriod=0;   //本秒内运行时间为0
 TempPcb->WaitFor=0;                      //初始化不等待资源
 TempPcb->Msg=0;                          //初始化没有接收到消息
 for(i=0;i<15;i++)                        //设置任务的标题
  {
   TempPcb->Title[i]=TaskName[i];
   if(TaskName[i]==0)break;
  }
 for(;i<15;i++)  //传递进来的标题长度不足时,补空格。
  {
   TempPcb->Title[i]=' ';
  }
 TempPcb->Title[15]=0;
 
 TempPcb->TaskSP=OSSetStack(StackAddr+StackLength,TaskEntryAddr,Mode);  //设置好任务的堆栈,并将返回的堆栈地址保存起来

 InsertToDelayList(TempPcb);   //将任务插入到延时表中
 TaskAmount++;                 //任务个数加1
 OSExitCritical();             //退出临界段
 return (uint32)TempPcb->PID;    //任务创建成功,返回任务的PID
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:任务延时NumOfTick个时钟节拍
入口参数1:NumOfTick。延迟的时钟节拍个数。
返回:无。
**********************************************************************************************/
void OSTaskDelay(uint32 NumOfTick)
{
 OSEnterCritical();  //进入临界段
 if(OSCurrentPcb->Next==(OSpcb *)0)  //如果要将系统空闲任务挂起
  {
   OSEnterCritical();  //则退出临界段,返回。因为空闲任务不能被挂起!
   return;
  }
 OSCurrentPcb->Delay=NumOfTick;     //设置延时节拍数
 DeleteFromReadyList(OSCurrentPcb); //将任务从就绪态表只删除
 InsertToDelayList(OSCurrentPcb);   //将其插入到延态时表中
 OSExitCritical();                  //退出临界段
 OSTaskSwitch();                    //任务切换
}
///////////////////////////////////////////////////////////////////////////////////////////////

/**********************************************************************************************
功能:将一个任务挂起。
入口参数:pcb。要挂起的任务的pcb。
返回:是否成功挂起。0:成功挂起。错误代码 NO_SUCH_A_TASK:没有这个任务;CAN_NOT_BE_SUSPENDED:指定的任务不能挂起
备注:无。
/*********************************************************************************************/
uint32 OSTaskSuspend(OSpcb * pcb)
{
 OSpcb * TempPcb;
 
 if(pcb==&OSReadyListBottom)  //如果要挂起系统空闲任务,
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -