中文字幕 另类精品,亚洲欧美一区二区蜜桃,日本在线精品视频免费,孩交精品乱子片免费

<sup id="3hn2b"></sup>

    1. <sub id="3hn2b"><ol id="3hn2b"></ol></sub><legend id="3hn2b"></legend>

      1. <xmp id="3hn2b"></xmp>

      2. 新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > UCOS操作系統(tǒng)堆棧淺談

        UCOS操作系統(tǒng)堆棧淺談

        作者: 時(shí)間:2016-12-01 來(lái)源:網(wǎng)絡(luò) 收藏
        1 聲明堆棧大小
        在uc/os-ii操作系統(tǒng)的任務(wù)切換和中斷處理過(guò)程中,需要保存處理器的內(nèi)部寄存器和變量的值,這就
        要求每個(gè)任務(wù)都有自己的堆??臻g。堆棧必須聲明為OS_STK類型,并且由連續(xù)的內(nèi)存空間組成,可以靜態(tài)
        分配空間(在編譯時(shí)分配),也可以動(dòng)態(tài)分配堆??臻g(在運(yùn)行時(shí)分配)。由于采用動(dòng)態(tài)分配方式,會(huì)導(dǎo)致
        內(nèi)存中含有大量?jī)?nèi)存碎片,因此不推薦使用動(dòng)態(tài)分配方式。其兩種聲明方式如下:
        靜態(tài)分配方式:
        static OS_STK TaskStk[StkSize];
        或者
        OS_STK TaskStk[StkSize];
        動(dòng)態(tài)分配方式:
        OS_STK *pstk;
        pstk = (OS_STK*)malloc(StkSize);
        if(pstk != (OS_STK*)0) //判斷堆棧分配是否成功
        {
        printf("Create TaskStk Success");
        }
        2 設(shè)置堆棧生產(chǎn)方向
        uc/os-ii操作系統(tǒng)支持2中堆棧生長(zhǎng)方向。即可從高地址往低地址生長(zhǎng),也可以由低地址往高地址生長(zhǎng)。
        在調(diào)用OSTaskCreate()或者OSTaskCreateExt()創(chuàng)建任務(wù)的時(shí)候由于必須知道堆棧的生長(zhǎng)方向,所以要在OS_CPU.H
        文件中設(shè)置任務(wù)堆棧的生長(zhǎng)方向。
        #define OS_STK_GROWTH 1 //設(shè)置堆棧是從上往下長(zhǎng)的
        OSTaskCreate(Task,pdata,&TaskStk[StkSize - 1],prio);
        或者
        #define OS_STK_GROWTH 0 //設(shè)置堆棧是從下往上長(zhǎng)的
        OSTaskCreate(Task,pdata,&TaskStk[0],prio);
        當(dāng)然也可以這樣編寫創(chuàng)建任務(wù)的以支持堆棧的從上往下和從下往上生長(zhǎng)
        #if OS_STK_GROWTH == 1
        OSTaskCreate(Task,pdata,&TaskStk[StkSize - 1],prio);
        #else
        OSTaskCreate(Task,pdata,&TaskStk[0],prio);
        #endif
        3 堆棧檢驗(yàn)
        為控制產(chǎn)品成本,有時(shí)需要確定任務(wù)實(shí)際需要的堆棧空間的大小,避免為任務(wù)分配過(guò)多的對(duì)戰(zhàn)空間,從而
        減少應(yīng)用程序代碼所需的RAM數(shù)量。uc/os-ii系統(tǒng)提供OSTaskStkChk()函數(shù)用以確定任務(wù)實(shí)際需要的堆??臻g。
        使用堆棧檢驗(yàn)功能必須做一下幾點(diǎn):
        1.在OS_CFG.H文件中設(shè)置OS_TASK_CREATE_EXT為 1
        2.使用OSTaskCreateExt()創(chuàng)建任務(wù),并且賦予任務(wù)比實(shí)際需要多一點(diǎn)的空間。可以在任何任務(wù)中調(diào)用STaskStkChk()函數(shù),對(duì)任何用OSTaskCreateExt()建立的任務(wù)進(jìn)行堆棧檢驗(yàn)。
        3.在OSTaskCreateExt()中,將參數(shù)opt設(shè)置為:OS_TASK_OPT_STK_CHK + OS_TASK_OPT_STK_CLR
        4.把需要進(jìn)行檢測(cè)的任務(wù)的優(yōu)先級(jí)作為OSTaskStkChk()的參數(shù)并調(diào)用
        應(yīng)使自己的應(yīng)用程序運(yùn)行足夠長(zhǎng)的時(shí)間,并且經(jīng)歷最壞的堆棧使用情況,這樣才能得到正確的樹木。一旦得到所需要的對(duì)單需求,就可以重新設(shè)置堆棧的最終大小了。在堆棧檢驗(yàn)中,所得到的只是一個(gè)大智的堆棧使用情況,并不能說(shuō)明堆棧的使用全部實(shí)際情況。
        4 堆棧溢出
        在實(shí)際的項(xiàng)目中,由于產(chǎn)品的升級(jí)需要可能一個(gè)任務(wù)會(huì)經(jīng)常修改,所需要的實(shí)際堆棧大小并不能很好的確定,即便使用堆棧檢驗(yàn)功能后,在后續(xù)產(chǎn)品的升級(jí)過(guò)程中變量的增加會(huì)導(dǎo)致堆棧不夠用。而在調(diào)試的過(guò)程中,如果沒(méi)有堆棧溢出的報(bào)警機(jī)制,一旦堆棧出現(xiàn)溢出,這個(gè)問(wèn)題是很難一時(shí)被發(fā)現(xiàn)的。在這里,我建議在系統(tǒng)開(kāi)始運(yùn)行前,把每個(gè)任務(wù)的堆棧棧頂初始化一個(gè)值,每次出現(xiàn)任務(wù)切換的時(shí)候就讀取對(duì)應(yīng)棧頂?shù)闹?,如果和初始化棧頂值相同的話就說(shuō)明沒(méi)有問(wèn)題,如果值出現(xiàn)改變的話那么出現(xiàn)堆棧溢出的概率至少達(dá)到90%以上,這樣可以避免出現(xiàn)堆棧溢出而不能發(fā)現(xiàn)的尷尬。下面是個(gè)項(xiàng)目的一部分,刪了一些,可供參考。
        #include "user/lc_sqce_aj.h"
        #include "include_all.h"
        /* size of each tasks stacks (# of WORDs) */
        #define TASK_START_STK_SIZE 128
        #define BUZZER_STK_SIZE 128
        #define CTRLMSG_STK_SIZE 128
        #define STORDEV_MOUNT_STK_SIZE 512
        #define MODE_SWITCH_STK_SIZE 512
        #define MODE_EXE_STK_SIZE 2000
        #define TWO_CHANNEL_REC_SIZE 512
        #define ALARM_STK_SIZE 128
        #define TASK_STK_SIZE 512
        /* application tasks */
        #define TASK_START_ID 0
        #define TASK_1_ID 1
        #define TASK_2_ID 2
        #define TASK_3_ID 3
        #define TASK_4_ID 4
        #define TASK_5_ID 5
        #define TASK_6_ID 6
        #define TASK_7_ID 7
        #define TASK_8_ID 8
        #define TASK_9_ID 9
        #define TASK_10_ID 10
        #define TASK_11_ID 11
        #define TASK_12_ID 12
        #define TASK_13_ID 13
        #define TASK_14_ID 14
        #define TASK_15_ID 15
        /* application tasks priorities */
        #define TASK_START_PRIO 0
        #define TASK_1_PRIO 1
        #define TASK_2_PRIO 2
        #define TASK_3_PRIO 3
        #define TASK_4_PRIO 4
        #define TASK_5_PRIO 5
        #define TASK_6_PRIO 6
        #define TASK_7_PRIO 7
        #define TASK_8_PRIO 8
        #define TASK_9_PRIO 9
        #define TASK_10_PRIO 10
        #define TASK_11_PRIO 11
        #define TASK_12_PRIO 12
        #define TASK_13_PRIO 13
        #define TASK_14_PRIO 14
        #define TASK_15_PRIO 15
        /*see task stacks*/
        OS_STK TaskStartStk[TASK_START_STK_SIZE];
        OS_STK BuzzerStk[BUZZER_STK_SIZE];
        OS_STK CtrlmsgStk[CTRLMSG_STK_SIZE];
        OS_STK StorDevStk[STORDEV_MOUNT_STK_SIZE];
        OS_STK ModeSwitchStk[MODE_SWITCH_STK_SIZE];
        OS_STK ModeExeStk[MODE_EXE_STK_SIZE];
        static void TaskStart(void *p_arg); //函數(shù)聲明
        static void TaskStartCreateTasks(void);
        void InitStackMark(void);
        //************************************************************************************
        //* 函數(shù)名 :main
        //* 返回值 :N/A
        //* 參數(shù) :N/A
        //* 函數(shù)說(shuō)明:主函數(shù)
        //* 作 者:啊呆
        //***********************************************************************************
        void main(void)
        {
        INT8U err;
        // initialize uC/OS-II
        OSInit();
        // install uC/OS-IIs context switch vector
        IRQSetVect(uCOS, OSCtxSw);
        OSTaskCreateExt(TaskStart,
        (void *)0,
        &TaskStartStk[TASK_START_STK_SIZE - 1],
        TASK_START_PRIO,
        TASK_START_ID,
        &TaskStartStk[0],
        TASK_START_STK_SIZE,
        (void *)0,
        OS_TASK_OPT_STK_CLR + OS_TASK_OPT_STK_CHK);
        OSTaskNameSet(TASK_START_PRIO, "Start Task", &err);
        // start multitasking
        OSStart();
        }
        上一頁(yè) 1 2 下一頁(yè)

        關(guān)鍵詞: UCOS操作系統(tǒng)堆

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉