中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

茶葉網(wǎng)站建設(shè)公司做網(wǎng)站seo推廣公司

茶葉網(wǎng)站建設(shè)公司,做網(wǎng)站seo推廣公司,網(wǎng)站開發(fā)作品,php網(wǎng)站開發(fā)工程師崗位職責(zé)SylixOS 操作系統(tǒng)下,任務(wù)切換可以分為兩種 中斷退出時(shí),執(zhí)行的任務(wù)切換(_ScheduleInt)內(nèi)核退出時(shí),執(zhí)行的任務(wù)切換(_Schedule) 下面分別講講這兩種任務(wù)切換 1、中斷退出時(shí)任務(wù)切換 關(guān)于 ARM 架…

SylixOS 操作系統(tǒng)下,任務(wù)切換可以分為兩種

  • 中斷退出時(shí),執(zhí)行的任務(wù)切換(_ScheduleInt)
  • 內(nèi)核退出時(shí),執(zhí)行的任務(wù)切換(_Schedule)

下面分別講講這兩種任務(wù)切換

1、中斷退出時(shí)任務(wù)切換

關(guān)于 ARM 架構(gòu)下,??臻g,推薦這篇文章:ARM 棧和函數(shù)調(diào)用

;/*********************************************************************************************************
;  中斷入口
;*********************************************************************************************************/FUNC_DEF(archIntEntry);/* 在 IRQ 模式下,LR(R14_irq)存儲的是 當(dāng)前執(zhí)行地址 + 4,所以需要 減 4 調(diào)整回正確的返回地址 */SUB     LR , LR, #4                                                 ;/*  調(diào)整用于中斷返回的 PC 值    */;/* 保存 REG 到 IRQ 模式??臻g(中斷上下文保存)*/STMFD   SP!, {LR}                                                   ;/*  保存返回地址                */STMFD   SP!, {R0-R12}                                               ;/*  保存寄存器                  */;/* 將當(dāng)前 IRQ 模式的棧指針 SP_irq 存入 R1(用于后續(xù)保存 SYS 模式寄存器)*/MOV     R1 , SPMSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式               */;/* 將 SYS 模式的棧指針 SP_sys 存入 R1 指向的內(nèi)存(保存任務(wù)棧)*/STMFD   R1!, {SP}                                                   ;/*  保存 SP_sys                 */;/* 將 SYS 模式的鏈接寄存器 LR_sys 存入 R1 指向的內(nèi)存(保存任務(wù)返回地址) */STMFD   R1 , {LR}                                                   ;/*  保存 LR_sys                 */MSR     CPSR_c, #(DIS_INT | IRQ32_MODE)                             ;/*  回到 IRQ 模式               */SUB     SP , SP , #(2 * 4)                                          ;/*  調(diào)整 SP_irq                 */;/* 讀取 SPSR_irq(保存了被中斷任務(wù)的 CPSR_sys) */MRS     R2 , SPSR;/* 將 SPSR_irq(即原 CPSR_sys)壓入 IRQ 模式棧(保存任務(wù)狀態(tài)) */STMFD   SP!, {R2}                                                   ;/*  保存 CPSR_sys               */;/*; * API_InterEnter(SP_irq), 如果是第一次中斷, 會將 IRQ 模式??臻g的 ARCH_REG_CTX; * 拷貝到當(dāng)前任務(wù) TCB 的 ARCH_REG_CTX 里; */MOV     R0 , SPLDR     R1 , =API_InterEnterMOV     LR , PCBX      R1;/*; * 如果不是第一次進(jìn)入中斷, 那么上一次中斷(工作在 SYS 模式)已經(jīng)設(shè)置 SP_sys, 只需要回到 SYS 模式; */CMP     R0 , #1BNE     1f;/*; * 第一次進(jìn)入中斷: 因?yàn)橐呀?jīng)將 IRQ 模式棧空間的 ARCH_REG_CTX 拷貝到當(dāng)前任務(wù) TCB 的 ARCH_REG_CTX 里; * 調(diào)整 SP_irq; */ADD     SP , SP , #(ARCH_REG_CTX_SIZE);/*; * 第一次進(jìn)入中斷: 獲得當(dāng)前 CPU 中斷堆棧棧頂, 并回到 SYS 模式, 并設(shè)置 SP_sys; */LDR     R0 , =API_InterStackBaseGetMOV     LR , PCBX      R0MSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式               */MOV     SP , R0                                                     ;/*  設(shè)置 SP_sys                 */1:MSR     CPSR_c, #(DIS_INT | SYS32_MODE)                             ;/*  回到 SYS 模式(不是多余的)   */;/*; * bspIntHandle(); */LDR     R1 , =bspIntHandleMOV     LR , PCBX      R1;/*; * API_InterExit(); * 如果沒有發(fā)生中斷嵌套, 則 API_InterExit 會調(diào)用 archIntCtxLoad 函數(shù), SP_irq 在上面已經(jīng)調(diào)整好; */LDR     R1 , =API_InterExitMOV     LR , PCBX      R1

??這里有一個(gè)很重要的點(diǎn),API_InterStackBaseGet函數(shù)。因?yàn)?ARM 異常棧通常不會很大,而我們后面調(diào)用的 bspIntHandle 是一個(gè) C 函數(shù),需要用到堆棧。所以這里調(diào)用 API_InterStackBaseGet 函數(shù)設(shè)置了一個(gè)操作系統(tǒng)給每個(gè) CPU 分配的中斷堆棧。

LW_API
ULONG    API_InterEnter (ARCH_REG_T  reg0,ARCH_REG_T  reg1,ARCH_REG_T  reg2,ARCH_REG_T  reg3)
{PLW_CLASS_CPU  pcpu;pcpu = LW_CPU_GET_CUR();pcpu->CPU_ulInterNesting++;#if !defined(__SYLIXOS_ARM_ARCH_M__) || (LW_CFG_CORTEX_M_SVC_SWITCH > 0)archIntCtxSaveReg(pcpu, reg0, reg1, reg2, reg3);
#endif	......
}

這里要注意,中斷上下文的保存,不僅僅需要保存到 ARM 架構(gòu)的異常棧中,同時(shí)也需要保存一份,到當(dāng)前任務(wù) TCB 中。因?yàn)橹袛嗤顺鰰r(shí)(API_InterExit),會進(jìn)行調(diào)度(_ScheduleInt)。所以無法保證中斷結(jié)束后,一定運(yùn)行的是之前被中斷的任務(wù),也有可能是其它高優(yōu)先級任務(wù)。之前被中斷的任務(wù)的上下文現(xiàn)場,必須要保存一份到它自己的 TCB 中!用于后面恢復(fù)!

??API_InterExit 函數(shù)中的 __KERNEL_SCHED_INT 會進(jìn)行一系列判斷,查找到需要切換的任務(wù)(不一定是之前被打斷的任務(wù)),獲得任務(wù)的 TCB 控制塊。然后使用 archIntCtxLoad 函數(shù)進(jìn)行任務(wù)上下文切換。

LW_API
VOID    API_InterExit (VOID)
{......__KERNEL_SCHED_INT(pcpu);											/*  中斷中的調(diào)度                */......
#if !defined(__SYLIXOS_ARM_ARCH_M__) || (LW_CFG_CORTEX_M_SVC_SWITCH > 0)archIntCtxLoad(pcpu);                                               /*  中斷返回 (當(dāng)前任務(wù) CTX 加載)*/
#endif......
}
FUNC_DEF(archTaskCtxStart)LDR     R0 , [R0]                                                   ;/*  獲取當(dāng)前 TCB 的 REG_CTX 地址*/LINE_LABEL(archTaskCtxLoad)LDMIA   R0!, {R2-R4}                                                ;/*  讀取 CPSR LR SP             */MSR     CPSR_c , #(DIS_INT | SYS32_MODE)                            ;/*  進(jìn)入 SYS 模式, 關(guān)中斷       */MOV     SP , R4                                                     ;/*  恢復(fù) SP_sys                 */MOV     LR , R3                                                     ;/*  恢復(fù) LR_sys                 */MSR     CPSR_c, #(DIS_INT | SVC32_MODE)                             ;/*  進(jìn)入 SVC 模式, 關(guān)中斷       */MSR     SPSR_cxsf , R2                                              ;/*  CPSR_sys -> SPSR_svc        */LDMIA   R0 , {R0-R12, PC}^                                          ;/*  恢復(fù)包括 PC 的所有寄存器,   */;/*  同時(shí)更新 CPSR               */FUNC_END()FUNC_DEF(archIntCtxLoad)B       archTaskCtxStartFUNC_END()

2、內(nèi)核退出時(shí)任務(wù)切換

??在內(nèi)核退出時(shí)最終會調(diào)用 archTaskCtxSwitch 函數(shù)進(jìn)行任務(wù)切換。

INT  _Schedule (VOID)
{....../* 前面的調(diào)度已經(jīng)找到了一個(gè)最適合在當(dāng)前核上運(yùn)行的任務(wù),下面就是將該任務(wù)加載到當(dāng)前 CPU 核的寄存器中 */archTaskCtxSwitch(pcpuCur);  ......
}
/*********************************************************************************************************
** 函數(shù)名稱: __kernelExit
** 功能描述: 退出內(nèi)核狀態(tài)
** 輸 入  : NONE
** 輸 出  : 調(diào)度器返回值
** 全局變量: 
** 調(diào)用模塊: 
*********************************************************************************************************/
INT  __kernelExit (VOID)
{......iRetVal = _Schedule();                                      /*  嘗試調(diào)度                    */......
}

??首先是保存當(dāng)前上下文,和進(jìn)入中斷時(shí)一樣,保存當(dāng)前 TCB 上下文。這里有一個(gè)很重要的點(diǎn),_SchedSafeStack函數(shù)。因?yàn)槭侨蝿?wù)調(diào)度,所以使用的棧還是當(dāng)前 TCB 的棧。因?yàn)槲覀兿旅嫘枰{(diào)用 _SchedSwp C 函數(shù),會用到棧,可能會破壞之前 TCB 的??臻g。所以我們需要調(diào)用 _SchedSafeStack函數(shù)來獲取一個(gè)額外的堆??臻g。

??然后調(diào)用 _SchedSwp 程序進(jìn)行切換當(dāng)前 CPU 控制塊的當(dāng)前 TCB,然后進(jìn)行上下文恢復(fù)。

;/*********************************************************************************************************
;  線程切換 
;  參數(shù)為當(dāng)前 CPU 控制塊, 即 R0 為當(dāng)前 CPU 控制塊指針
;*********************************************************************************************************/FUNC_DEF(archTaskCtxSwitch)LDR     R1 , [R0]                                                   ;/*  獲取當(dāng)前 TCB                */ADD     R1 , R1 , #(ARCH_REG_CTX_SIZE)                              ;/*  當(dāng)前 TCB 的 REG_CTX 頂端地址*//* 保存當(dāng)前 TCB 的上下文,保存到當(dāng)前 TCB 中 */STMFD   R1!, {LR}                                                   ;/*  保存返回地址                */STMFD   R1 , {R0-R12}                                               ;/*  保存寄存器                  */SUB     R1 , R1 , #(13 * 4)                                         ;/*  調(diào)整 R1                     */STMFD   R1!, {SP}                                                   ;/*  保存 SP                     */STMFD   R1!, {LR}                                                   ;/*  保存 LR                     */MRS     R2 , CPSR                                                   ;/*  保存 CPSR                   */STMFD   R1!, {R2}MOV     R9 , R0                                                     ;/*  備份 R0                     */
#if LW_CFG_SMP_EN > 0LDR     R1 , =_SchedSafeStack                                       ;/*  _SchedSafeStack();          */MOV     LR , PCBX      R1MOV     SP , R0                                                     ;/*  設(shè)置 SP                     */MOV     R0 , R9                                                     ;/*  恢復(fù) R0                     */
#endif;/* 這里會去切換當(dāng)前 CPU 控制塊的當(dāng)前 TCB */LDR     R1 , =_SchedSwp                                             ;/*  _SchedSwp();                */MOV     LR , PCBX      R1MOV     R0 , R9                                                     ;/*  恢復(fù) R0                     */;/* 因?yàn)閯倓傄呀?jīng)切換過,這里直接恢復(fù)切換后的 TCB 上下文 */B       archTaskCtxStartFUNC_END()

archTaskCtxStart 這里和中斷退出時(shí)恢復(fù)寄存器一樣。

http://www.risenshineclean.com/news/44064.html

相關(guān)文章:

  • 怎么用服務(wù)器ip做網(wǎng)站谷歌官方網(wǎng)站首頁
  • 花錢做推廣廣告哪個(gè)網(wǎng)站好網(wǎng)絡(luò)營銷的發(fā)展現(xiàn)狀及趨勢
  • 怎么樣建設(shè)一個(gè)電影網(wǎng)站友情鏈接網(wǎng)自動(dòng)收錄
  • 廣州市建設(shè)交易中心網(wǎng)站首頁深圳網(wǎng)絡(luò)推廣專員
  • 做短視頻的網(wǎng)站網(wǎng)址怎么申請注冊
  • 網(wǎng)站備案主體撤銷西安網(wǎng)站建設(shè)優(yōu)化
  • 愛眼護(hù)眼ppt模板免費(fèi)下載 素材鶴壁seo
  • 湖北網(wǎng)站建設(shè)的釋義搜索網(wǎng)站有哪幾個(gè)
  • 網(wǎng)站建設(shè)學(xué)習(xí)廣告公司主要做什么
  • 網(wǎng)站可以做電信增值百度的首頁
  • 什么是小手機(jī)型網(wǎng)站網(wǎng)銷是做什么的
  • 蘇州做網(wǎng)站最好公司軟文是什么東西
  • 政府部門網(wǎng)站建設(shè)負(fù)責(zé)部門百度一下首頁網(wǎng)址百度
  • 云主機(jī)網(wǎng)站配置網(wǎng)頁設(shè)計(jì)需要學(xué)什么軟件
  • 做a 免費(fèi)網(wǎng)站如何制作一個(gè)網(wǎng)址
  • 南昌企業(yè)網(wǎng)站設(shè)計(jì)建設(shè)制作百度風(fēng)云榜
  • 深圳開發(fā)網(wǎng)站建設(shè)搜索引擎推廣的基本方法
  • 松江專業(yè)做網(wǎng)站公司谷歌關(guān)鍵詞搜索排名
  • 什么APP可以做網(wǎng)站網(wǎng)絡(luò)推廣發(fā)帖網(wǎng)站
  • 布吉做棋牌網(wǎng)站建設(shè)好的在線crm系統(tǒng)
  • wordpress自定義頁seo代碼優(yōu)化包括哪些
  • nodejs做網(wǎng)站能保護(hù)源代碼嗎廊坊seo排名霸屏
  • 做js鏈接的網(wǎng)站要加證書嗎seo具體優(yōu)化流程
  • 免費(fèi)電子版?zhèn)€人簡歷可編輯李江seo
  • 網(wǎng)頁設(shè)計(jì)證書考什么昆明百度關(guān)鍵詞優(yōu)化
  • 網(wǎng)站后臺界面 園林設(shè)計(jì)怎樣做搜索引擎推廣
  • iis5.1建網(wǎng)站網(wǎng)站測試
  • 網(wǎng)站建設(shè)預(yù)算明細(xì)表網(wǎng)絡(luò)營銷策劃案
  • java做的網(wǎng)站怎么轉(zhuǎn)appseo沈陽
  • 南寧商城網(wǎng)站建設(shè)網(wǎng)絡(luò)促銷的方法有哪些