欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

     找回密碼
     立即注冊

    QQ登錄

    只需一步,快速開始

    搜索
    查看: 4188|回復: 1
    打印 上一主題 下一主題
    收起左側

    UCOS移植代碼之LAMMY分析--OS_CPU_a.s

    [復制鏈接]
    跳轉到指定樓層
    樓主
    ID:72519 發表于 2015-1-23 20:46 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    OS_CPU_a.s:
    ;定義系統模式堆棧的大小
    SVC_STACK_LEGTH EQU 32

    NoInt EQU 0x80

    USR32Mode EQU 0x10
    SVC32Mode EQU 0x13
    SYS32Mode EQU 0x1f
    IRQ32Mode EQU 0x12
    FIQ32Mode EQU 0x11

    ;T_bit用于檢測進入異常前cpu是否處于THUMB狀態
    T_bit EQU 0x20

    CODE32

    AREA |subr|, CODE, READONLY

    IMPORT OSTCBCur ;指向當前任務TCB的指針
    IMPORT OSTCBHighRdy ;指向將要運行的任務TCB的指針
    IMPORT OSPrioCur ;當前任務的優先級
    IMPORT OSPrioHighRdy ;將要運行的任務的優先級
    IMPORT OSTaskSwHook ;任務切換的鉤子函數
    IMPORT OSRunning ;uC/OS-II運行標志

    IMPORT OsEnterSum ;關中斷計數器(關中斷信號量)
    IMPORT SWI_Exception ;軟中斷異常處理程序

    EXPORT __OSStartHighRdy
    EXPORT OSIntCtxSw ;中斷退出時的入口,參見startup.s中的IRQ_Handler
    EXPORT SoftwareInterrupt ;軟中斷入口

    ;軟件中斷
    //當CPU發現有軟中斷信號出現時,CPU的PC馬上指到軟中斷服務地址處【見Startup.s】,然后通過跳轉到下面這段軟中斷處理程序,進入后,首先要設置好管理模式下的堆棧,保存好用戶任務的幾個寄存器,其它寄存器系統會自動保存,然后取出SWI號。
    SoftwareInterrupt
    LDR SP, StackSvc ; 重新設置堆棧指針
    STMFD SP!, {R0-R3, R12, LR} //為什么只保存這幾個寄存器,見上面的解釋
    MOV R1, SP ; R1指向參數存儲位置

    MRS R3, SPSR //保存管理模式的狀態寄存器
    TST R3, #T_bit ; 中斷前是否是Thumb狀態
    LDRNEH R0, [LR,#-2] ; 是: 取得Thumb狀態SWI號
    BICNE R0, R0, #0xff00
    LDREQ R0, [LR,#-4] ; 否: 取得arm狀態SWI號
    BICEQ R0, R0, #0xFF000000
    ; r0 = SWI號,R1指向參數存儲位置
    CMP R0, #1
    LDRLO PC, =OSIntCtxSw
    LDREQ PC, =__OSStartHighRdy ; SWI 0x01為第一次任務切換

    BL SWI_Exception

    LDMFD SP!, {R0-R3, R12, PC}^

    StackSvc DCD (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

    OSIntCtxSw
    ;下面為保存任務環境
    LDR R2, [SP, #20] ;獲取PC//其實他就是管理模式下的LR寄存器的值,也就是用戶任務的PC值,為什么是SP+20,因為該棧是滿棧遞減,保存了R0-R3, R12, LR,所以LR的值為[SP+#20]。
    LDR R12, [SP, #16] ;獲取R12
    MRS R0, CPSR //用通用寄存器R0保存該管理模式下的CPSR

    MSR CPSR_c, #(NoInt | SYS32Mode)//切換到系統模式
    MOV R1, LR //把用戶的LR保存在通用寄存器R1中
    STMFD SP!, {R1-R2} ;保存LR,PC//把系統模式的LR,PC壓入用戶任務的棧中
    STMFD SP!, {R4-R12} ;保存R4-R12//把系統模式的R4-R12壓入用戶棧中

    MSR CPSR_c, R0 //重新回到管理模式
    LDMFD SP!, {R4-R7} ;獲取R0-R3//實際上把用戶的R0~R3放到管理模式下的R4-R7
    ADD SP, SP, #8 ;出棧R12,PC//這兩個已經保存了,所以SP要往上8個字節

    MSR CPSR_c, #(NoInt | SYS32Mode//系統模式
    STMFD SP!, {R4-R7} ;保存R0-R3//因為管理模式的R4-R11和系統模式的R4-R11是一樣的,保它保存在用戶任務的棧中
    //接下來的我就不分析拉,因為你如果按照我上面的分析,應該不成問題的,如果還未明白,請多看幾遍,如果有問題,請留言我們一起來探討,謝謝合作!上面的分析除了紅色部分是周立功公司的注釋外,其余都是我的理解,如果有錯的,真心希望您能指出!謝謝!
    LDR R1, =OsEnterSum ;獲取OsEnterSum
    LDR R2, [R1]
    STMFD SP!, {R2, R3} ;保存CPSR,OsEnterSum

    ;保存當前任務堆棧指針到當前任務的TCB
    LDR R1, =OSTCBCur
    LDR R1, [R1]
    STR SP, [R1]

    BL OSTaskSwHook ;調用鉤子函數
    ;OSPrioCur <= OSPrioHighRdy
    LDR R4, =OSPrioCur
    LDR R5, =OSPrioHighRdy
    LDRB R6, [R5]
    STRB R6, [R4]
    ;OSTCBCur <= OSTCBHighRdy
    LDR R6, =OSTCBHighRdy
    LDR R6, [R6]
    LDR R4, =OSTCBCur
    STR R6, [R4]
    OSIntCtxSw_1
    ;獲取新任務堆棧指針
    LDR R4, [R6]
    ADD SP, R4, #68 ;17寄存器CPSR,OsEnterSum,R0-R12,LR,SP
    LDR LR, [SP, #-8]
    MSR CPSR_c, #(NoInt | SVC32Mode) ;進入管理模式
    MOV SP, R4 ;設置堆棧指針

    LDMFD SP!, {R4, R5} ;CPSR,OsEnterSum
    ;恢復新任務的OsEnterSum
    LDR R3, =OsEnterSum
    STR R4, [R3]

    MSR SPSR_cxsf, R5 ;恢復CPSR
    LDMFD SP!, {R0-R12, LR, PC }^ ;運行新任務


    __OSStartHighRdy
    MSR CPSR_c, #(NoInt | SYS32Mode)
    ;告訴uC/OS-II自身已經運行
    LDR R4, =OSRunning
    MOV R5, #1
    STRB R5, [R4]

    BL OSTaskSwHook ;調用鉤子函數

    LDR R6, =OSTCBHighRdy
    LDR R6, [R6]
    B OSIntCtxSw_1

    AREA SWIStacks, DATA, NOINIT,ALIGN=2
    SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;管理模式堆棧空間

    END


    分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
    收藏收藏 分享淘帖 頂 踩
    回復

    使用道具 舉報

    沙發
    ID:68804 發表于 2015-2-9 15:05 | 只看該作者
    學習了
    回復

    使用道具 舉報

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規則

    小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

    Powered by 單片機教程網

    快速回復 返回頂部 返回列表