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

📄 os_core.c

📁 本RTOS参考 usOS-II, ARM-RTX
💻 C
📖 第 1 页 / 共 2 页
字号:
 uint8 y;
 uint8 prio; 
  
    
    //while(OSRdyGrp!=0)
    if(OSRdyGrp!=0)
    {
      y             = OSUnMapTbl[OSRdyGrp];            //计算优先级,先计算组号
      prio=(INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
      
      fun=Tasks_TCB[prio].pTask;
      
      //if((OSRdyTbl[y] &= ~OSMapTbl[prio&0x07])==0)  //任务从就绪表中删除
      //  OSRdyGrp &=  ~OSMapTbl[y];
      
      if(fun!=0)
      {
        //fun();
        OSCurrentTaskID=prio;
      }
    }
    
  // The scheduler enters idle mode at this point 
  //Sys_Go_To_Sleep();
}

/*
//任务延时
1.1 计算当前任务使用堆栈情况
1.2 保存任务特殊功能寄存器
1.3 保存任务堆栈+任务特殊功能寄存器->堆栈备份空间
1.4 切换任务
2.1 从堆栈备份空间->恢复新的就绪的任务的堆栈
2.2 恢复任务特殊功能寄存器
2.3 将新任务原来断点地址压入堆栈
*/

//#pragma disable  //禁止所有中断
void os_dly_wait( U16 delay_time ) SMALL
//void  OSTimeDly (uint16 ticks, uint8 prio) SMALL
{//uint8 SPtemp;
 uint8 data IEtemp;
    
    //SPtemp=Read_data(SP--);//将堆栈中的中断标志读出来 #pragma disable  //禁止所有中断
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if (delay_time > 0) 
    {                                                      /* 0 means no delay!         */
        //IrqAll_Unable();    //总中断禁止  IrqT0_Unable();  //定时器0中断禁止
        
        Tasks_TCB[OSCurrentTaskID].OSTCBStat = WAIT_DLY; //进入延时等待
        //1.任务从就绪表中删除,2.如果一组中无如何任务就绪,那么删除组标志
        if((OSRdyTbl[OSCurrentTaskID>>3] &= ~OSMapTbl[OSCurrentTaskID&0x07])==0)  //任务从就绪表中删除
          OSRdyGrp    &= ~OSMapTbl[OSCurrentTaskID>>3];   // prio>>3-->prio/8, //prio&0x07-->prio%8
        Tasks_TCB[OSCurrentTaskID].OSTCBDly = delay_time; // Load delay_time in TCB
        //IrqAll_Enable();    //总中断允许  IrqT0_Enable();          //打开T0中断允许
    }
    
    TF0=1;//设置T0中断,调用任务切换
    
/*    
    //1.2 保存任务特殊功能寄存器
  #ifdef DEBUG
    SP += 13;
    //方便在本文件中调试,查看代码方便,将多占2byte堆栈,和一点代码空间
    Push_Reg();
  #else
    #pragma asm
     ;//压栈和出栈按中断压栈和出栈的顺序
	   PUSH ACC
     PUSH B
     PUSH DPH
     PUSH DPL
     PUSH PSW
     PUSH 0
     PUSH 1
     PUSH 2
     PUSH 3
     PUSH 4
     PUSH 5
     PUSH 6
     PUSH 7
    #pragma ENDASM
  #endif
    
    //下次任务运行地址是从调用os_dly_wait()地址之后开始运行
    OSIntExit();
    
    //2.2 恢复任务特殊功能寄存器
  #ifdef DEBUG
    //方便在本文件中调试,查看代码方便,将多占2byte堆栈,和一点代码空间
    Pop_Reg();
    SP -= 13;
  #else
    #pragma ASM
    #pragma ENDASM
  #endif
        
*/    
    
    //OS_AllIRQ_Enable(); //总中断允许
    IE=IEtemp;  //恢复所有中断状态
    //DelayNop(10);
}

/*
 wait_flags    // Bit pattern of events to wait for
 timeout       // Length of time to wait for event
*/

OS_RESULT os_evt_wait_or ( EVENT_BIT wait_flags,  U16 timeout )
{uint8 data IEtemp;
   
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if (timeout > 0) 
    {                                                      /* 0 means no delay!         */
        //IrqAll_Unable();    //总中断禁止  IrqT0_Unable();  //定时器0中断禁止
        
        Tasks_TCB[OSCurrentTaskID].OSTCBStat = WAIT_OR; //进入延时等待
        Tasks_TCB[OSCurrentTaskID].events = wait_flags; //等待事件
        //1.任务从就绪表中删除,2.如果一组中无如何任务就绪,那么删除组标志
        if((OSRdyTbl[OSCurrentTaskID>>3] &= ~OSMapTbl[OSCurrentTaskID&0x07])==0)  //任务从就绪表中删除
          OSRdyGrp    &= ~OSMapTbl[OSCurrentTaskID>>3];   // prio>>3-->prio/8, //prio&0x07-->prio%8
        Tasks_TCB[OSCurrentTaskID].OSTCBDly = timeout; // Load delay_time in TCB
        //IrqAll_Enable();    //总中断允许  IrqT0_Enable();          //打开T0中断允许
        
        TF0=1;//设置T0中断,调用任务切换
    }
    IE=IEtemp;  //恢复所有中断状态
    
    DelayNop(1);
    
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if( Tasks_TCB[OSCurrentTaskID].OSTCBDly == 0)
    {
      Tasks_TCB[OSCurrentTaskID].events = 0; //等待事件清0
      IE=IEtemp;  //恢复所有中断状态
      return(OS_R_TMO);
    }
    else
    {
      Tasks_TCB[OSCurrentTaskID].OSTCBDly = 0; //等待延时清0
      IE=IEtemp;  //恢复所有中断状态
      return(OS_R_EVT);
    }
}

OS_RESULT os_evt_wait_and ( EVENT_BIT wait_flags,  U16 timeout )
{uint8 data IEtemp;
   
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if (timeout > 0) 
    {                                                      /* 0 means no delay!         */
        //IrqAll_Unable();    //总中断禁止  IrqT0_Unable();  //定时器0中断禁止
        
        Tasks_TCB[OSCurrentTaskID].OSTCBStat = WAIT_AND; //进入延时等待
        Tasks_TCB[OSCurrentTaskID].events = wait_flags; //等待事件
        //1.任务从就绪表中删除,2.如果一组中无如何任务就绪,那么删除组标志
        if((OSRdyTbl[OSCurrentTaskID>>3] &= ~OSMapTbl[OSCurrentTaskID&0x07])==0)  //任务从就绪表中删除
          OSRdyGrp    &= ~OSMapTbl[OSCurrentTaskID>>3];   // prio>>3-->prio/8, //prio&0x07-->prio%8
        Tasks_TCB[OSCurrentTaskID].OSTCBDly = timeout; // Load delay_time in TCB
        //IrqAll_Enable();    //总中断允许  IrqT0_Enable();          //打开T0中断允许
        
        TF0=1;//设置T0中断,调用任务切换
    }
    IE=IEtemp;  //恢复所有中断状态
    
    DelayNop(1);
    
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if( Tasks_TCB[OSCurrentTaskID].OSTCBDly == 0)
    {
      Tasks_TCB[OSCurrentTaskID].events = 0; //等待事件清0
      IE=IEtemp;  //恢复所有中断状态
      return(OS_R_TMO);
    }
    else
    {
      Tasks_TCB[OSCurrentTaskID].OSTCBDly = 0; //等待延时清0
      IE=IEtemp;  //恢复所有中断状态
      return(OS_R_EVT);
    }
}

/*
event_flags // Bit pattern of event flags to set
task        // The task that the events apply to
*/
void os_evt_set ( EVENT_BIT event_flags, OS_TID TaskID )
{uint8 data IEtemp;
   
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if( (Tasks_TCB[TaskID].events & event_flags) != 0 )//是等待的事件发生才处理,否则忽略发生的事件
    {
      Tasks_TCB[TaskID].events &= ~event_flags;
      if( (Tasks_TCB[TaskID].OSTCBStat == WAIT_OR) || //只要有事件发生
          (Tasks_TCB[TaskID].OSTCBStat == WAIT_AND && Tasks_TCB[TaskID].events==0) ) //有事件发生,并且所有事件都发生
      {
         OSRdyGrp               |= OSMapTbl[TaskID>>3];     //prio>>3-->prio/8
         OSRdyTbl[TaskID>>3]      |= OSMapTbl[TaskID&0x07];   //prio&0x07-->prio%8
         Tasks_TCB[TaskID].OSTCBStat = READY; //进入准备状态
         
         TF0=1;//设置T0中断,调用任务切换
      }
    }
    
    IE=IEtemp;  //恢复所有中断状态
}
/*
中断调用
event_flags // Bit pattern of event flags to set
task        // The task that the events apply to
*/
void isr_evt_set ( EVENT_BIT event_flags, OS_TID TaskID )
{uint8 data IEtemp;
   
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if( (Tasks_TCB[TaskID].events & event_flags) != 0 )//是等待的事件发生才处理,否则忽略发生的事件
    {
      Tasks_TCB[TaskID].events &= ~event_flags;
      if( (Tasks_TCB[TaskID].OSTCBStat == WAIT_OR) || //只要有事件发生
          (Tasks_TCB[TaskID].OSTCBStat == WAIT_AND && Tasks_TCB[TaskID].events==0) ) //有事件发生,并且所有事件都发生
      {
         OSRdyGrp               |= OSMapTbl[TaskID>>3];     //prio>>3-->prio/8
         OSRdyTbl[TaskID>>3]      |= OSMapTbl[TaskID&0x07];   //prio&0x07-->prio%8
         Tasks_TCB[TaskID].OSTCBStat = READY; //进入准备状态
         
         TF0=1;//设置T0中断,调用任务切换
      }
    }
    
    IE=IEtemp;  //恢复所有中断状态
}

/*
设置任务运行间隔时间
interval_time );   // Time interval for periodic wake-up
*/
void os_itv_set ( U16 interval_time )
{uint8 data IEtemp;
   
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    if (interval_time > 0) 
    {                                                      
        Tasks_TCB[OSCurrentTaskID].OSTCBPer=interval_time;//设置任务运行间隔时间
        
    }
    
    IE=IEtemp;  //恢复所有中断状态
}

/*
等待任务运行间隔时间到
*/
void os_itv_wait (void)
{uint8 data IEtemp;
    
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    
    Tasks_TCB[OSCurrentTaskID].OSTCBStat = WAIT_ITV; //任务进入间隔运行
    if((OSRdyTbl[OSCurrentTaskID>>3] &= ~OSMapTbl[OSCurrentTaskID&0x07])==0)  //任务从就绪表中删除
      OSRdyGrp    &= ~OSMapTbl[OSCurrentTaskID>>3];
    Tasks_TCB[OSCurrentTaskID].OSTCBDly = Tasks_TCB[OSCurrentTaskID].OSTCBPer;//
    
    TF0=1;//设置T0中断,调用任务切换
    
    IE=IEtemp;  //恢复所有中断状态
}

/*********************************************************************************************************
** 函数名称: OSTaskSuspend
** 功能描述: 使指定任务休眠,但不进行任务切换
** 输 入: TaskID : 任务ID
** 输 出: 无
** 全局变量: 
********************************************************************************************************/
//挂起一个任务
//#pragma disable  //禁止所有中断
void OSTaskSuspend (uint8 TaskID)	SMALL
{uint8 data IEtemp;
//OS_TCB    *ptcb;
  
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    //ptcb=&Tasks_TCB[TaskID];
    //Tasks_TCB[TaskID].OSTCBStat      |= OS_STAT_SUSPEND;  //
    Tasks_TCB[TaskID].OSTCBStat = INACTIVE; //任务挂起
    //1.任务从就绪表中删除,2.如果一组中无如何任务就绪,那么删除组标志
    if((OSRdyTbl[TaskID>>3] &= ~OSMapTbl[TaskID&0x07])==0)  //任务从就绪表中删除
      OSRdyGrp    &= ~OSMapTbl[TaskID>>3];   //TaskID>>3-->TaskID/8, //TaskID&0x07-->TaskID%8                  
  
    TF0=1;//设置T0中断,调用任务切换
    IE=IEtemp;  //恢复所有中断状态
}

//唤醒挂起的任务
//#pragma disable  //禁止所有中断

void OSTaskResume (uint8 TaskID) SMALL
{uint8 data IEtemp;
//OS_TCB    *ptcb;
  
    IEtemp=IE;//保存中断
    OS_AllIRQ_Unable(); //总中断禁止
    //ptcb=&Tasks_TCB[TaskID];
    //if (((Tasks_TCB[TaskID].OSTCBStat &= ~OS_STAT_SUSPEND) == OS_STAT_RDY) &&      // Remove suspension 
    if ( (Tasks_TCB[TaskID].OSTCBStat == INACTIVE) &&
        (Tasks_TCB[TaskID].OSTCBDly  == 0) )
    {
      //Make task ready to run
      OSRdyGrp               |= OSMapTbl[TaskID>>3];     //TaskID>>3-->TaskID/8
      OSRdyTbl[TaskID>>3]      |= OSMapTbl[TaskID&0x07];   //TaskID&0x07-->TaskID%8
      Tasks_TCB[TaskID].OSTCBStat = READY; //进入准备状态
      
      TF0=1;//设置T0中断,调用任务切换
    }
    //TF0=1;//设置T0中断,调用任务切换
    IE=IEtemp;  //恢复所有中断状态
}

⌨️ 快捷键说明

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