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

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

?? ucos-ii源碼分析.c

?? ucosII源碼分析
?? C
?? 第 1 頁 / 共 3 頁
字號:
OK,到這里OSInit算高一個段落了,我們接著回到main往下看。
 
OSTaskCreate
 
OSTaskCreate負責創建Task所需的數據結構,該函數原形如下所示:
INT8U  OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT8U prio)
其中task是一個函數指針,指向該Task所開始的函數,當這個Task第一次被調度運行時將會從task處開始運行。
p_arg是傳給task的參數指針;
ptos是堆棧指針,指向棧頂(堆棧從上往下)或棧底(堆棧從下往上);
prio是進程的優先級,uC/OS-II共支持最大64個優先級,其中最低的兩個優先級給Idle和Stat進程,并且各個Task的優先級必須不同。
接下來,我們看看這個函數的執行流程:
#if OS_ARG_CHK_EN > 0
    if (prio > OS_LOWEST_PRIO) {             /* Make sure priority is within allowable range           */
        return (OS_PRIO_INVALID);
    }
#endif
    OS_ENTER_CRITICAL();
    if (OSIntNesting > 0) {                  /* Make sure we don't create the task from within an ISR  */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_CREATE_ISR);
    }
    if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority  */
        OSTCBPrioTbl[prio] = (OS_TCB *)1;    /* Reserve the priority to prevent others from doing ...  */
                                             /* ... the same thing until task is created.              */
        OS_EXIT_CRITICAL();
        psp = (OS_STK *)OSTaskStkInit(task, p_arg, ptos, 0);    /* Initialize the task's stack         */
        err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
        if (err == OS_NO_ERR) {
            if (OSRunning == TRUE) {         /* Find highest priority task if multitasking has started */
                OS_Sched();
            }
        } else {
            OS_ENTER_CRITICAL();
            OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others                 */
            OS_EXIT_CRITICAL();
        }
        return (err);
    }
    OS_EXIT_CRITICAL();
    return (OS_PRIO_EXIST);
OS_LOWEST_PRIO在ucos-ii.h中被定義為63,表示Task的優先級從0到63,共64級。首先判斷prio是否超過最低優先級,如果是,則返回OS_PRIO_INVALID錯誤。
然后調用OS_ENTER_CRITICAL(),進入臨界段,在臨界段中的代碼執行不允許被中斷。這個宏是用戶自定義的,一般是進行關中斷操作,例如在x86中的CLI等。這個宏和OS_EXIT_CRITICAL()相對應,這個宏表示離開臨界段。
OSTaskCreate不允許在中斷中調用,因此會判斷OSIntNesting是否大于0,如果大于0,表示正在中斷嵌套,返回OS_ERR_TASK_CREATE_ISR錯誤。
接著判斷該prio是否已經有Task存在,由于uC/OS-II只支持每一個優先級一個Task,因此如果該prio已經有進程存在,OSTaskCreate會返回OS_PRIO_EXIST錯誤。
相反,如果該prio先前沒有Task存在,則將OSTCBPrioTbl[prio]置1,表示該prio已被占用,然后調用OSTaskStkInit初始化堆棧,調用OS_TCBInit初始化TCB,如果OSRunning為TRUE表示OS正在運行,則調用OS_Sched進行進程調度;否則返回。
下面來看看OSTaskStkInit和OS_TCBInit這兩個函數。

OSTaskStkInit是一個用戶自定義的函數,因為uC/OS-II在設計時無法知道當前處理器在進行進程調度時需要保存那些信息,OSTaskStkInit就是初始化堆棧,讓Task看起來就好像剛剛進入中斷并保存好寄存器的值一樣,當OS_Sched調度到該Task時,只需切換到該堆棧中,將寄存器值Pop出來,然后執行一個中斷返回指令IRET即可。
OSTaskStkInit的原型如下:
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
和OSTaskCreate類似,task是進程入口地址,pdata是參數地址,ptos是堆棧指針,而opt只是作為一個預留的參數Option而保留。返回的是調整以后的堆棧指針。
在OSTaskStkInit中,一般是將pdata入棧,flag入棧,task入棧,然后將各寄存器依次入棧。
OS_TCBInit初始化TCB數據結構,下面只提取主要部分來看:
INT8U  OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
    OS_TCB    *ptcb;
   
    OS_ENTER_CRITICAL();
    ptcb = OSTCBFreeList;                                  /* Get a free TCB from the free TCB list    */
    if (ptcb != (OS_TCB *)0) {
        OSTCBFreeList        = ptcb->OSTCBNext;            /* Update pointer to free TCB list          */
        OS_EXIT_CRITICAL();
        ptcb->OSTCBStkPtr    = ptos;                       /* Load Stack pointer in TCB                */
        ptcb->OSTCBPrio      = prio;                       /* Load task priority into TCB              */
        ptcb->OSTCBStat      = OS_STAT_RDY;                /* Task is ready to run                     */
        ptcb->OSTCBPendTO    = FALSE;                      /* Clear the Pend timeout flag              */
        ptcb->OSTCBDly       = 0;                          /* Task is not delayed                      */
#if OS_TASK_CREATE_EXT_EN > 0
        ptcb->OSTCBExtPtr    = pext;                       /* Store pointer to TCB extension           */
        ptcb->OSTCBStkSize   = stk_size;                   /* Store stack size                         */
        ptcb->OSTCBStkBottom = pbos;                       /* Store pointer to bottom of stack         */
        ptcb->OSTCBOpt       = opt;                        /* Store task options                       */
        ptcb->OSTCBId        = id;                         /* Store task ID                            */
#else
        pext                 = pext;                       /* Prevent compiler warning if not used     */
        stk_size             = stk_size;
        pbos                 = pbos;
        opt                  = opt;
        id                   = id;
#endif
#if OS_TASK_DEL_EN > 0
        ptcb->OSTCBDelReq    = OS_NO_ERR;
#endif
        ptcb->OSTCBY         = (INT8U)(prio >> 3);         /* Pre-compute X, Y, BitX and BitY          */
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX         = (INT8U)(prio & 0x07);
        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];
#if OS_EVENT_EN
        ptcb->OSTCBEventPtr  = (OS_EVENT *)0;              /* Task is not pending on an event          */
#endif
        OSTaskCreateHook(ptcb);                            /* Call user defined hook                   */
        
        OS_ENTER_CRITICAL();
        OSTCBPrioTbl[prio] = ptcb;
        ptcb->OSTCBNext    = OSTCBList;                    /* Link into TCB chain                      */
        ptcb->OSTCBPrev    = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb;
        }
        OSTCBList               = ptcb;
        OSRdyGrp               |= ptcb->OSTCBBitY;         /* Make task ready to run                   */
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
        OSTaskCtr++;                                       /* Increment the #tasks counter             */
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    }
    OS_EXIT_CRITICAL();
    return (OS_NO_MORE_TCB);
}
首先調用OS_ENTER_CRITICAL進入臨界段,首先從OSTCBFreeList中拿出一個TCB,如果OSTCBFreeList為空,則返回OS_NO_MORE_TCB錯誤。
然后調用OS_EXIT_CRITICAL離開臨界段,接著對該TCB進行初始化:
 將OSTCBStkPtr初始化為該Task當前堆棧指針;
 OSTCBPrio設置為該Task的prio;
 OSTCBStat設置為OS_STAT_RDY,表示就緒狀態;
 OSTCBDly設置為0,當該Task調用OSTimeDly時會初始化這個變量為Delay的時鐘數,然后Task轉入OS_STAT_狀態。這個變量在OSTimeTick中檢查,如果大于0表示還需要進行Delay,則進行減1;如果等于零表示無須進行Delay,可以馬上運行,轉入OS_STAT_RDY狀態。
 OSTCBBitY和OSTCBBitX的作用我們在等會專門來討論。
緊接著就要將該TCB插入OSTCBList列表中,先調用OS_ENTER_CRITICAL進入臨界段,將該TCB插入到OSTCBList成為第一個節點,然后調整OSRdyGrp和OSRdyTbl,(這兩個變量一會和OSTCBBitX/OSTCBBitY一起討論),最后將OSTaskCtr計數器加一,調用OS_EXIT_CRITICAL退出臨界段。
OSMapTbl和OSUnMapTbl
剛才我們看到TCB數據結構中的OSTCBBitX/OSTCBBitY以及OSRdyGrp/OSRdyTbl的使用,這里專門來討論討論這幾個變量的用法。
uC/OS-II將64個優先級的進程分為8組,每組8個。剛好可以使用8個INT8U的數據進行表示,于是這就是OSRdyGrp和OSRdyTbl的由來,OSRdyGrp表示組別,從0到7,從前面我們可以看到OSRdyGrp和OSRdyTbl是這么被賦值的:
     OSRdyGrp               |= ptcb->OSTCBBitY;
        OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
     
 也就是OSTCBBitY保存的是組別,OSTCBBitX保存的是組內的偏移。而這兩個變量是這么被初始化的:
     
     ptcb->OSTCBY         = (INT8U)(prio >> 3);
        ptcb->OSTCBBitY      = OSMapTbl[ptcb->OSTCBY];
        ptcb->OSTCBX         = (INT8U)(prio & 0x07);
        ptcb->OSTCBBitX      = OSMapTbl[ptcb->OSTCBX];
 
 由于prio不會大于64,prio為6位值,因此OSTCBY為prio高3位,不會大于8,OSTCBX為prio低3位。
 這里就涉及到OSMapTbl數組和OSUnMapTbl數組的用法了。我們先看看OSMapTbl和OSUnMapTbl的定義:
 INT8U  const  OSMapTbl[8]   = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
 
 INT8U  const  OSUnMapTbl[256] = {
     0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x00 to 0x0F                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x10 to 0x1F                             */
     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x20 to 0x2F                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x30 to 0x3F                             */
     6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x40 to 0x4F                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x50 to 0x5F                             */
     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x60 to 0x6F                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x70 to 0x7F                             */
     7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x80 to 0x8F                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0x90 to 0x9F                             */
     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xA0 to 0xAF                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xB0 to 0xBF                             */
     6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xC0 to 0xCF                             */
     4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xD0 to 0xDF                             */
     5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,       /* 0xE0 to 0xEF                             */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲综合一区二区| 国产精品久99| 欧美午夜电影网| www.欧美日韩国产在线| 久久精品国产精品亚洲精品| 亚洲一区二区三区在线看| 亚洲欧洲韩国日本视频| 国产精品国产自产拍高清av | 亚洲在线视频一区| 1000精品久久久久久久久| 国产精品网曝门| 亚洲欧洲日韩一区二区三区| 国产精品成人午夜| 亚洲欧美色图小说| 一区二区不卡在线视频 午夜欧美不卡在| 国产精品久久三区| 亚洲欧美日韩系列| 亚洲成在线观看| 日韩国产欧美视频| 韩国毛片一区二区三区| 国产精品综合视频| 不卡影院免费观看| 在线亚洲高清视频| 91精品久久久久久久99蜜桃| 日韩精品一区二区三区视频播放 | 中文字幕一区二区视频| 亚洲欧美日韩一区二区| 亚洲国产精品久久艾草纯爱| 奇米影视7777精品一区二区| 国内精品国产三级国产a久久| 成人午夜av影视| 色8久久人人97超碰香蕉987| 7878成人国产在线观看| 久久久久久久久久电影| 国产精品不卡在线| 日韩国产精品久久| 成人午夜碰碰视频| 欧美日韩mp4| 国产午夜精品理论片a级大结局| 中文字幕亚洲一区二区va在线| 亚州成人在线电影| 国产成人在线视频播放| 在线观看视频欧美| 26uuu成人网一区二区三区| 综合在线观看色| 久久99国产精品久久99| 色偷偷久久人人79超碰人人澡| 日韩美女一区二区三区| 亚洲视频在线一区| 久久99精品久久只有精品| 91热门视频在线观看| 精品理论电影在线观看| 亚洲资源在线观看| 国产成人午夜高潮毛片| 欧美老肥妇做.爰bbww视频| 国产亚洲精品超碰| 日韩av一二三| 日本道色综合久久| 欧美激情艳妇裸体舞| 蜜臀va亚洲va欧美va天堂| 91丨porny丨蝌蚪视频| 精品999久久久| 日韩精品免费视频人成| 色一情一伦一子一伦一区| 久久久久久久综合色一本| 日本视频在线一区| 欧美日韩在线播放三区四区| 亚洲欧洲精品成人久久奇米网| 国产乱国产乱300精品| 欧美成人精品3d动漫h| 视频在线观看一区二区三区| 日本精品视频一区二区| 国产精品久久久久四虎| 国产黄色精品视频| 26uuu精品一区二区在线观看| 首页国产欧美日韩丝袜| 精品视频一区 二区 三区| 亚洲日本韩国一区| 99国产精品国产精品久久| 中文字幕成人网| 成人午夜电影久久影院| 国产精品亲子乱子伦xxxx裸| 懂色av一区二区三区免费看| 国产欧美精品区一区二区三区 | av欧美精品.com| 欧美激情一区不卡| 成人综合婷婷国产精品久久| 国产欧美一区二区精品秋霞影院 | 一本大道久久a久久精二百| 国产精品久久久久aaaa| 成人黄色av电影| 亚洲精品视频观看| 欧美午夜理伦三级在线观看| 麻豆中文一区二区| 欧美不卡一二三| 国产成人一级电影| 国产精品白丝在线| 欧美亚洲一区二区在线| 日韩黄色免费电影| xfplay精品久久| 波多野结衣91| 亚洲成人777| 日韩三级在线免费观看| 国产麻豆日韩欧美久久| 国产精品午夜春色av| 91成人在线免费观看| 日韩成人精品视频| 久久久精品免费免费| 91麻豆免费在线观看| 日韩高清在线观看| 国产欧美日韩激情| 欧美色精品天天在线观看视频| 奇米在线7777在线精品| 国产精品人人做人人爽人人添| 欧亚一区二区三区| 狠狠色丁香婷婷综合久久片| 中文字幕亚洲一区二区av在线| 欧美日韩一区高清| 国产成人一区在线| 婷婷久久综合九色综合伊人色| 久久精品夜色噜噜亚洲a∨| 91久久免费观看| 国产一区二区三区日韩| 亚洲一区二区免费视频| 久久亚洲精华国产精华液| 欧洲激情一区二区| 国产超碰在线一区| 日本午夜精品视频在线观看| 国产精品精品国产色婷婷| 欧美一二三四在线| 色婷婷综合久色| 国产精品一区二区三区乱码| 亚洲不卡在线观看| 国产精品国产三级国产普通话99| 欧美一区二区性放荡片| 一本一道综合狠狠老| 精油按摩中文字幕久久| 亚洲va欧美va人人爽午夜| 国产精品久久国产精麻豆99网站| 日韩欧美国产不卡| 欧美日韩国产色站一区二区三区| 国产98色在线|日韩| 久久精品国产久精国产爱| 亚洲成人www| 有码一区二区三区| 18欧美亚洲精品| 国产精品视频免费| 久久精品亚洲精品国产欧美| 欧美一区二区精品| 欧美日韩免费高清一区色橹橹 | 成人午夜电影久久影院| 久久精品国产精品亚洲精品| 午夜在线成人av| 亚洲一区精品在线| 一区二区三区四区高清精品免费观看| 国产精品婷婷午夜在线观看| 国产视频一区二区在线| 久久久国产精品午夜一区ai换脸| 精品久久免费看| 欧美xxx久久| 久久免费视频色| 国产亚洲欧美日韩日本| 欧美国产成人在线| 国产精品每日更新| 成人免费在线视频| 亚洲激情第一区| 亚洲成人先锋电影| 日本美女视频一区二区| 久久97超碰国产精品超碰| 国产在线精品一区二区不卡了| 精品亚洲aⅴ乱码一区二区三区| 麻豆91在线观看| 国产精品白丝jk白祙喷水网站| 成人黄色大片在线观看| 在线视频中文字幕一区二区| 欧美精品久久99久久在免费线| 日韩欧美一区二区久久婷婷| 久久久国产精品麻豆| 国产精品久久久久精k8| 亚洲黄色在线视频| 亚洲sss视频在线视频| 美女网站一区二区| 国产成人小视频| 日本久久一区二区三区| 欧美精品日韩一区| 久久久久久久综合色一本| 亚洲丝袜精品丝袜在线| 日韩中文字幕区一区有砖一区| 狠狠网亚洲精品| 91免费国产在线观看| 欧美一级夜夜爽| 国产精品嫩草99a| 午夜亚洲福利老司机| 国产精品中文字幕一区二区三区| 99久久精品国产毛片| 欧美一区永久视频免费观看| 欧美国产成人精品| 日本视频在线一区| 一本久久a久久免费精品不卡| 日韩精品影音先锋|