<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 移植ucosII到STM32F103ZE(五)

          移植ucosII到STM32F103ZE(五)

          作者: 時(shí)間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
          os_cpu_a.asm
          這個(gè)文件包含著必須用匯編寫的代碼。
          EXTERN OSRunning ; External references
          EXTERN OSPrioCur
          EXTERN OSPrioHighRdy
          EXTERN OSTCBCur
          EXTERN OSTCBHighRdy
          EXTERN OSIntNesting
          EXTERN OSIntExit
          EXTERN OSTaskSwHook
          申明這些變量是在其他文件定義的,本文件只做引用(有幾個(gè)好像并未引用,不過沒有關(guān)系)。
          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中斷
          聲明這些函數(shù)是在本文件中定義的。EXPORT這個(gè)關(guān)鍵字是跟編譯器有關(guān)的,能被keil識(shí)別,但不能被IAR 識(shí)別。
          NVIC_INT_CTTRL EQU 0xE000ED04 ;中斷控制及狀態(tài)寄存器 ICSR 的地址
          NVIC_SYSPRI14 EQU 0xE000ED22 ;PendSV優(yōu)先級(jí)寄存器的地址
          NVIC_PENDSV_PRI EQU 00xFF ; PendSV 中斷的優(yōu)先級(jí)為 255(最低)
          NVIC_PENDSVSET EQU 0x10000000 ; 位 28 為 1
          ;定義幾個(gè)常量,類似 C 語言中的#define預(yù)處理指令。
          S_CPU_SR_Save
          MRS R0, PRIMASK ;讀取 PRIMASK 到R0 中,R0 為返回值
          CPSID I ;PRIMASK=1,關(guān)中斷(NMI 和硬 fault 可以響應(yīng))
          BX LR ;返回

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

          OSStartHighRdy()由 OSStart()調(diào)用,用來啟動(dòng)最高優(yōu)先級(jí)任務(wù),當(dāng)然任務(wù)必須在OSStart()前已被創(chuàng)建。
          OSStartHighRdy
          ;設(shè)置 PendSV 中斷的優(yōu)先級(jí) #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
          ;設(shè)置 PSP 為0 #2
          MOVS R0, #0 ;R0 = 0
          MSR PSP, R0 ;PSP = R0
          ;設(shè)置 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),應(yīng)該不會(huì)到這里
          B OSStartHang
          #1.PendSV 中斷的優(yōu)先級(jí)應(yīng)該為最低優(yōu)先級(jí),原因在<>的 7.6 節(jié)已有說明。
          #2.PSP 設(shè)置為 0,是告訴具體的任務(wù)切換程序(OS_CPU_PendSVHandler()),這是第一次任務(wù)切換。做過切換后 PSP 就不會(huì)為0了,后面會(huì)看到。
          #3.往中斷控制及狀態(tài)寄存器 ICSR(0xE000ED04)第 28 位寫 1 即可產(chǎn)生 PendSV 中斷。這個(gè)<>8.4.5 其它異常的配置寄存器有說明。
          當(dāng)一個(gè)任務(wù)放棄 cpu 的使用權(quán),就會(huì)調(diào)用OS_TASK_SW()宏,而 OS_TASK_SW()就是 OSCtxSw()。OSCtxSw()應(yīng)該做任務(wù)切換。但是在 CM3 中,所有任務(wù)切換都被放到PendSV 的中斷處理函數(shù)中去做了,因此 OSCtxSw() 只需簡單的觸發(fā) PendSV中斷即可。OS_TASK_SW()是由OS_Sched()調(diào)用。
          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 ;返回
          當(dāng)一個(gè)中斷處理函數(shù)退出時(shí),OSIntExit()會(huì)被調(diào)用來決定是否有優(yōu)先級(jí)更高的任務(wù)需要執(zhí)行。如果有
          OSIntExit()對(duì)調(diào)用 OSIntCtxSw()做任務(wù)切換。
          OSIntCtxSw ;觸發(fā) PendSV 中斷
          LDR R0, =NVIC_INT_CTRL
          LDR R1, =NVIC_PENDSVSET
          STR R1, [R0]
          BX LR
          看到這里有人可能奇怪怎么 OSCtxSw()和OSIntCtxSw()完全一樣,事實(shí)上,這兩個(gè)函數(shù)的意義是不一樣的,OSCtxSw()做的是任務(wù)之間的切換,如任務(wù) A 因?yàn)榈却硞€(gè)資源或是做延時(shí)切換到任務(wù) B,而
          OSIntCtxSw()則是中斷退出時(shí),由中斷狀態(tài)切換到另一個(gè)任務(wù)。由中斷切換到任務(wù)時(shí),CPU 寄存器入棧的工作已經(jīng)做完了,所以無需做第二次了(參考邵老師書的 3.10 節(jié))。這里只不過由于 CM3 的特殊機(jī)制導(dǎo)致了在這兩個(gè)函數(shù)中只要做觸發(fā) PendSV中斷即可,具體切換由 PendSV 中斷來處理。
          前面已經(jīng)說過真正的任務(wù)切換是在 PendSV 中斷處理函數(shù)里做的,由于 CM3 在中斷時(shí)會(huì)有一半的寄存器自動(dòng)保存到任務(wù)堆棧里,所以在 PendSV 中斷處理函數(shù)中只需保存 R4-R11并調(diào)節(jié)堆棧指針即可。

          上一頁 1 2 下一頁

          關(guān)鍵詞: 移植ucosIISTM32F103Z

          評(píng)論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();