亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ucos-ii源碼分析.c

?? ucosII源碼分析
?? C
?? 第 1 頁 / 共 3 頁
字號:
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0        /* 0xF0 to 0xFF                             */
 };
 OSMapTbl分別是一個INT8U的八個位,而OSUnMap數組中的值就是從0x00到0xFF的八位中,每一個值所對應的最低位的值。我們在調度的時候只需將OSRdyGrp的值代入OSUnMapTbl數組中,得到OSUnMapTbl[OSRdyGrp]的值就是哪個優先級最高的Group有Ready進程存在,再使用該Group對應OSRdyTbl[]數組中的值一樣帶入OSUnMapTbl中就可以得出哪個Task是優先級最高的。
 于是我們提前來看看OS_Sched()中獲取最高優先級所使用的方法:
 y             = OSUnMapTbl[OSRdyGrp];      /* Get pointer to HPT ready to run              */
    OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
 顯然,先得到的y就是存在最高優先級的Group,然后OSUnMapTbl[OSRdyTbl[y]]就是Group中的偏移,因此OSPrioHighRdy最高優先級就應該是Group<<3再加上這個偏移。
 
 于是乎,我們就可以對上面那一小段很模糊的代碼做一下總結:
 prio只有6位,高3位代表著某一個Group保存在OSTCBY中,OSTCBBitY表示該Group所對應的Bit,將OSRdyGrp的該位置1表示該Group中有進程是Ready的;低3位代表著該Group中的第幾個進程,保存在OSTCBX中,OSTCBBitX表示該進程在該Group中所對應的Bit,OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX就等于將該進程所對應的Bit置1了。
OSStart
OK,接下來我們來看這個開始函數了。OSStart其實很短,只有匆匆幾句代碼:
void  OSStart (void)
{
    INT8U y;
    INT8U x;

    if (OSRunning == FALSE) {
        y             = OSUnMapTbl[OSRdyGrp];        /* Find highest priority's task priority number   */
        x             = OSUnMapTbl[OSRdyTbl[y]];
        OSPrioHighRdy = (INT8U)((y << 3) + x);
        OSPrioCur     = OSPrioHighRdy;
        OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run    */
        OSTCBCur      = OSTCBHighRdy;
        OSStartHighRdy();                            /* Execute target specific code to start task     */
    }
}
如果OSRunning為TRUE,表示OS已經在運行了,則OSStart不做任何事。
OSRunning為FALSE,則找出最高優先級的Ready的Task,并將該指針賦給OSTCBHighRdy和OSTCBCur。然后調用OSStartHighRdy()開始運行該進程。
OSStartHighRdy()為用戶自定義函數,在這個函數中,主要功能就是進行堆棧切換并將OSRunning設置為TRUE表示OS已經開始運行,然后將保存的寄存器彈出,最后執行中斷返回指令IRET就跳到OSTCBHighRdy的最開始處運行了。
 
OSTimeDly
 
在Task中,一般執行一段時間之后調用OSTimeDly推遲一段時間再繼續運行,OSTimeDly將本進程從Ready TCBList中刪除,然后將Delay的時間設置給OSTCBDly,最后調用OS_Sched進行進程調度。
void  OSTimeDly (INT16U ticks)
{
    INT8U      y;
   
    if (ticks > 0) {                             /* 0 means no delay!                                  */
        OS_ENTER_CRITICAL();
        y            =  OSTCBCur->OSTCBY;        /* Delay current task                                 */
        OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0) {  
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks;              /* Load ticks in TCB                                  */
        OS_EXIT_CRITICAL();
        OS_Sched();                              /* Find next task to run!                             */
    }
}
如果ticks為零,說明不需延遲,則什么事情都不做。否則,調用OS_ENTER_CRITICAL進入臨界段,將本進程從Ready TCBList中刪除的代碼如下:
        y            =  OSTCBCur->OSTCBY;        /* Delay current task                                 */
        OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0) {  
            OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
        }
y為當前進程所在Group,OSRdyTbl[y]為該Group所在字節,&=~則將該字節中本進程所占用的Bit清零。如果OSRdyTbl[y]為0,則說明這個Group中沒有進程處于Ready狀態,則將OSRdyGrp中該Group所占用的Bit清零。
然后將ticks保存在OSTCBDly中,每次OSTimeTick運行時會將這個值減一直至為零。
調用OS_EXIT_CRITICAL離開臨界段,緊接著調用OS_Sched進入調度例程。
 
OS_Sched
 
OS_Sched是進程調度所使用的函數,在這里面找到最高優先級的進程,然后切換到該進程運行。
void  OS_Sched (void)
{
    INT8U      y;
    OS_ENTER_CRITICAL();
    if (OSIntNesting == 0) {                           /* Schedule only if all ISRs done and ...       */
        if (OSLockNesting == 0) {                      /* ... scheduler is not locked                  */
            y             = OSUnMapTbl[OSRdyGrp];      /* Get pointer to HPT ready to run              */
            OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
            if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy     */
                OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
                OSCtxSwCtr++;                          /* Increment context switch counter             */
                OS_TASK_SW();                          /* Perform a context switch                     */
            }
        }
    }
    OS_EXIT_CRITICAL();
}
OS_Sched不允許在中斷嵌套中調用,因此先判斷是否是中斷嵌套,并且是否限制進程調度,這兩個條件都滿足之后,找到最高優先級的進程,如果這個進程不是當前進程,則將新的進程TCB指針保存到OSTCBHighRdy中,為調度計數器OSCtxSwCtr加一,然后調用宏OS_TASK_SW()進行切換。
OS_TASK_SW()宏也是一個自定義的宏,uC/OS-II推薦使用軟中斷方式實現。
OSCtxSw是一個中斷響應函數,一般我們在初始化時將這個軟終端和OSCtxSw掛接好。在OSCtxSw中所需要做的事情就是將當前寄存器的值保存到當前堆棧中,然后切換堆棧到新進程的堆棧,將寄存器的值出棧,然后調用中斷返回指令IRET就返回到新進程中斷前的地方繼續執行了。
 
定時中斷
 
uC/OS-II的定時中斷必須在OSStart之后初始化,而不能在OSStart之前,因為害怕第一個TimeTick發生時第一個進程還沒有開始運行,而這時uC/OS是處于不可預期狀態,會導致死機。
因此對于定時中斷,我一般是放在最高級進程的初始化中進行,然后將定時中斷和OSTickISR掛接。
OSTickISR也是一個用戶自定義函數,所要完成的功能一個是保存當前的寄存器到當前堆棧將OSIntNesting加一,然后調用uC/OS提供的OSTimeTick函數,然后調用OSIntExit()將OSIntNesting減一,最后將各寄存器值出棧,使用中斷返回指令IRET返回。
OSTimeTick在每個時鐘中斷中被調用一次,在該函數中會更新各個進程TCB所對應的OSTCBDly,如果該OSTCBDly減為0,則對應的TCB就被放入Ready TCBList中。
    OS_ENTER_CRITICAL();                                   /* Update the 32-bit tick counter               */
    OSTime++;
    OS_EXIT_CRITICAL();
    
            ptcb = OSTCBList;                                  /* Point at first TCB in TCB list               */
        while (ptcb->OSTCBPrio != OS_IDLE_PRIO) {          /* Go through all TCBs in TCB list              */
            OS_ENTER_CRITICAL();
            if (ptcb->OSTCBDly != 0) {                     /* No, Delayed or waiting for event with TO     */
                if (--ptcb->OSTCBDly == 0) {               /* Decrement nbr of ticks to end of delay       */
                                                           /* Check for timeout                            */
                    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
                        ptcb->OSTCBStat   &= ~OS_STAT_PEND_ANY;                /* Yes, Clear status flag   */
                        ptcb->OSTCBPendTO  = TRUE;                             /* Indicate PEND timeout    */
                    } else {
                        ptcb->OSTCBPendTO  = FALSE;
                    }
                    if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?       */
                        OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready          */
                        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                    }
                }
            }
            ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list                */
            OS_EXIT_CRITICAL();
        }
首先在臨界段將OSTime加一,然后遍歷整個非Free的TCBList,如果OSTCBDly不為0,則,將OSTCBDly減一,如果這時OSTCBDly為0,而且TCB對應的進程需要等待任何信號量或Event等,則說明超時時間到了,將當前TCB的State中OS_STAT_PEND_ANY位去掉,然后將OSTCBPendTo設置為TRUE,表示這是PEND的超時,否則設置OSTCBPendTO為FALSE。
如果OSTCBDly減為零,且該進程沒有Suspend,則將該進程放入Ready TCBList中,使用方法同TaskCreate中的方法。
然后我們來說說OSIntExit這個函數。該函數代碼如下:
void  OSIntExit (void)
{
    INT8U      y;
  
    if (OSRunning == TRUE) {
        OS_ENTER_CRITICAL();
        if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping       */
            OSIntNesting--;
        }
        if (OSIntNesting == 0) {                           /* Reschedule only if all ISRs complete ... */
            if (OSLockNesting == 0) {                      /* ... and not locked.                      */
  y             = OSUnMapTbl[OSRdyGrp];          
                OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
                if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
                    OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
                    OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
                    OSIntCtxSw();                          /* Perform interrupt level ctx switch       */
                }
            }
        }
 OS_EXIT_CRITICAL();
    }
}
首先判斷OSRunning是否為1,也就是OS是否在運行,當然沒有運行就什么都不做。
然后將OSIntNesting減一,這個是需要在臨界段進行的。如果OSIntNesting減為零,并且沒有限制進程切換,則找到當前最高優先級的進程(方法同OS_Sched()),然后調用OSIntCtxSw進行進程切換。
OSIntCtxSw()是用戶自定義函數,該函數的主要功能與OSCtxSw類似,只是需要對當前的堆棧進行稍微的調整,將OSIntExit和OSIntCtxSw調用所需要的堆棧去掉,然后做的和OSCtxSw一樣。
在實際的Porting中發現要去掉OSIntExit和OSIntCtxSw調用所占用的堆棧還是比較麻煩的,因此我就現在OSTickISR剛開始的時候保存好現場之后就將堆棧指針賦給當前進程TCB的OSStkPtr,這樣,在OSIntCtxSw中就不需要重新對當前堆棧的值進行保存,只需進行切換就可以了。
 
OK,到這里應該對uC/OS的運行機制有一點點理解了,我們的分析之旅告個段落。以后如果有興趣我們再繼續對Event、信號量等等之類的分模塊進行分析。

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91丨porny丨最新| 国产91在线看| 亚洲精品成人悠悠色影视| 欧美大片日本大片免费观看| 欧美视频在线观看一区| 色8久久精品久久久久久蜜| 国产精品1024| 北条麻妃国产九九精品视频| 成人网在线播放| 不卡一区在线观看| 91色porny| 欧美日韩在线观看一区二区| 欧美性xxxxxx少妇| 精品视频999| 日韩精品自拍偷拍| 久久久精品黄色| 综合久久国产九一剧情麻豆| 亚洲三级在线播放| 亚洲一区二区三区四区在线观看| 亚洲综合在线视频| 日本伊人午夜精品| 国产成人一区在线| 在线影院国内精品| 日韩精品一区在线观看| 久久精品视频一区二区三区| 中文字幕亚洲在| 亚洲成人精品在线观看| 久久 天天综合| 成人av综合在线| 欧美人xxxx| 国产精品美女久久久久久2018| 亚洲欧洲在线观看av| 午夜精品福利视频网站| 国产自产视频一区二区三区| 成人激情免费网站| 制服丝袜中文字幕一区| 久久久99免费| 亚洲成人手机在线| 成人网男人的天堂| 777午夜精品免费视频| 久久精品一区二区三区不卡| 亚洲图片欧美综合| 风间由美中文字幕在线看视频国产欧美| 欧美性一区二区| 久久久青草青青国产亚洲免观| 一区二区三区日韩欧美| 国产精品一线二线三线精华| 欧美日韩一二区| 国产精品久久三| 激情综合一区二区三区| 欧美在线色视频| 亚洲国产成人午夜在线一区| 免费看日韩精品| 欧美色视频一区| 1024成人网色www| 国产一区二区免费视频| 欧美日韩精品久久久| 亚洲欧美日韩在线不卡| 国产91精品免费| 欧美大片在线观看一区二区| 亚洲va天堂va国产va久| 91丨porny丨在线| 国产免费成人在线视频| 久久国产日韩欧美精品| 欧美疯狂性受xxxxx喷水图片| 亚洲精品视频一区| 一本色道久久综合精品竹菊| 国产日韩影视精品| 国产一本一道久久香蕉| 欧美一级一级性生活免费录像| 亚洲免费视频成人| 色偷偷久久人人79超碰人人澡| 国产精品免费久久久久| 国产一区二区影院| 久久综合九色综合97_久久久| 奇米影视一区二区三区小说| 欧美精品99久久久**| 亚洲成人av电影| 欧美丰满嫩嫩电影| 午夜久久久久久| 8v天堂国产在线一区二区| 午夜成人在线视频| 日韩一级大片在线| 理论片日本一区| 欧美电视剧在线观看完整版| 九一久久久久久| 日本一区二区三区视频视频| 成人免费精品视频| 亚洲柠檬福利资源导航| 欧洲精品在线观看| 亚洲1区2区3区视频| 51午夜精品国产| 国产中文字幕精品| 国产精品久久久久一区 | 欧美性色欧美a在线播放| 亚洲精品久久久蜜桃| 精品视频在线免费观看| 日韩精品每日更新| 欧美精品一区二区三区久久久| 国产精品系列在线观看| 日韩美女精品在线| 欧美二区在线观看| 国产成人av一区二区三区在线| 中文字幕色av一区二区三区| 欧美色大人视频| 国模大尺度一区二区三区| 亚洲国产高清在线| 欧美日韩不卡在线| 久久国产三级精品| 亚洲欧美日韩中文播放| 4438x成人网最大色成网站| 国内精品国产成人国产三级粉色 | 亚洲欧美自拍偷拍| 欧美日韩电影一区| 色婷婷国产精品| 亚洲国产视频一区二区| 久久久久久影视| 在线观看免费视频综合| 国产在线看一区| 一区二区三区在线观看网站| 日韩欧美一级片| 色综合久久88色综合天天 | 精品国精品自拍自在线| av影院午夜一区| 激情久久久久久久久久久久久久久久| 国产精品久久久久国产精品日日| 91精品国产综合久久婷婷香蕉| 成人看片黄a免费看在线| 麻豆国产一区二区| 亚洲国产综合色| 亚洲欧美一区二区三区极速播放 | 欧美私模裸体表演在线观看| 国产精品综合一区二区| 日韩精品福利网| 亚洲精品国产品国语在线app| 欧美大黄免费观看| 欧美久久久一区| 在线看国产一区二区| av在线不卡免费看| av日韩在线网站| 成人v精品蜜桃久久一区| 极品少妇一区二区三区精品视频| 婷婷开心久久网| 亚洲电影在线免费观看| 亚洲精品视频在线观看网站| 国产精品伦理一区二区| 国产色婷婷亚洲99精品小说| 26uuu精品一区二区三区四区在线| 91精品在线观看入口| 欧美精品一二三四| 5月丁香婷婷综合| 日韩一区二区电影| 精品久久久久99| 欧美大片在线观看一区| 精品福利一区二区三区 | 成人教育av在线| 国产aⅴ精品一区二区三区色成熟| 国产美女在线观看一区| 国产成人综合自拍| 成人免费看视频| 97久久精品人人做人人爽| 91蜜桃视频在线| 在线视频亚洲一区| 欧美一区二区不卡视频| 日韩欧美国产综合| 久久久久久电影| 国产精品免费网站在线观看| 中文字幕亚洲在| 亚洲第一综合色| 狠狠色综合播放一区二区| 国产精品一区在线观看乱码| av激情综合网| 在线不卡中文字幕| 久久亚洲捆绑美女| 亚洲人成人一区二区在线观看| 亚洲一区在线播放| 久久成人综合网| 成人伦理片在线| 欧美精品粉嫩高潮一区二区| 精品久久久久久久人人人人传媒 | aaa亚洲精品一二三区| 在线观看视频一区| 日韩欧美二区三区| 欧美激情一区二区三区蜜桃视频| 亚洲欧美日韩成人高清在线一区| 亚洲超碰97人人做人人爱| 国产中文字幕精品| 色综合久久久久久久久| 欧美一级理论片| 国产精品久久久久7777按摩| 亚洲aⅴ怡春院| jlzzjlzz欧美大全| 欧美一区二区三区在线| 欧美经典三级视频一区二区三区| 亚洲综合网站在线观看| 国模少妇一区二区三区| 欧美性高清videossexo| 国产精品入口麻豆九色| 日本sm残虐另类| 色呦呦网站一区|