自己寫單片機(jī)操做系統(tǒng)3-任務(wù)創(chuàng)建和調(diào)度
這個(gè)要看MCU進(jìn)入中斷的流程才能知道棧需要怎么保護(hù)。
OS_STK* InitStkBuff(VOID_FUN_PTR task,OS_STK* pstk)
{
pstk--;
*pstk = (U16)(((U32)task) >> 8);存要執(zhí)行的函數(shù)
pstk--;
*pstk = 0xFFFF;//IY存y寄存器
(pstk)--;
*pstk = 0x1111;//IX存x寄存器
pstk--;
*pstk = 0xAA;//A;存A
((U8*)pstk)--;A和B都是8位的在寄存器中是一起放在一個(gè)16位中的、
*pstk = 0xBB;//B存B
((U8*)pstk)--;//在中斷中需要多保存一次page頁,所以需要留一個(gè)空間出來
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給到任務(wù)的sp中
}
任務(wù)調(diào)度函數(shù)
void Os_Schel(void)
{
U8 i;
OldTask = HeadTask;
for(i = 0;i < TASK_SIZE;i++)
{
if(OsTaskObjTbl[i].taskState == TASK_STATE_READY) 直接查看任務(wù)的狀態(tài),是否已經(jīng)就緒
{
HeadTask = &OsTaskObjTbl[i];
break;
}
}
OS_STK* InitStkBuff(VOID_FUN_PTR task,OS_STK* pstk)
{
pstk--;
*pstk = (U16)(((U32)task) >> 8);存要執(zhí)行的函數(shù)
pstk--;
*pstk = 0xFFFF;//IY存y寄存器
(pstk)--;
*pstk = 0x1111;//IX存x寄存器
pstk--;
*pstk = 0xAA;//A;存A
((U8*)pstk)--;A和B都是8位的在寄存器中是一起放在一個(gè)16位中的、
*pstk = 0xBB;//B存B
((U8*)pstk)--;//在中斷中需要多保存一次page頁,所以需要留一個(gè)空間出來
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給到任務(wù)的sp中
}
任務(wù)調(diào)度函數(shù)
void Os_Schel(void)
{
U8 i;
OldTask = HeadTask;
for(i = 0;i < TASK_SIZE;i++)
{
if(OsTaskObjTbl[i].taskState == TASK_STATE_READY) 直接查看任務(wù)的狀態(tài),是否已經(jīng)就緒
{
HeadTask = &OsTaskObjTbl[i];
break;
}
}
if(i == TASK_SIZE)
{
HeadTask = IdelTask;
}
OS_TASK_SW();啟動(dòng)軟件中斷進(jìn)入中斷調(diào)度
}
__interrupt VectorNumber_Vswi void OSCtxSw(void) //4為SWI中斷
{
DisableInterrupts; //關(guān)中斷
//PTP = 0xAA;
asm{
ldaa $30 //保存頁面寄存器,單片機(jī)16位最大的flash只能是64k。但是128k需要通過頁面寄存器切換
psha
STS Sp_bf將當(dāng)前的sp賦值給sp_bf
}
OldTask->TaskSp = Sp_bf;保存sp-bf
Sp_bf = HeadTask->TaskSp; 取出sp的地址。
asm{
LDS Sp_bf將sp-bf給SP
pula
staa $30 將頁面寄存器恢復(fù)
}
EnableInterrupts; //開中斷
}
這樣一個(gè)任務(wù)就調(diào)度出來了、
{
HeadTask = IdelTask;
}
OS_TASK_SW();啟動(dòng)軟件中斷進(jìn)入中斷調(diào)度
}
__interrupt VectorNumber_Vswi void OSCtxSw(void) //4為SWI中斷
{
DisableInterrupts; //關(guān)中斷
//PTP = 0xAA;
asm{
ldaa $30 //保存頁面寄存器,單片機(jī)16位最大的flash只能是64k。但是128k需要通過頁面寄存器切換
psha
STS Sp_bf將當(dāng)前的sp賦值給sp_bf
}
OldTask->TaskSp = Sp_bf;保存sp-bf
Sp_bf = HeadTask->TaskSp; 取出sp的地址。
asm{
LDS Sp_bf將sp-bf給SP
pula
staa $30 將頁面寄存器恢復(fù)
}
EnableInterrupts; //開中斷
}
這樣一個(gè)任務(wù)就調(diào)度出來了、
評論