搜索
bottom↓
回复: 8

谁能指出来uC/OS-II中任务级任务切换那条指令是将"PC指令寄存器"压入堆

[复制链接]

出0入0汤圆

发表于 2010-3-23 14:06:13 | 显示全部楼层 |阅读模式
好多人认为对任务切换了解的非常透彻了,其实不然.

   其实在MSDOS时代,文件型病毒就是采用类似的机制,获取病毒代码当前所处的绝对位置的.

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2010-3-23 14:19:31 | 显示全部楼层
采用软件中断方式,模拟一个中断过程,压入堆栈应该是CPU自动处理的,我没找到相关的指令。
而IRET指令,先弹出地址,后弹出PC指针吧。

出0入0汤圆

发表于 2010-3-23 14:28:39 | 显示全部楼层
;**********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From task level)
;                                           void OSCtxSw(void)
;
; Note(s):            1) Upon entry:
;                        OSTCBCur      points to the OS_TCB of the task to suspend
;                        OSTCBHighRdy  points to the OS_TCB of the task to resume
;
;                     2) The stack frame of the task to suspend looks as follows:
;                                                   
;                                                   PC                    (High memory)
;                                                                                                          LR(R14)                                       
;                                                                       R12
;                                                                               R11
;                                                                       R10
;                                                                               R9
;                                                                       R8
;                                                                       R7
;                                                                       R6
;                                                                       R5
;                                                                       R4
;                                                                       R3
;                                                                       R2
;                                                                       R1
;                                                                       R0
;                                                 OSTCBCur->OSTCBStkPtr ----> CPSR                                        (Low memory)
;
;
;                     3) The stack frame of the task to resume looks as follows:
;
;                                                                                                            PC                                (High memory)
;                                                   LR(R14)       
;                                                                               R12
;                                                                       R11
;                                                                       R10
;                                                                               R9
;                                                                       R8
;                                                                       R7
;                                                                               R6
;                                                                       R5
;                                                                       R4
;                                                                       R3
;                                                                       R2
;                                                                       R1
;                                                                               R0
;                                         OSTCBHighRdy->OSTCBStkPtr ---->        CPSR                                        (Low memory)
;*********************************************************************************************************/
OSCtxSw
       
        STMFD        SP!, {LR}           ;PC
        STMFD        SP!, {R0-R12, LR}   ;R0-R12 LR
        MRS                R0,  CPSR       ;Push CPSR
        STMFD        SP!, {R0}       
               
        ;----------------------------------------------------------------------------------
        ;                 OSTCBCur->OSTCBStkPtr = SP
        ;----------------------------------------------------------------------------------               
        LDR                R0, =OSTCBCur
        LDR                R0, [R0]
        STR                SP, [R0]
       
        ;----------------------------------------------------------------------------------               
        ; OSTaskSwHook();
        ;---------------------------------------------------------------------------------       
        BL                 OSTaskSwHook

        ;----------------------------------------------------------------------------------                       
        ; OSTCBCur = OSTCBHighRdy;
        ;----------------------------------------------------------------------------------               
        LDR                R0, =OSTCBHighRdy
        LDR                R1, =OSTCBCur
        LDR                R0, [R0]
        STR                R0, [R1]
       
        ;----------------------------------------------------------------------------------               
        ; OSPrioCur = OSPrioHighRdy;
        ;----------------------------------------------------------------------------------               
        LDR                R0, =OSPrioHighRdy
        LDR                R1, =OSPrioCur
        LDRB        R0, [R0]
        STRB        R0, [R1]
       
        ;----------------------------------------------------------------------------------               
        ;  OSTCBHighRdy->OSTCBStkPtr;
        ;----------------------------------------------------------------------------------               
        LDR                R0, =OSTCBHighRdy
        LDR                R0, [R0]
        LDR                SP, [R0]

        ;----------------------------------------------------------------------------------       
        ;Restore New task context
        ;----------------------------------------------------------------------------------       
        LDMFD         SP!, {R0}                ;POP CPSR
        MSR         SPSR_cxsf, R0
        LDMFD         SP!, {R0-R12, LR, PC}^       

这是在ARM920T上的任务切换代码的一部分,自己好好读读UCOS的源码就不会这样问了

出0入0汤圆

发表于 2010-3-23 14:40:21 | 显示全部楼层
回复【2楼】Clinging  
;**********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From task level)
;                                           void OSCtxSw(void)
;
; Note(s):            1) Upon entry:
;                        OBCur      points to the OS_TCB of the task to suspend
;                        OBHighRdy  points to the OS_T......
-----------------------------------------------------------------------

不知道你对DSP(2812)的堆栈结构有没有了解?

出0入0汤圆

 楼主| 发表于 2010-3-23 17:16:14 | 显示全部楼层
static void  Task2(void *p_arg)
{
    INT8U err;
    p_arg = p_arg;
       
    while (1)
    {
        if(PORTC&0x08)       
           PORTC &= 0xF7;
        else                       
           PORTC |= 0x08;       
        OSTimeDly(40);
    }
}


  (1).执行 OSTimeDly(40);时,"PC指令寄存器"压入Task2的堆栈中.
     我使用的单片机是AVR公司的ATMEGA128
     CALL 子程序   的汇编指令执行结果如下:
        STACK <---PC+2
        SP    <---SP+2
        PC    <---K

     可以看到,当执行OSTimeDly(40)节拍函数时,将"断点"压入任务TASK2堆栈中



_OSCtxSw::
                PUSH_ALL                            ; Save current task's context
                PUSH_SREG
                PUSH_SP

                LDS     R30,_OSTCBCur               ; Z = OSTCBCur->OSTCBStkPtr
                LDS     R31,_OSTCBCur+1             ;
                ST      Z+,R28                      ; Save Y (R29:R28) pointer
                ST      Z+,R29                      ;

                CALL    _OSTaskSwHook               ; Call user defined task switch hook

                LDS     R16,_OSPrioHighRdy          ; OSPrioCur = OSPrioHighRdy
                STS     _OSPrioCur,R16

                LDS     R30,_OSTCBHighRdy           ; Let Z point to TCB of highest priority task
                LDS     R31,_OSTCBHighRdy+1         ; ready to run
                STS     _OSTCBCur,R30               ; OSTCBCur = OSTCBHighRdy
                STS     _OSTCBCur+1,R31             ;

                LD      R28,Z+                      ; Restore Y pointer
                LD      R29,Z+                      ;

                POP_SP                              ; Restore stack pointer
                POP_SREG                            ; Restore status register
                POP_ALL                             ; Restore all registers

                RET


(2).执行 RET时,  "PC指令寄存器"弹出高优先级任务的断点,然后从高优先级任务的断点处继续执行.
     我使用的单片机是AVR公司的ATMEGA128
     RET   的汇编指令执行结果如下:
        SP    <---SP+2
        PC    <---STACK


  由于目前的硬件一般不提供直接将PC寄存器(指令寄存器)压栈的指令,因此一般用CALL指令模拟压栈PC,用RET或IRET模拟出栈PC.

出0入0汤圆

发表于 2010-6-25 16:37:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-30 10:04:24 | 显示全部楼层
ba_wang_mao大侠,帮忙看看我的程序,我的瑞萨单片机H82218的OSCtxSw程序,在中断返回后就程序飞了。有没什么建议呢?
==========================================

;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                                          All Rights Reserved
;
;                                           H8S Specific code
;                                           (ADVANCED mode)
;
;
; File : OS_CPU_A.SRC
;********************************************************************************************************
        
          .EXPORT _OSStartHighRdy      ; Public functions
          .EXPORT _OSCtxSw
          .EXPORT _OSIntCtxSw
          .EXPORT _OSTickISR

          .IMPORT _OSIntEnter          ; External functions
          .IMPORT _OSIntExit
          .IMPORT _OSTimeTick
          .IMPORT _OSTaskSwHook
         
          .IMPORT _OSTCBCur            ; External variables (uC/OS-II)
          .IMPORT _OSTCBHighRdy
          .IMPORT _OSPrioCur
          .IMPORT _OSPrioHighRdy
          .IMPORT _OSIntNesting
          .IMPORT _OSRunning
         .IMPORT _TickClr
                                            ; the OS tick source

_OSStartHighRdy:
          JSR      @_OSTaskSwHook         ; Execute task switch hook
;
          MOV.B    #1,  R6L              ; Set OSRunning to TRUE
          MOV.B    R6L, @_OSRunning
;
          MOV.L    @_OSTCBHighRdy, ER0    ; SP = OSTCBHighRdy->OSTCBStkPtr
          MOV.L    #_OSTCBCur,ER1
          MOV.L    ER0,  @ER1
          MOV.L    @ER0, ER7
;         
          POP.L    ER6
          POP.L    ER5
          POP.L    ER4
          POP.L    ER3
          POP.L    ER2
          POP.L    ER1
          POP.L    ER0
  
;         
          RTE


_OSCtxSw:        
          PUSH.L   ER0
          PUSH.L   ER1
          PUSH.L   ER2
          PUSH.L   ER3
          PUSH.L   ER4
          PUSH.L   ER5
          PUSH.L   ER6
;
          MOV.L    @_OSTCBCur, ER6        ; Save current task's SP into its TCB
          MOV.L    ER7, @ER6
;         
          JSR      @_OSTaskSwHook         ; Execute task switch hook
;
          MOV.B    @_OSPrioHighRdy, R1L   ; OSPrioCur = OSPrioHighRdy
          MOV.B    R1L, @_OSPrioCur
;         
          MOV.L    @_OSTCBHighRdy, ER6    ; Get new task's SP from its TCB
          MOV.L    ER6,  @_OSTCBCur       ; OSTCBCur = OSTCBHighRdy
          MOV.L    @ER6, ER7
;         
          POP.L    ER6
          POP.L    ER5
          POP.L    ER4
          POP.L    ER3
          POP.L    ER2
          POP.L    ER1
          POP.L    ER0
;         
          RTE                            ; Return to task

_OSIntCtxSw:
          JSR      @_OSTaskSwHook         ; Execute task switch hook
;
          MOV.B    @_OSPrioHighRdy, R1L   ; OSPrioCur = OSPrioHighRdy
          MOV.B    R1L, @_OSPrioCur
;         
          MOV.L    @_OSTCBHighRdy, ER6    ; Get new task's SP from its TCB
          MOV.L    ER6, @_OSTCBCur        ; OSTCBCur = OSTCBHighRdy
          MOV.L    @ER6, ER7
;         
          POP.L    ER6
          POP.L    ER5
          POP.L    ER4
          POP.L    ER3
          POP.L    ER2
          POP.L    ER1
          POP.L    ER0
;         
          RTE

                  
_OSTickISR:
          PUSH.L   ER0
          PUSH.L   ER1
          PUSH.L   ER2
          PUSH.L   ER3
          PUSH.L   ER4
          PUSH.L   ER5
          PUSH.L   ER6

          MOV.B    @_OSIntNesting, R6L    ; tell uC/OS-II we're in an ISR
          INC.B    R6L
          MOV.B    R6L, @_OSIntNesting

          CMP.B    #1,R6L                ; if (OSNesting == 1)
          BNE      _OSTickISR1
          MOV.L    @_OSTCBCur, ER6        ;     Save current task's SP into its TCB
          MOV.L    ER7, @ER6
_OSTickISR1:

          JSR      @_TickClr              ; Notify uC/OS-II about Tick
          JSR      @_OSTimeTick
          JSR      @_OSIntExit            ; Notify uC/OS-II about end of ISR

          POP.L    ER6
          POP.L    ER5
          POP.L    ER4
          POP.L    ER3
          POP.L    ER2
          POP.L    ER1
          POP.L    ER0   

          RTE

        .END
======================================================================

出0入0汤圆

发表于 2011-2-18 17:30:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-11-10 18:57:04 | 显示全部楼层
mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-15 18:10

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表