资讯详情

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

如果存在两个或以上的任务调度就需要将栈保 的寄存器了。这个地方就是各个 不同的地方了。 这个要看MCU进入中断的流程才能知道栈需要怎么保护。 OS_K* InitStkBuff(VOID_FUN_ 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_ST_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_STA_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给 pula staa $30 将页面寄存器恢复 } EnableInterrupts; //开中断 } 这样一个任务就调度出来了、 -电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台