新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 自己寫(xiě)單片機(jī)操做系統(tǒng)3-任務(wù)創(chuàng)建和調(diào)度

        自己寫(xiě)單片機(jī)操做系統(tǒng)3-任務(wù)創(chuàng)建和調(diào)度

        作者: 時(shí)間:2016-12-01 來(lái)源:網(wǎng)絡(luò) 收藏
        如果存在兩個(gè)或以上的任務(wù)調(diào)度就需要將棧保CPU的寄存器了。這個(gè)地方就是各個(gè)MCU不同的地方了。
        這個(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頁(yè),所以需要留一個(gè)空間出來(lái)
        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 //保存頁(yè)面寄存器,單片機(jī)16位最大的flash只能是64k。但是128k需要通過(guò)頁(yè)面寄存器切換
        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 將頁(yè)面寄存器恢復(fù)
        }
        EnableInterrupts; //開(kāi)中斷
        }
        這樣一個(gè)任務(wù)就調(diào)度出來(lái)了、


        評(píng)論


        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 台山市| 屏山县| 廉江市| 隆昌县| 宝兴县| 油尖旺区| 古丈县| 鄂州市| 河北省| 景德镇市| 武胜县| 锦屏县| 恭城| 金平| 綦江县| 黄梅县| 兴仁县| 靖西县| 阳朔县| 靖江市| 浦北县| 南汇区| 灵丘县| 波密县| 新泰市| 五寨县| 仁化县| 红桥区| 新龙县| 张家口市| 马边| 临安市| 水富县| 积石山| 宜春市| 随州市| 江油市| 遂宁市| 玛曲县| 彩票| 清河县|