新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 移植ucosII到STM32F103ZE(四)

        移植ucosII到STM32F103ZE(四)

        作者: 時間:2016-11-25 來源:網(wǎng)絡 收藏


        os_cpu_c.c
        ucosii 移植時需要我們寫 10個相當簡單的C 函數(shù)。
        OSInitHookBegin()
        OSInitHookEnd()
        OSTaskCreateHook()
        OSTaskDelHook()
        OSTaskIdleHook()
        OSTaskStatHook()
        OSTaskStkInit()
        OSTaskSwHook()
        OSTCBInitHook()
        OSTimeTickHook()
        這些函數(shù)除了 OSTaskStkInit(),都是一些 hook 函數(shù)。這些 hook 函數(shù)如果不使能的話,都不會用上,也都比較簡單,看看就應該明白了,所以就不介紹。
        下面就說一說 OSTaskStkInit()。說之前還是得先說一下任務切換,因為初始化任務堆棧,是為任務切換服務的。代碼在正常運行時,一行一行往下執(zhí)行,怎么才能跑到另一個任務(即函數(shù))執(zhí)行呢?首先大家可以回想一下中斷過程,當中斷發(fā)生時,原來函數(shù)執(zhí)行的地方(程序計數(shù)器PC、處理器狀態(tài)寄存器及所有通用寄存器,即當前代碼的現(xiàn)場)被保存到棧里面去了,然后開始取中斷向量,跑到中斷函數(shù)里面執(zhí)行。執(zhí)行完了呢,想回到原來函數(shù)執(zhí)行的地方,該怎么辦呢,只要把棧中保存的原來函數(shù)執(zhí)行的信息恢復即可(把棧中保存的代碼現(xiàn)場重新賦給 cpu 的各個寄存器),一切就都回去了,好像什么事都沒發(fā)生一樣。這個過程大家應該都比較熟悉,任務切換和這有什么關系,試想一下,如果有 3 個函數(shù) foo1(), foo2(), foo3() 都像是剛被中斷,現(xiàn)場保存到棧里面去了,而中斷返回時做點手腳(調(diào)度程序的作用),想回哪個回哪個,是不是就做了函數(shù)(任務)切換了。看到這里應該有點明白 OSTaskStkInit()的作用了吧,它被任務創(chuàng)建函數(shù)調(diào)用,所以要在開始時,在棧中作出該任務好像剛被中斷一樣的假象。(關于任務切換的原理邵老師書中的 3.06 節(jié)有介紹)。
        那么中斷后棧中是個什么情形呢,<>中 9.1.1 有介紹,xPSR,PC,LR,R12,R3-R0 被自動保存到棧中的,R11-R4如果需要保存,只能手工保存。因此 OSTaskStkInit()的工作就是在任務自己的棧中保存 cpu 的所有寄存器。這些值里 R1-R12 都沒什么意義,這里用相應的數(shù)字代號(如 R1 用0x01010101)主要是方便調(diào)試。
        OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
        {
        OS_STK *stk;
        (void)opt;
        stk = ptos;


        *(stk) = (INT32U)0x01000000L;
        *(--stk) = (INT32U)task;
        *(--stk) = (INT32U)0xFFFFFFFEL;
        *(--stk) = (INT32U)0x12121212L;
        *(--stk) = (INT32U)0x03030303L;
        *(--stk) = (INT32U)0x02020202L;
        *(--stk) = (INT32U)0x01010101L;
        *(--stk) = (INT32U)p_arg;


        *(--stk) = (INT32U)0x11111111L;
        *(--stk) = (INT32U)0x10101010L;
        *(--stk) = (INT32U)0x09090909L;
        *(--stk) = (INT32U)0x08080808L;
        *(--stk) = (INT32U)0x07070707L;
        *(--stk) = (INT32U)0x06060606L;
        *(--stk) = (INT32U)0x05050505L;
        *(--stk) = (INT32U)0x04040404L;

        return (stk);
        }
        xPSR = 0x01000000L,xPSR T 位(第24 位)置 1,否則第一次執(zhí)行任務時 Fault,
        PC 肯定得指向任務入口,
        R14 = 0xFFFFFFFEL,最低4位為E,是一個非法值,主要目的是不讓使用 R14,即任務是不能返回的。R0 用于傳遞任務函數(shù)的參數(shù),因此等于 p_arg。
        把 OS_CPU_SysTickHandler(), OS_CPU_SysTickInit()這兩個函數(shù)的內(nèi)容代碼注釋掉。
        os_cpu_c.c文件中的






        #define OS_CPU_CM3_NVIC_ST_CTRL (*((volatile INT32U *)0xE000E010))
        #define OS_CPU_CM3_NVIC_ST_RELOAD (*((volatile INT32U *)0xE000E014))
        #define OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018))
        #define OS_CPU_CM3_NVIC_ST_CALL (*((volatile INT32U *)0xE000E01C))

        #define OS_CPU_CM3_NVIC_ST_CTRL_COUNT 0x00010000
        #define OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC 0x00000004
        #define OS_CPU_CM3_NVIC_ST_CTRL_INTEN 0x00000002
        #define OS_CPU_CM3_NVIC_ST_CTRL_ENABLE 0x00000001
        把上面這些宏定義也注釋掉,因為它們都用于 OS_CPU_SysTickHandler(), OS_CPU_SysTickInit()。




        上一頁 1 2 下一頁

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 甘肃省| 西畴县| 渑池县| 昭觉县| 开远市| 黄浦区| 许昌县| 中江县| 延庆县| 阿拉善左旗| 静海县| 彩票| 岚皋县| 新绛县| 轮台县| 宁强县| 诸暨市| 香港 | 宝鸡市| 石门县| 广汉市| 托克逊县| 康平县| 白城市| 宝鸡市| 封丘县| 太保市| 武宣县| 张北县| 长沙县| 元阳县| 尚义县| 聊城市| 惠水县| 延寿县| 武城县| 洪雅县| 林芝县| 开阳县| 陇南市| 牙克石市|