×
嵌入式 > 技术百科 > 详情

自己写单片机操做系统3-任务创建和调度

发布时间:2020-06-16 发布时间:
|
如果存在两个或以上的任务调度就需要将栈保CPU的寄存器了。这个地方就是各个MCU不同的地方了。
这个要看MCU进入中断的流程才能知道栈需要怎么保护。

OS_STK* InitStkBuff(VOID_FUN_PTR task,OS_STK* pstk)
{
   pstk--;        
    *pstk = (U16)(((U32)task) >> 8);    存要执行的函数
    pstk--;                                
    *pstk = 0xFFFF; //IY        存y寄存器
    (pstk)--;
    *pstk = 0x1111; //IX        存x寄存器
    pstk--;
    *pstk = 0xAA;//A;            存A
    ((U8*)pstk)--;        A和B都是8位的在寄存器中是一起放在一个16位中的、
    *pstk = 0xBB; //B        存B
    ((U8*)pstk)--; //在中断中需要多保存一次page页,所以需要留一个空间出来
   return pstk;
}
 void CreatTask(VOID_FUN_PTR task,OS_STK *pStk,U8 stkSize,U8 osPior)
{
 OsTaskObjTbl[osPior].Task = task;
 OsTaskObjTbl[osPior].TaskSp = pStk;
 OsTaskObjTbl[osPior].stkSize = stkSize;
 OsTaskObjTbl[osPior].taskDly = 0;
 OsTaskObjTbl[osPior].taskState = TASK_STATE_READY;
 OsTaskObjTbl[osPior].nextTask = IdelTask;
 OsTaskObjTbl[osPior].TaskSp = InitStkBuff(task,pStk);       将修改后的sp给到任务的sp中
}
 任务调度函数

void Os_Schel(void)
{
 U8 i;
 OldTask = HeadTask;
 for(i = 0;i < TASK_SIZE;i++)
 {
  if(OsTaskObjTbl[i].taskState == TASK_STATE_READY) 直接查看任务的状态,是否已经就绪
  {
   HeadTask = &OsTaskObjTbl[i];
   break;
  }
 }
 if(i == TASK_SIZE)
 {
  HeadTask = IdelTask;
 }
 
 OS_TASK_SW();启动软件中断进入中断调度
}
__interrupt VectorNumber_Vswi void OSCtxSw(void)   //4为SWI中断

    DisableInterrupts;              //关中断
  // PTP = 0xAA;
   asm{
        ldaa $30                    //保存页面寄存器,单片机16位最大的flash只能是64k。但是128k需要通过页面寄存器切换
        psha
        STS Sp_bf            将当前的sp赋值给sp_bf
       }
        OldTask->TaskSp = Sp_bf;    保存sp-bf
    Sp_bf = HeadTask->TaskSp;   取出sp的地址。
   asm{  
        LDS Sp_bf                将sp-bf给SP   
        pula
        staa $30                  将页面寄存器恢复
       }
    EnableInterrupts;             //开中断    
}
这样一个任务就调度出来了、



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实时控制.安全.如何加速实现未来工厂落地?