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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

RT-Thread内核之线程调度(5)

發布時間:2025/4/14 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RT-Thread内核之线程调度(5) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載于:?http://blog.csdn.net/lpjybn/article/details/46911559

?

5.線程切換的本質?

到現在我們知道,每個線程的執行需要一定的“物質”基礎。首先,需要獲得CPU的使用權,這就包括CPU內部各寄存器的使用,然后有自己獨立的棧空間,這部分的空間每個線程應該各自獨立。然后,每個線程都有一段獨特的指令以完成特定的功能。由這些就組成了“線程上下文”,線程的切換就是線程上下文的切換。在RT-Thread中有兩個架構相關的函數來完成這項工作:rt_hw_context_switch,rt_hw_context_switch_interrupt。 那么這兩個函數有什么區別呢?顯然,rt_hw_context_switch是在非中斷中進行上下文切換,而rt_hw_context_switch_interrupt則是在中斷上下文中完成線程切換的。這里以S3C2440處理為例: /******************************************************************************************* ** 函數名稱: rt_hw_context_switch ** 函數功能: 非中斷中進行上下文切換 ** 入口參數: from 被切出的線程的棧頂指針 ** to 被切入的線程的棧頂指針 ** 返 回 值: 無 ** 調 用: *******************************************************************************************/ .globl rt_hw_context_switch rt_hw_context_switch: ? ? stmfd sp!, {lr} ? ?/** 將被中斷的線程的下一條要執行的指令的地址壓入棧中 ?*?(LR存放下一條將要執行的指令地址)? ?*/ ? ? stmfd sp!, {r0-r12, lr}/** 將LR,R12-R0寄存器依次入棧 */ ? ? ??mrs r4, cpsr ? ? ? ? ? ??/** 讀取CPSR寄存器的值到R4中 */ ? ? stmfd sp!, {r4} ? ? ? ? ?/** 將R4寄存器的值(CPSR)壓入棧中 */ ? ? mrs r4, spsr ? ? ? ? ? ??/** 讀取SPSR寄存器的值到R4寄存器中 */ ? ? stmfd sp!, {r4} ? ? ? ? ?/** 將R4寄存器的值(SPSR)壓入棧中 */ ? ? ? str sp, [r0] ? ? ? ? ? ??/** 將線程的棧頂指針保存到線程結構的sp中 */ ? ? ? ldr sp, [r1] ? ? ? ? ? ??/** 從新線程的線程結構的sp中取出該線程的棧頂指針 */ ? ? ? ldmfd sp!, {r4} ? ? ? ? ? ?/** 從線程的棧中彈出SPSR寄存器值到R4寄存器中 */ ? ? msr spsr_cxsf, r4 ? ? ? ? ?/** 將值寫入SPSR寄存器中 */ ? ? ldmfd sp!, {r4} ? ? ? ? ? ?/** 從線程的棧中彈出CPSR寄存器值到R4寄存器中 */ ? ? msr spsr_cxsf, r4 ? ? ? ? ?/** 將值寫入CPSR寄存器中 */ ? ? ? ldmfd sp!, {r0-r12, lr, pc}^ ? ??/** 恢復該線程其他寄存器的值PC,LR,R12 - R0 */ ? ? /******************************************************************************************* ** 函數名稱: rt_hw_context_switch_interrupt ** 函數功能: 中斷中進行上下文切換 ** 入口參數: from 被切出的線程的棧頂指針 ** to 被切入的線程的棧頂指針 ** 返 回 值: 無 ** 調 用: ******************************************************************************************/ .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread ? .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: ? ? ? ? /** 1.判斷rt_thread_switch_interrupt_flag變量的值是否為1 */ ? ??ldr r2, =rt_thread_switch_interrupt_flag? ??/** 加載變量rt_thread_switch_interrupt_flag ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 的地址到r2寄存器中? ? ? ? ? ?*/ ? ?ldr r3, [r2]?? ??/** 讀取rt_thread_switch_interrupt_flag寄存器的值到R3寄存器中 */ ? ?cmp r3, #1?? ? ??/** 判斷rt_thread_switch_interrupt_flag的值是否為1 */ ? ? ? /** 如果rt_thread_switch_interrupt_flag值為1 */ ? ?beq?_reswitch ? ??/** 如果rt_thread_switch_interrupt_flag值為1,跳轉到標號_reswitch執行 */ ? ?mov r3, #1?? ? ? ?/** 如果rt_thread_switch_interrupt_flag值為0,將其值設置為1 */ ? ?str r3, [r2] ? ? ?ldr r2, =rt_interrupt_from_thread ? ?/** 加載rt_interrupt_from_thread變量的地址到R2寄存 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 器中? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? ?str r0, [r2]?? ? ?/** 將被切換出的線程的棧頂地址保存到變量rt_interrupt_from_thread中 */ ? _reswitch: ? ?ldr r2, =rt_interrupt_to_thread ? ???/** 加載rt_interrupt_to_thread變量的地址到R2寄存器 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 中 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? ?str r1, [r2]?? ? ??/** 將被切入的線程的棧頂地址保存到變量rt_interrupt_to_thread中 */ ? ?mov pc, lr? ? /******************************************************************************************* ** 函數名稱: rt_hw_context_switch_interrupt ** 函數功能: 中斷中進行上下文切換 ** 入口參數: from 被切出的線程的棧頂指針 ** to 被切入的線程的棧頂指針 ** 返 回 值: 無 ** 調 用: *******************************************************************************************/ .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread ? .globl rt_hw_context_switch_interrupt rt_hw_context_switch_interrupt: ? ?/** 1.判斷rt_thread_switch_interrupt_flag變量的值是否為1 */ ?ldr r2, =rt_thread_switch_interrupt_flag/** 加載變量rt_thread_switch_interrupt_flag的地址到r2寄存器中 */ ?ldr r3, [r2] ? ??/** 讀取rt_thread_switch_interrupt_flag寄存器的值到R3寄存器中 */ ?cmp r3, #1 ? ? ??/** 判斷rt_thread_switch_interrupt_flag的值是否為1 */ ? ?/** 如果rt_thread_switch_interrupt_flag值為1 */ ?beq _reswitch ? ??/** 如果rt_thread_switch_interrupt_flag值為1,跳轉到標號_reswitch執行 */ ?mov r3, #1 ? ? ? ?/** 如果rt_thread_switch_interrupt_flag值為0,將其值設置為1 */ ?str r3, [r2] ? ?ldr r2, =rt_interrupt_from_thread ? ?/** 加載rt_interrupt_from_thread變量的地址到R2寄存器中 */ ?str r0, [r2] ? ? ?/** 將被切換出的線程的棧頂地址保存到變量rt_interrupt_from_thread中 */ ? _reswitch: ?ldr r2, =rt_interrupt_to_thread ? ???/** 加載rt_interrupt_to_thread變量的地址到R2寄存器中 */ ?str r1, [r2] ? ? ??/** 將被切入的線程的棧頂地址保存到變量rt_interrupt_to_thread中 */ ?mov pc, lr? ? ? 我們發現rt_hw_context_switch_interrupt并沒有完成線程的切換,只是用全局變rt_interrupt_from_thread 和rt_interrupt_to_thread保存了被換出和換入的線程的棧頂指針,而真正的切換過程在中斷處理中完成。 ? .globl rt_interrupt_enter .globl rt_interrupt_leave .globl rt_thread_switch_interrupt_flag .globl rt_interrupt_from_thread .globl rt_interrupt_to_thread vector_irq: ? ? stmfd sp!, {r0-r12,lr} ? ??/** 使用中斷模式的棧空間來存儲SVC模式下的PC, R12 - R0 */ ? ? bl?rt_interrupt_enter ? ? ?/** 調用rt_interrupt_enter函數: 中斷嵌套的層數加1 */ ? ? bl?rt_hw_trap_irq ? ? ? ? ?/** 根據中斷號去調用中斷處理程序:由于中斷處理程序是在IRQ模式執行, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 因此系統是不支持中斷嵌套的? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? bl?rt_interrupt_leave ? ???/** 調用rt_interrupt_leave函數: 中斷嵌套的層數減1 */ ? ? ? ? /** 在中斷退出之前,判斷rt_thread_switch_interrupt_flag變量的值是否為1 */ ? ? ldr r0, =rt_thread_switch_interrupt_flag ? ??/** 讀取變量rt_thread_switch_interrupt_flag ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 的地址到r0寄存器中? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? ldr r1, [r0] ? ? ? ? ?/** 讀取變量rt_thread_switch_interrupt_flag的值 */ ? ? cmp r1, #1 ? ? ? ? ???/** 判斷變量rt_thread_switch_interrupt_flag的值是否為1 */ ? ? ? beq?_interrupt_thread_switch ? ??/** 如果為1說明在退出中斷模式之前還需要進行任務切換工作; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 如果為0則可以安全的退出中斷模式了? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? ? ? ldmfd sp!, {r0-r12,lr} ? ? ?/** 恢復SVC模式下的各個寄存器值 */ ? ? subs pc, lr, #4 ? ? ? ? ? ??/** 繼續從被中斷點執行 */
? _interrupt_thread_switch: ? ? ??/** 1.將變量rt_thread_switch_interrupt_flag的值清0 */ ? ? mov r1, ?#0 ? ? ? ? ??/** 設置R1寄存器的值為0 */ ? ? str r1, ?[r0] ? ? ? ??/** 將變量rt_thread_switch_interrupt_flag的值設置為0 */ ? ? ? ldmfd sp!, {r0-r12,lr} ? ??/** 恢復保存在IRQ模式中的各寄存器值 */ ? ? stmfd sp!, {r0-r3} ? ? ? ??/** 將R0-R3寄存器入棧 */ ? ? mov r1, ?sp ? ? ? ? ? ? ? ?/** 將此時的棧指針保存在R1中 */ ? ? add sp, ?sp, #16 ? ? ? ? ??/** 將SP的值加16,SP重新指向R0-R3入棧時的位置 */ ? ? sub r2, ?lr, #4 ? ? ? ? ???/** 計算出被中斷的線程的PC值保存到R2中 */ ? ? ? mrs r3, ?spsr ? ? ? ? ? ??/** 加載被中斷的線程的CPSR寄存器值到R3寄存器中 */ ? ? orr r0, ?r3, #NOINT ? ? ??/** 屏蔽中斷位 */ ? ? msr spsr_c, r0 ? ? ? ? ? ?/** 將設置后的值寫回IRQ模式的SPSR寄存器中 */ ? ? ? ldr r0, ?=.+8 ? ? ? ? ? ??/** 通過反匯編查看: 是將下面第二條指令的地址存到R0中 */ ? ? movs pc, ?r0 ? ? ? ? ? ? ?/** movs指令會影響到CPSR,包括N,Z,C標志位,CPSR會被SPSR覆蓋 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 因此執行此條指令相當于完成處理器從IRQ到SVC模式的切換 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?* 下面指令的sp將為SVC下的sp寄存器,而非IRQ模式的sp ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/ ? ? ? stmfd sp!, {r2} ? ? ? ? ? ??/** 將被中斷的線程的PC值入棧 */ ? ? stmfd sp!, {r4-r12,lr} ? ? ?/** 將被中斷的線程的LR,R12-R4寄存器入棧 */ ? ? mov r4, ?r1 ? ? ? ? ? ? ? ??/** 將R1的值保存到R4 */ ? ? mov r5, ?r3 ? ? ? ? ? ? ? ??/** 將R3的值保存到R5(IRQ_SPSR) */ ? ? ldmfd r4!, {r0-r3} ? ? ? ? ?/** 將棧中保存的R0-R3寄存器值恢復 */ ? ? stmfd sp!, {r0-r3} ? ? ? ? ?/** 將R3-R0寄存器值入棧 */ ? ? stmfd sp!, {r5} ? ? ? ? ? ??/** 將舊任務的CPSR值入棧 */ ? ? mrs r4, ?spsr ? ? stmfd sp!, {r4} ? ? ? ? ? ??/** 將舊任務的SPSR值入棧 */ ? ? ? ? /** 讀取保存在變量rt_interrupt_from_thread的舊線程的sp值 */ ? ? ldr r4, ?=rt_interrupt_from_thread ? ? ldr r5, ?[r4] ? ? str sp, ?[r5] ? ? ? ? ? ? ??/** 保存換出任務的棧頂指針 */ ? ? ? ??/** 獲取新線程的棧頂指針 */ ? ? ldr r6, ?=rt_interrupt_to_thread ? ??/** 加載變量rt_interrupt_to_thread的地址到R6寄存器 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * 中? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ? ldr r6, ?[r6] ? ? ? ? ? ??/** 加載變量rt_interrupt_to_thread的值到R6中 */ ? ? ldr sp, ?[r6] ? ? ? ? ? ??/** 加載變量rt_interrupt_to_thread的值到SP寄存器中 */ ? ? ? ldmfd sp!, {r4} ? ? ? ? ? ??/** 彈出新線程的SPSR寄存器值 */ ? ? msr SPSR_cxsf, r4 ? ? ldmfd sp!, {r4} ? ? ? ? ? ??/** 彈出新線程的CPSR寄存器值 */ ? ? msr CPSR_cxsf, r4 ? ? ? ldmfd sp!, {r0-r12,lr,pc} ??/** 彈出新線程的其他各寄存器,線程恢復 */

?

轉載于:https://www.cnblogs.com/tureno/articles/7999942.html

總結

以上是生活随笔為你收集整理的RT-Thread内核之线程调度(5)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 精品在线一区二区三区 | 天堂欧美城网站网址 | 日本大尺度做爰呻吟 | 中文字幕在线播放一区二区 | 黄网免费在线观看 | 亚洲射图| 久久亚洲av无码精品色午夜麻豆 | 中国亚洲老头同性gay男男… | 女同久久另类69精品国产 | 色丁香婷婷 | 国产91视频在线 | 免费看黄20分钟 | 亚洲午夜无码久久久久 | 久久这里只有精品23 | 久久资源av| 精品国产乱码 | 国产精品8 | 亚洲好看站 | 久久免费毛片 | 麻豆网站入口 | 欧美视频久久 | 在线观看中文字幕一区 | 欧美一区二区免费视频 | 亚洲福利一区 | 福利视频h | 美女毛片在线观看 | 哪个网站可以看毛片 | 91网站免费观看 | 波多野结衣一区二区三区 | 国产黄色免费网站 | 男人的天堂一区 | 久久露脸| 日日干夜 | www成人免费视频 | 丰满人妻一区二区三区精品高清 | 亚洲精品在线一区二区 | 男女插插插网站 | 免费在线观看黄网站 | 国产青青草在线 | 香港三级日本三级三69 | 久草手机在线观看 | 天天干天天干 | 国产福利视频一区二区三区 | 日韩精品一区在线播放 | 精品在线视频观看 | 中文字幕在线观看一区二区三区 | 91精品国产高清一区二区三蜜臀 | 蜜臀少妇久久久久久久高潮 | 美女黄视频大全 | 成人夜晚看av | 97av在线 | 免费性情网站 | 丝袜在线一区 | 91精品国自产在线偷拍蜜桃 | 5d肉蒲团之性战奶水 | 欧美日韩一区二区视频观看 | 日韩欧美国产亚洲 | 四虎影库 | 国产a视频 | 特黄aaaaaaaaa真人毛片 | 超碰人人在线观看 | 欧洲av网站 | 青草青在线视频 | 国产精品欧美激情 | 天天热天天干 | 中文在线字幕免费观 | 在线观看网址你懂的 | 久久免费的精品国产v∧ | 天天天天天干 | 原神淫辱系列同人h | 精品成在人线av无码免费看 | 波多野结衣一区二区三区在线观看 | 久久av免费| 国产高清露脸 | 日本免费一区二区三区视频 | 国产成人精品毛片 | 国产传媒一区二区三区 | 精品久久BBBBB精品人妻 | 亚洲欧美精品久久 | 主播福利在线 | 日韩欧美一区二区三区在线观看 | 午夜时刻免费入口 | 自拍偷拍21p | 欧美一区二区久久久 | a视频在线观看免费 | 成人免费xxxxx在线观看 | 国产一级二级三级视频 | 桃色视频网站 | 中日韩在线观看视频 | 老熟女重囗味hdxx69 | 欧美一区二区性久久久 | 亚洲天堂一区二区 | 变态另类ts人妖一区二区 | 国产精品第13页 | 成人在线亚洲 | 精品视频导航 | 黄污视频在线播放 | 免费看裸体网站视频 | 欧美亚洲一区二区在线观看 |