欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: ucos到stm32(一) [打印本頁]

作者: 51黑fan    時(shí)間: 2016-1-31 01:03
標(biāo)題: ucos到stm32(一)
      /**********************************戰(zhàn)艦版實(shí)例**************************************/
P80:μc/osⅡ時(shí)鐘
  硬件定時(shí)器中斷(使用了STM32中的Systick中斷)每產(chǎn)生一次,μc/osⅡ時(shí)鐘就會(huì)進(jìn)入一次系統(tǒng)中斷服務(wù)程序(OSTickISR()),系統(tǒng)中斷服務(wù)程序通過調(diào)用OSTimeTick()來完成系統(tǒng)每個(gè)時(shí)鐘節(jié)拍所要完成的工作(包括遍歷每個(gè)任務(wù)控制塊將其延時(shí)參數(shù)減1等)。
任哲版教材P87鉤子函數(shù)在戰(zhàn)艦的對應(yīng)源碼:
鉤子函數(shù)的使用(以O(shè)STimerTickHook為例):
Step1:發(fā)生硬件時(shí)鐘中斷時(shí)會(huì)調(diào)用右圖的鉤子函數(shù)(在os_cpu.c文件中)。但是調(diào)用的該函數(shù)實(shí)現(xiàn)的條件是:
需要到os_cfg.h中把這兩個(gè)宏#define成>0。
P88:OSTimeDly
在OSTimeDly中完成OSTCBCur->OSTCBDly(任務(wù)延時(shí)寄存器)的寫入并進(jìn)行一次任務(wù)切換:



關(guān)于 μc/osⅡ的疑難:
·μc/osⅡ的時(shí)鐘OSTimeTick()是怎么與STM32的SysTick關(guān)聯(lián)起來的?
戰(zhàn)艦開發(fā)板配套程序中在main()中有delay_init()(delay.c下)函數(shù),其原代碼如下:
void delay_init()         
{
#ifdef OS_CRITICAL_METHOD         //如果OS_CRITICAL_METHOD定義了,說明使用ucosII了.
        u32 reload;
#endif
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);        //選擇外部時(shí)鐘  HCLK/8
        fac_us=SystemCoreClock/8000000;        //為系統(tǒng)時(shí)鐘的1/8  
         
#ifdef OS_CRITICAL_METHOD         //如果OS_CRITICAL_METHOD定義了,說明使用ucosII了.
        reload=SystemCoreClock/8000000;                //每秒鐘的計(jì)數(shù)次數(shù) 單位為K           
        reload*=1000000/OS_TICKS_PER_SEC;//根據(jù)OS_TICKS_PER_SEC設(shè)定溢出時(shí)間
                                                        //reload為24位寄存器,最大值:16777216,在72M下,約合1.86s左右
        fac_ms=1000/OS_TICKS_PER_SEC;//代表ucos可以延時(shí)的最少單位           
        SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;           //開啟SYSTICK中斷
        SysTick->LOAD=reload;         //每1/OS_TICKS_PER_SEC秒中斷一次        
       SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;          //開啟SYSTICK   
#else
        fac_ms=(u16)fac_us*1000;//非ucos下,代表每個(gè)ms需要的systick時(shí)鐘數(shù)   
#endif
}        
可見delay_init()開啟了STM32的SYSTICK中斷,下面繼續(xù)找SYSTICK的中斷服務(wù)程序(同樣也在delay.c),代碼如下:
void SysTick_Handler(void)
{                                   
OSIntEnter();                //進(jìn)入中斷,其作僅僅是將判斷中斷層數(shù)是否達(dá)到255否則OSIntNesting++
OSTimeTick();       //調(diào)用ucos的時(shí)鐘服務(wù)程序               
OSIntExit();        //觸發(fā)任務(wù)切換軟中斷
}
發(fā)現(xiàn)OSTimeTick(); 在        SYSTICK的中斷服務(wù)程序被調(diào)用,現(xiàn)在μc/osⅡ的時(shí)鐘OSTimeTick()就與STM32的SysTick關(guān)聯(lián)了起來。
OSIntExit (void)的作用除了執(zhí)行了OSIntNesting--之外       還進(jìn)行了一次中斷級任務(wù)調(diào)度OSIntCtxSw()       。
·OSIntCtxSw()切換任務(wù)的原理:
Step1:SIntCtxSw()觸發(fā)了一次軟件中斷,代碼如下
;/**************************************************************************************
;* 函數(shù)名稱: OSIntCtxSw
;* 功能描述: 中斷級任務(wù)切換(其實(shí)是進(jìn)行了一次軟件中斷)
;* 參    數(shù): None
;* 返 回 值: None
;***************************************************************************************/
OSIntCtxSw
                PUSH    {R4, R5}
        LDR     R4, =NVIC_INT_CTRL ;觸發(fā)PendSV異常 (causes context switch)
                                                                        ;NVIC_INT_CTRL就是軟件中斷控制寄存器
        LDR     R5, =NVIC_PENDSVSET  ;NVIC_PENDSVSET是觸發(fā)軟件中斷的值.
        STR     R5, [R4]     ;將R5中的字?jǐn)?shù)據(jù)寫入以R4為地址的存儲(chǔ)器中就發(fā)生了PendSV中斷
                POP     {R4, R5}
        BX      LR
        NOP
Step2:執(zhí)行完了step后會(huì)進(jìn)入軟件中斷服務(wù)函數(shù),代碼(在os_cpu_aasm中)如下
;/**************************************************************************************
;* 函數(shù)名稱: OSPendSV
;*
;* 功能描述: 該函數(shù)實(shí)際上完成了cpu各寄存器的壓棧和新任務(wù)堆棧向cpu的進(jìn)棧;
;* 參    數(shù): None
;*
;* 返 回 值: None
;***************************************************************************************/
PendSV_Handler  ;軟件中斷服務(wù)函數(shù)
    CPSID   I      ; Prevent interruption during context switch
    MRS     R0, PSP   ; PSP is process stack pointer 如果在用PSP堆棧,則可以忽略保存寄存器,參考CM3權(quán)威中的雙堆棧-白菜注
    CBZ     R0, PendSV_Handler_Nosave         ; Skip register save the first time
    SUBS    R0, R0, #0x20   ; Save remaining regs R4-11 on process stack
    STM     R0, {R4-R11}
    LDR     R1, =OSTCBCur  ; OSTCBCur->OSTCBStkPtr = SP; =OSTCBCur就是取的OSTCBCur
;首地址,即任務(wù)控制塊的堆棧。
    LDR     R1, [R1]
    STR     R0, [R1]   ; R0 is SP of process being switched out

   







歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1