在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<s id="cmphk"><label id="cmphk"></label></s>
    <span id="cmphk"><var id="cmphk"></var></span>
    <dfn id="cmphk"><var id="cmphk"></var></dfn>
    <menu id="cmphk"><thead id="cmphk"></thead></menu>

    <address id="cmphk"></address>

      <dfn id="cmphk"></dfn>
      
      
      <span id="cmphk"></span>

      <object id="cmphk"><tt id="cmphk"></tt></object>
      1. 新聞中心

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

        移植ucosII到STM32F103ZE(五)

        作者: 時間:2016-11-25 來源:網絡 收藏
        os_cpu_a.asm
        這個文件包含著必須用匯編寫的代碼。
        EXTERN OSRunning ; External references
        EXTERN OSPrioCur
        EXTERN OSPrioHighRdy
        EXTERN OSTCBCur
        EXTERN OSTCBHighRdy
        EXTERN OSIntNesting
        EXTERN OSIntExit
        EXTERN OSTaskSwHook
        申明這些變量是在其他文件定義的,本文件只做引用(有幾個好像并未引用,不過沒有關系)。
        EXPORT OS_CPU_SR_Save ; Functions declared in this file
        EXPORT OS_CPU_SR_Restore
        EXPORT OSStartHighRdy
        EXPORT OSCtxSw
        EXPORT OSIntCtxSw
        EXPORT OS_CPU_PendSVHandler ; #0
        #0這里 OS_CPU_PendSVHandler 要替換為PendSV_Handler;如下圖:

        替換后的 PPendSV中斷
        聲明這些函數是在本文件中定義的。EXPORT這個關鍵字是跟編譯器有關的,能被keil識別,但不能被IAR 識別。
        NVIC_INT_CTTRL EQU 0xE000ED04 ;中斷控制及狀態(tài)寄存器 ICSR 的地址
        NVIC_SYSPRI14 EQU 0xE000ED22 ;PendSV優(yōu)先級寄存器的地址
        NVIC_PENDSV_PRI EQU 00xFF ; PendSV 中斷的優(yōu)先級為 255(最低)
        NVIC_PENDSVSET EQU 0x10000000 ; 位 28 為 1
        ;定義幾個常量,類似 C 語言中的#define預處理指令。
        S_CPU_SR_Save
        MRS R0, PRIMASK ;讀取 PRIMASK 到R0 中,R0 為返回值
        CPSID I ;PRIMASK=1,關中斷(NMI 和硬 fault 可以響應)
        BX LR ;返回

        OS_CPU_SR_Restore
        MSR PRIMASK, R0 ;讀取 R0 到PRIMASK 中,R0 為參數
        BX LR ;返回

        OSStartHighRdy()由 OSStart()調用,用來啟動最高優(yōu)先級任務,當然任務必須在OSStart()前已被創(chuàng)建。
        OSStartHighRdy
        ;設置 PendSV 中斷的優(yōu)先級 #1
        LDR R0, =NVIC_SYSPRI14 ;R0 = NVIC_SYSPRI14
        LDR R1, =NVIC_PENDSV_PRI ;R1 = NVIC_PENDSV_PRI
        STRB R1, [R0] ; *(uint8_t *)NVIC_SYSPRI14 = NVIC_PENDSV_PRI
        ;設置 PSP 為0 #2
        MOVS R0, #0 ;R0 = 0
        MSR PSP, R0 ;PSP = R0
        ;設置 OSRunning 為TRUE
        LDR R0, =OSRunning ;R0 = OSRunning
        MOVS R1, #1 ;R1 = 1
        STRB R1, [R0] ;OSRunning = 1
        ;觸發(fā) PendSV 中斷 #3
        LDR R0, =NVIC_INT_CTRL ;R0 = NVIC_INT_CTRL
        LDR R1, =NVIC_PENDSVSET ;R1 = NVIC_PENDSVSET
        STR R1, [R0] ; *(uint32_t *)NVIC_INT_CTRL = NVIC_PENDSVSET
        CPSIE I ;開中斷
        OSStartHang
        ;死循環(huán),應該不會到這里
        B OSStartHang
        #1.PendSV 中斷的優(yōu)先級應該為最低優(yōu)先級,原因在<>的 7.6 節(jié)已有說明。
        #2.PSP 設置為 0,是告訴具體的任務切換程序(OS_CPU_PendSVHandler()),這是第一次任務切換。做過切換后 PSP 就不會為0了,后面會看到。
        #3.往中斷控制及狀態(tài)寄存器 ICSR(0xE000ED04)第 28 位寫 1 即可產生 PendSV 中斷。這個<>8.4.5 其它異常的配置寄存器有說明。
        當一個任務放棄 cpu 的使用權,就會調用OS_TASK_SW()宏,而 OS_TASK_SW()就是 OSCtxSw()。OSCtxSw()應該做任務切換。但是在 CM3 中,所有任務切換都被放到PendSV 的中斷處理函數中去做了,因此 OSCtxSw() 只需簡單的觸發(fā) PendSV中斷即可。OS_TASK_SW()是由OS_Sched()調用。
        void OS_Sched (void)
        {
        # if OS_CRITICAL_METHOD==3
        OS_CPU_SR cpu_sr = 0;
        #endif
        OS_ENTER_CRITICAL();

        if (OSIntNesting ==0) {
        if (OSLockNesting == 0) {
        OS_SchedNew();
        if (OSPrioHighRdy != OSPrioCur)
        {
        OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
        #if OS_TASK_PROFILE_EN > 0
        OSTCBHighRdy->OSTCBCtxSwCtr++;
        #endif
        OSCtxSwCtr++;
        OS_TASK_SW();
        }
        }
        }

        OS_EXIT_CRITICAL();
        }

        OSCtxSw ;觸發(fā)PendSV 中斷
        LDR R0, =NVIC_INT_CTRL ;R0 = NVIC_INT_CTRL
        LDR R1, =NVIC_PENDSVSET ;R1 = NVIC_PENDSVSET
        STR R1, [R0] ;*(uint32_t *)NVIC_INT_CTRL = NVIC_PENDSVSET
        BX LR ;返回
        當一個中斷處理函數退出時,OSIntExit()會被調用來決定是否有優(yōu)先級更高的任務需要執(zhí)行。如果有
        OSIntExit()對調用 OSIntCtxSw()做任務切換。
        OSIntCtxSw ;觸發(fā) PendSV 中斷
        LDR R0, =NVIC_INT_CTRL
        LDR R1, =NVIC_PENDSVSET
        STR R1, [R0]
        BX LR
        看到這里有人可能奇怪怎么 OSCtxSw()和OSIntCtxSw()完全一樣,事實上,這兩個函數的意義是不一樣的,OSCtxSw()做的是任務之間的切換,如任務 A 因為等待某個資源或是做延時切換到任務 B,而
        OSIntCtxSw()則是中斷退出時,由中斷狀態(tài)切換到另一個任務。由中斷切換到任務時,CPU 寄存器入棧的工作已經做完了,所以無需做第二次了(參考邵老師書的 3.10 節(jié))。這里只不過由于 CM3 的特殊機制導致了在這兩個函數中只要做觸發(fā) PendSV中斷即可,具體切換由 PendSV 中斷來處理。
        前面已經說過真正的任務切換是在 PendSV 中斷處理函數里做的,由于 CM3 在中斷時會有一半的寄存器自動保存到任務堆棧里,所以在 PendSV 中斷處理函數中只需保存 R4-R11并調節(jié)堆棧指針即可。

        上一頁 1 2 下一頁

        評論


        技術專區(qū)

        關閉