os_core.lst

来自「实时系统的正确性不仅依耐系统计算的逻辑结果」· LST 代码 · 共 319 行 · 第 1/2 页

LST
319
字号
 148   1       OK_flag=0;              //创建成功标志初始化为0,表示失败
 149   1       for(i=0;i<MAX_TASK;i++)   //查找资源
 150   1        {
 151   2         if((OS_Task_List&(0x01<<i))==0)  //如果找到可用资源
 152   2          {
 153   3           Task_ID=i;                   //则保存当前资源号
 154   3           OS_Task_List|=0x01<<i;       //并标志该资源被占用
 155   3           OK_flag=1;                   //标志创建成功
 156   3           break;                       //退出查找
 157   3          }
 158   2        }
 159   1      
 160   1       if(!OK_flag)                  //如果所有资源都被占用
 161   1        {
 162   2         OS_Exit_Critical();         //退出临界段保护
 163   2         return OS_Resource_Lack;    //返回错误代码--资源不足
 164   2        }
 165   1       
 166   1       Stack_p=(unsigned char)OS_Stack[Task_ID];   //根据分配到的资源使用堆栈段
 167   1       
 168   1       for(i=0;i<S_DEPTH;i++)
 169   1        {
 170   2         ((unsigned char idata *)Stack_p)[i]=0;         //初始化清空堆栈
 171   2        }
 172   1      
 173   1      
 174   1       OS_pcb[Task_ID].Task_SP=Stack_p;                   //将该任务的堆栈栈低地址保存
 175   1       ((unsigned char idata *)Stack_p)[0]=Task_p;        //将任务入口地址保存在堆栈,压入低8位
 176   1       OS_pcb[Task_ID].Task_SP++;                         //压入一个后,堆栈加1,因为51的堆栈是往上生长的
 177   1       ((unsigned char idata *)Stack_p)[1]=Task_p>>8;     //压入高8位
 178   1      
 179   1       OS_pcb[Task_ID].Task_SP+=Num_PUSH_bytes;   //设置好堆栈指针
C51 COMPILER V8.08   OS_CORE                                                               01/17/2009 15:09:00 PAGE 4   

 180   1                                          //即任务开始进入时,堆栈要模仿成被切换返回时的样子
 181   1                                          //这时寄存器是被压栈的,且是压入了Num_PUSH_bytes个
 182   1      
 183   1      
 184   1       OS_pcb[Task_ID].Priority=Task_Priority;             //设置任务优先级
 185   1      
 186   1       OS_pcb[Task_ID].Delay=0;                            //任务初始不延时
 187   1      
 188   1       OS_pcb[Task_ID].MSG=Msg_p;                          //消息指针
*** WARNING C289 IN LINE 188 OF OS_CORE.C: '=': converting non-pointer to pointer
 189   1       
 190   1       
 191   1       
 192   1      
 193   1       
 194   1       if(OS_Running)
 195   1        {
 196   2         OS_pcb[Task_ID].Suspend=0;                       //如果在运行中建立的任务,则不挂起
 197   2        }
 198   1       else
 199   1        {
 200   2      #ifdef CPU_STAT
 201   2      
 202   2       OS_pcb[Task_ID].Suspend=1;                          //如果需要CPU使用率统计,则任务初始挂起
 203   2      
 204   2      #else
              
               OS_pcb[Task_ID].Suspend=0;                          //如果不需要CPU使用率统计,则任务初始不挂起
              
              #endif
 209   2      
 210   2         OS_Current_ID=Task_ID;                          //在开始运行之前建立的任务,要保存其ID号
 211   2        }
 212   1       OS_Exit_Critical();             //退出临界段保护
 213   1      
 214   1       return OS_Successful+Task_ID;   //返回创建成功及创建的任务ID号
 215   1      }
 216          /////////////////////////////////////////////////////////////////////////////////////////////
 217          
 218          
 219          /////////////////////////////////  释放资源  ////////////////////////////////////////////////
 220          /////////////////// 当一个任务被删除时,需要释放其占有的资源,否则别的任务不能使用  /////////
 221          void OS_Release_Resource(unsigned char Task_ID)
 222          {
 223   1       release_printer(Task_ID);  //因为我们这里只有打印机资源,所以只释放打印机,及消息接收标志
 224   1       if(Task_ID==Msg_1_Receiver)  //如果需要接收消息的任务被删除,则需要告诉发消息者,无任务接收消息
 225   1        {
 226   2         Msg_1_Receiver=0;     //
 227   2        }
 228   1                             //如果有多个独占资源,在任务被删除时,一定要记得检查是否需要释放
 229   1                             //将释放资源的代码添加到此
 230   1      }
 231          /////////////////////////////////////////////////////////////////////////////////////////////
 232          
 233          
 234          ///////////////////////////////// 删除一个任务  //////////////////////////////////////////////
 235          unsigned int OS_Task_Kill(unsigned char Task_ID)
 236          {
 237   1       OS_Enter_Critical();       //进入临界段保护
 238   1       if(Task_ID==0)             //如果任务ID为0,即空闲任务,则
 239   1        {
 240   2         OS_Exit_Critical();      //退出临界段保护
C51 COMPILER V8.08   OS_CORE                                                               01/17/2009 15:09:00 PAGE 5   

 241   2         return OS_Task_Cannot_Be_Killed+Task_ID;   //返回错误代码---该任务不能被删除
 242   2        }
 243   1       if(Task_ID>=MAX_TASK)       //如果该ID号比MAX_TASK大,则说明该任务不可能存在
 244   1        {
 245   2         OS_Exit_Critical();
 246   2         return OS_Task_Not_Exist+Task_ID;  //返回错误代码---该任务不存在
 247   2        }
 248   1       if(OS_Task_List&(0x01<<Task_ID))  //如果所要删除的任务存在
 249   1        {
 250   2         OS_pcb[Task_ID].Suspend=1;      //则先将其挂起
 251   2         OS_Task_List&=~(0x01<<Task_ID); //从任务列表中删除之
 252   2         OS_Release_Resource(Task_ID);   //并释放该任务所占用的资源
 253   2         OS_Exit_Critical();             //退出临界段保护
 254   2         if(Task_ID==OS_Current_ID)     //如果删除的是自己,则
 255   2          {
 256   3           OS_Task_Switch();            //任务切换
 257   3          }
 258   2         return OS_Successful+Task_ID;   //返回删除成功及被删除的任务的ID号
 259   2        }
 260   1       else
 261   1        {
 262   2         OS_Exit_Critical();             //如果所要删除的任务不存在
 263   2         return OS_Task_Not_Exist+Task_ID;  //则返回错误代码---该任务不存在
 264   2        }
 265   1      }
 266          /////////////////////////////////////////////////////////////////////////////////////////////
 267          
 268          ////////////////////////////////// OS 开始启动///////////////////////////////////////////////
 269          void OS_Start(void)
 270          {
 271   1       OS_pcb[OS_Current_ID].Task_SP-=Num_PUSH_bytes;    //调整任务堆栈指针,因为这时任务还未开始调度
 272   1                                                   //第一次进入中断时,会压栈。所以先将堆栈指针
 273   1                                                   //往下调Num_PUSH_bytes个字节,避免堆栈溢出
 274   1                                                   //调整后的SP紧接着的两个字节就是最后一个任务的入口地址
 275   1                                                   //在第一次中断发生时,返回地址被压入SP后面的两个地址
 276   1                                                   //在第一次进入中断后,将SP往前调整两字节,这样程序返回时,
 277   1                                                   //将返回到最后一个任务,而不再返回到主函数
 278   1      
 279   1       SP=OS_pcb[OS_Current_ID].Task_SP;                   //修改堆栈指针。使其指向任务当前任务的堆栈段
 280   1      
 281   1       TR2=1;             //启动定时器2
 282   1       EA=1;              //开中断
 283   1      while(1); 
 284   1       
 285   1      }
 286          /////////////////////////////////////////////////////////////////////////////////////////////////


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    649    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     10       3
   IDATA SIZE       =    124    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  1 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

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