日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uCOS中任务调度时的上下文切换

發布時間:2024/4/18 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uCOS中任务调度时的上下文切换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

uCOS中任務調度時的上下文切換

這里以STM32處理器為例,也就是Cortex-M3內核。

所謂的上下文切換呢,就是當?uC/OS轉向執行另一個任務的時候,它保存了當前任務CPU?寄存器到堆棧。并從新任務的的堆棧中?CPU?寄存器載入?CPU

在這里上下文切換分為兩種:一個是任務級的,一個是中斷級的。



(1)?開始執行切換,保存狀態寄存器和程序指針寄存器到當前的任務堆棧。保存的順序與中斷發生時?CPU?保存寄存器的順序相同。假定?SR?先入棧,然后其它寄存器入棧

(2)?當任務被停止時,保存?CPU?的?TSP?到該任務的OS_TCB?中,換句話說,OSTCBCurPtr->StkPtr=R14

(3)?然后將新任務?OS_TCB?的頂部地址存入?CPU?TSP?中。換句話說,R14=OSTCBCurPtr->StkPtr

(4)?最后,?將新任務堆棧中?R13~~R0?關內容載入?CPU寄存器。再然后(此時的會?TSP?指向?PC,如圖)通過一個中斷返回指令{比如匯編中的?IRET},程序指針寄存器和狀態寄存器被恢復到?CPU?的寄存器中。

?

以上是一個大概的流程分析,下面來看看其具體的代碼實現過程,當然,這里是用匯編來實現。

?

PendSV_Handler

????CPSID???I???????????????????????????????????????????????????;?Prevent?interruption?during?context?switch關所以中斷

????MRS?????R0,?PSP?????????????????????????????????????????????;?PSP?is?process?stack?pointer??PSP是當前進程堆棧的指針,將PSP賦值給R0

????CBZ?????R0,?PendSV_Handler_Nosave?????????????????????;?Skip?register?save?the?first?time如果R00時跳轉到PendSV_Handler_Nosave

?

????SUBS????R0,?R0,?#0x20???????????????????????????????????????;?Save?remaining?regs?r4-11?on?process?stack偏移0x20的位置用來保存R4R11

????STM?????R0,?{R4-R11}?;將剩下的R4R11寄存器保存在此進程的堆棧中

?

????LDR?????R1,?=p_OSTCBCur?????????????????????????????????????;?OSTCBCur->OSTCBStkPtr?=?SP;?OSTCBCur->OSTCBStkPtr這個保存當前的棧尾,以便下次彈出

????LDR?????R1,?[R1]

????STR?????R0,?[R1]????????????????????????????????????????????;?R0?is?SP?of?process?being?switched?out

?

????????????????????????????????????????????????????????????????;?At?this?point,?entire?context?of?process?has?been?saved此時,整個上下文的過程已經被保存

PendSV_Handler_Nosave

????PUSH????{R14}???????????????????????????????????????????????;?Save?LR?exc_return?value

????LDR?????R0,?=OSTaskSwHook???????????????????????????????????;?OSTaskSwHook();??這里的話可以刪除的,用于用戶擴展呵呵

????BLX?????R0

????POP?????{R14}

?

????LDR?????R0,?=OSPrioCur??????????????????????????????????????;?OSPrioCur?=?OSPrioHighRdy;

????LDR?????R1,?=OSPrioHighRdy?;將當前優先級變量指向最高優先級

????LDRB????R2,?[R1]

????STRB????R2,?[R0]

?

????LDR?????R0,?=p_OSTCBCur?????????????????????????????????????;?OSTCBCur??=?OSTCBHighRdy;

????LDR?????R1,?=p_OSTCBHighRdy?;TCB表也一樣

????LDR?????R2,?[R1]

????STR?????R2,?[R0]

;到這里,[R2]保存的是新的進程的堆棧指針SP

????LDR?????R0,?[R2]????????????????????????????????????????????;?R0?is?new?process?SP;?SP?=?OSTCBHighRdy->OSTCBStkPtr;??將堆棧指針賦值給SP

????LDM?????R0,?{R4-R11}????????????????????????????????????????;?Restore?r4-11?from?new?process?stack?彈出其它寄存器,和前面的是一個逆過程

????ADDS????R0,?R0,?#0x20?;和前面的逆過程對比可知

????MSR?????PSP,?R0?????????????????????????????????????????????;?Load?PSP?with?new?process?SPR0中的SP賦值給PSP寄存器

????ORR?????LR,?LR,?#0x04???????????????????????????????????????;?Ensure?exception?return?uses?process?stack確保異常返回時使用進程堆棧

????CPSIE???I?;開中斷

????BX??????LR??????????????????????????????????????????????????;?Exception?return?will?restore?remaining?context異常返回將恢復那些自動出棧的剩余寄存器

?

暈,排版有點亂,勉強湊合著看吧。。。

可以看出這其實是一個PendSV中斷來的,也就是M3的可編程掛起中斷,為什么用這個中斷來進行上下文切換呢?后面將會進行說明下。

CBZ?????R0,?PendSV_Handler_Nosave

這句是用來判斷是否第一次進入切換,也就是系統剛啟動的時候,則直接跳到PendSV_Handler_Nosave這個標號來執行了,因為系統剛啟動還沒有當前任務嘛。

當不是剛啟動的,進行上下文切換,首先是要將當前任務的寄存器保存下來,保存到當前任務的堆棧里,R4-R11手動保存到堆棧,其余會自動保存。

然后

????LDR?????R0,?=OSPrioCur??????????????????????????????????????;?OSPrioCur?=?OSPrioHighRdy;

????LDR?????R1,?=OSPrioHighRdy?;將當前優先級變量指向最高優先級

????LDRB????R2,?[R1]

????STRB????R2,?[R0]

?

????LDR?????R0,?=p_OSTCBCur?????????????????????????????????????;?OSTCBCur??=?OSTCBHighRdy;

????LDR?????R1,?=p_OSTCBHighRdy?;TCB表也一樣

????LDR?????R2,?[R1]

????STR?????R2,?[R0]

這里是將優先級最高的,也就是需要切換到的那個任務替換為當前任務。

然后讓PSP指向任務堆棧,再然后是一個逆過程,彈出堆棧里的數據到對應的寄存器。

?

上下文切換就差不多這樣。。。

關于在M3內核,為什么使用PendSV這個中斷來進行上下文切換呢?其原因是這個中斷擁有最低優先級的軟件中斷。

又問,為什么要在擁有最低優先級的軟件中斷中進行切換呢?這個答案在《Cortex-M3權威指南》第7章?異常???里有詳細的答案。

總結

以上是生活随笔為你收集整理的uCOS中任务调度时的上下文切换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。