[讨论] (求解答)中断函数特别是Tmr_TickISR_Handler 中断退出时必须加OSIntExit ()函数吗?

lalahu   2011-5-31 09:07 楼主

中断函数特别是Tmr_TickISR_Handler 中断退出时必须加OSIntExit ()函数吗?

 

但是我看到许多别人写的中断根本就没加,也就是中断后不做任何调度。

void Tmr_TickISR_Handler (void)

 {

    OSTimeTick(); /* Call uC/OS-II's OSTimeTick(). */

    T0CLRI = 0xFF; /* Clear timer #0 interrupt. */

}

 

 

那么就两个延时的任务而言,一个延时10ms(高优先级),一个延时50ms执行一次(低优先级),

高优先级执行1ms后,挂起本身后调度一下,准备延时10ms,调度引起低优先级任务执行,低优先级

执行2ms后,调度一下,准备延时50ms,之后我觉得如果时钟中断里不含调度的话任务都被挂起了,任务

从此就一直idle了。

 

问题1:我理解是否错误?

问题2:如果理解正确,是否有别的方法使任务调度回来(除了中断调度)。

 

回复评论 (4)

原来他在os_cpu_a.asm(IAR ARM7)

经过调试终于发现问题了。

 

OS_CPU_ARM_EXCEPT_HANDLER
    MRS     R1, SPSR                                            ; Save CPSR (i.e. exception's SPSR)

                                                                ; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION
                                                                ;   SPSR.Mode = FIQ, IRQ, SVC, ABT, UND : Other exception
                                                                ;   SPSR.Mode = SYS                     : Task
                                                                ;   SPSR.Mode = USR                     : *unsupported state*
    AND     R2, R1, #OS_CPU_ARM_MODE_MASK
    CMP     R2,     #OS_CPU_ARM_MODE_SYS//答案在这个地方,之前是系统模式,不跳转,顺序执行。

如果不是系统模式,就是进行嵌套处理。


  BNE     OS_CPU_ARM_EXCEPT_HANDLER_BreakExcept


;********************************************************************************************************
;                                  EXCEPTION HANDLER: TASK INTERRUPTED
;********************************************************************************************************

OS_CPU_ARM_EXCEPT_HANDLER_BreakTask
    MRS     R2, CPSR                                            ; Save exception's CPSR
    MOV     R4, SP                                              ; Save exception's stack pointer

                                                                ; Change to SYS mode & disable interruptions
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)

                                                                ; SAVE TASK'S CONTEXT ONTO TASK'S STACK
    STMFD   SP!, {R3}                                           ;   Push task's PC
    STMFD   SP!, {LR}                                           ;   Push task's LR
    STMFD   SP!, {R5-R12}                                       ;   Push task's R12-R5
    LDMFD   R4!, {R5-R9}                                        ;   Move task's R4-R0 from exception stack to task's stack
    STMFD   SP!, {R5-R9}

    TST     R3, #1                                              ;   See if called from Thumb mode
    ORRNE   R1, R1, #OS_CPU_ARM_CONTROL_THUMB                   ;   If yes, Set the T-bit
    STMFD   SP!, {R1}                                           ;   Push task's CPSR (i.e. exception SPSR)

                                                                ; if (OSRunning == 1)
    LDR     R1, ?OS_Running
    LDRB    R1, [R1]
    CMP     R1, #1
    BNE     OS_CPU_ARM_EXCEPT_HANDLER_BreakTask_1

                                                                ; HANDLE NESTING COUNTER
    LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting++;
    LDRB    R4, [R3]
    ADD     R4, R4, #1
    STRB    R4, [R3]

    LDR     R3, ?OS_TCBCur                                      ;   OSTCBCur->OSTCBStkPtr = SP;
    LDR     R4, [R3]
    STR     SP, [R4]

OS_CPU_ARM_EXCEPT_HANDLER_BreakTask_1
    MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE

    LDR     R1, ?OS_EXCEPT_HANDLER                              ; OS_EXCEPT_HANDLER();
    MOV     LR, PC
    BX      R1

                                                                ; Adjust exception stack pointer. This is needed because
                                                                ; exception stack is not used when restoring task context.
    ADD     SP, SP, #(14*4)

                                                                ; Change to SYS mode & disable interruptions.
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)

                                                                ; Call OSIntExit(). This call MAY never return
                                                                ;  if a ready task with higher priority than
                                                                ;  the interrupted one is found.
    LDR     R0, ?OS_IntExit
    MOV     LR, PC
    BX      R0

                                                                ; RESTORE NEW TASK'S CONTEXT
    LDMFD   SP!, {R0}                                           ;    Pop new task's CPSR
    MSR     CPSR_cxsf, R0

    LDMFD   SP!, {R0-R12, LR, PC}                               ;    Pop new task's context


;********************************************************************************************************
;                               EXCEPTION HANDLER: EXCEPTION INTERRUPTED
;********************************************************************************************************

OS_CPU_ARM_EXCEPT_HANDLER_BreakExcept
    MRS     R2, CPSR                                            ; Save exception's CPSR

                                                                ; Change to SYS mode & disable interruptions
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)

                                                                ; HANDLE NESTING COUNTER
    LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting++;
    LDRB    R4, [R3]
    ADD     R4, R4, #1
    STRB    R4, [R3]

    MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE

    LDR     R3, ?OS_EXCEPT_HANDLER                              ; OS_EXCEPT_HANDLER();
    MOV     LR, PC
    BX      R3

                                                                ; Change to SYS mode & disable interruptions
    MSR     CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SYS)

                                                                ; HANDLE NESTING COUNTER
    LDR     R3, ?OS_IntNesting                                  ;   OSIntNesting--;
    LDRB    R4, [R3]
    SUB     R4, R4, #1
    STRB    R4, [R3]

    MSR     CPSR_cxsf, R2                                       ; RESTORE INTERRUPTED MODE

    LDMFD   SP!, {R0-R12, PC}^                                  ; Pull working registers and return from exception.

[ 本帖最后由 lalahu 于 2011-6-3 12:45 编辑 ]
点赞  2011-6-3 12:28

这说明,在这段代码中,时钟中断里面和任何的中断退出时都会产生调度。

 

有的移植文件没有这样写。可以把OSINTEXIT放在c中断文件里面,灵活性强一点。

点赞  2011-6-3 12:44
帮楼主顶顶
点赞  2011-7-7 09:03
如果不调用OSIntExit (),那么操作系统就不是实时操作系统了
点赞  2011-10-8 23:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复