TI中文支持网
TI专业的中文技术问题搜集分享网站

UCOSII 的问题

在UCOSII 系统中,产生系统节拍的定时器中断函数为什么用C语言编写的不行啊,改为汇编就可以了。这个有什么区别呢?

#pragma vector = WDT_VECTOR

__interrupt void WDT_ISR(void)

{

  OSTimeTick();

}

这个在c中的中断不行,但是我设置断点调试,他也能进来的啊。但是就进步了任务函数。

Young Hu:

中断服务程序用C语言和汇编没有什么本质上的区别。你可以对照一下C的ISR生产的汇编和你写的汇编有什么不一样的地方。

Peter_Zheng:

回复 Young Hu:

我现在理解在430上编写uCOS的中断服务程序,只能这样

————————————-

汇编中断程序:

……… 用汇编写系统代码

………

调用C函数写的用户代码

……….

………..用汇编写系统代码

中断结束

————————————

而不能这样:

————————————

C中断程序:

……… 调用汇编程序编写的系统代码

………

用C写的用户代码

……….

…………调用汇编程序编写的系统代码

中断结束

————————————

因为,如果用C写中断程序,那么在进如中断的第一句,编译器已经保存了部分积存器,但我们不知道被保存的是哪些积存器,这样在中断结束要进行任务切换时就不知道把哪些积存器出栈,任务切换会失败。

还是需要把ucos的移植那本书再好好看一下,大家探讨一下

anger0925:

回复 Peter_Zheng:

我下了一个别人移植好的,但他产生时钟节拍是看门狗定时器,我想修改为其他定时器来做时钟节拍。但是修改后中断能产生,但进步而来时钟节拍函数。

这个是看门狗定时器产生的:

WDT_ISR                                     ; wd timer ISR

           PUSHALL                         ; push all registers            

           bic.b    #0x01, SFRIE1_L        ; bic.b    #0x01, SFRIE1             ; disable wd timer interrupt

           //是否有中断嵌套,因为单独使用了系统堆栈

           cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0)  

           jne      WDT_ISR_1    ;不等于时跳转

           mov.w    &OSTCBCur, R13         ;     save task stack

           mov.w    SP, 0(R13)

           mov.w    &OSISRStkPtr, SP       ;     load interrupt stack            

WDT_ISR_1

           inc.b    &OSIntNesting          ; increase OSIntNesting

           bis.b    #0x01, SFRIE1_L          ;bis.b    #0x01, SFRIE1             ; enable wd timer interrupt

           EINT                            ; enable general interrupt to allow for interrupt nesting

           calla    #OSTimeTick            ; call ticks routine            

           DINT                            ; IMPORTANT: disable general interrupt BEFORE calling OSIntExit()

           calla    #OSIntExit             ;

           //是否有中断嵌套,因为单独使用了系统堆栈

           cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0)

           jne      WDT_ISR_2

           mov.w    &OSTCBHighRdy, R13     ;     restore task stack SP

           mov.w    @R13, SP

WDT_ISR_2

           POPALL                          ; pop all registers

           reti                            ; return from interrupt

我修改的定时器A,后就进不了:

TIMER1_ISR                                     ; wd timer ISR

           PUSHALL                         ; push all registers            

           bic.w    #0x0002, TA1CTL        ; bic.b    #0x01, SFRIE1             ; disable wd timer interrupt

           //是否有中断嵌套,因为单独使用了系统堆栈

           cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0)  

           jne      TIMER1_ISR_1    ;不等于时跳转

           mov.w    &OSTCBCur, R13         ;     save task stack

           mov.w    SP, 0(R13)

           mov.w    &OSISRStkPtr, SP       ;     load interrupt stack            

TIMER1_ISR_1

           inc.b    &OSIntNesting          ; increase OSIntNesting

           bis.w   #0x0002, TA1CTL           ;bis.b    #0x01, SFRIE1             ; enable wd timer interrupt

           EINT                            ; enable general interrupt to allow for interrupt nesting

           calla   #OSTimeTick            ; call ticks routine            

           DINT                            ; IMPORTANT: disable general interrupt BEFORE calling OSIntExit()

           calla    #OSIntExit             ;

           //是否有中断嵌套,因为单独使用了系统堆栈

           cmp.b    #0, &OSIntNesting      ; if (OSIntNesting == 0)

           jne      TIMER2_ISR_2

           mov.w    &OSTCBHighRdy, R13     ;     restore task stack SP

           mov.w    @R13, SP

TIMER2_ISR_2

           POPALL                          ; pop all registers

           reti                            ; return from interrupt

anger0925:

回复 anger0925:

仿真时进到到这来但就是跳不进OSTimeTick这个函数

Peter_Zheng:

回复 anger0925:

;********************************************************************************************************

;                                              TICK ISR

;

; Description: This ISR handles tick interrupts.  This ISR uses the Watchdog timer as the tick source.

;

; Notes      : 1) The following C pseudo-code describes the operations being performed in the code below.

;

;                 Save all the CPU registers

;                 if (OSIntNesting == 0) {

;                     OSTCBCur->OSTCBStkPtr = SP;

;                     SP                    = OSISRStkPtr;  /* Use the ISR stack from now on           */

;                 }

;                 OSIntNesting++;

;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */

;                 Clear the interrupt source;

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

;                 DISABLE general interrupts;               /* Must DI before calling OSIntExit()      */

;                 OSIntExit();

;                 if (OSIntNesting == 0) {

;                     SP = OSTCBHighRdy->OSTCBStkPtr;       /* Restore the current task's stack        */

;                 }

;                 Restore the CPU registers

;                 Return from interrupt.

;

;              2) ALL ISRs should be written like this!

;

;              3) You MUST disable general interrupts BEFORE you call OSIntExit() because an interrupt

;                 COULD occur just as OSIntExit() returns and thus, the new ISR would save the SP of

;                 the ISR stack and NOT the SP of the task stack.  This of course will most likely cause

;                 the code to crash.  By disabling interrupts BEFORE OSIntExit(), interrupts would be

;                 disabled when OSIntExit() would return.  This assumes that you are using OS_CRITICAL_METHOD

;                 #3 (which is the prefered method).

;

;              4) If you DON'T use a separate ISR stack then you don't need to disable general interrupts

;                 just before calling OSIntExit().  The pseudo-code for an ISR would thus look like this:

;

;                 Save all the CPU registers

;                 if (OSIntNesting == 0) {

;                     OSTCBCur->OSTCBStkPtr = SP;

;                 }

;                 OSIntNesting++;

;                 Enable interrupt nesting;                 /* Allow nesting of interrupts (if needed) */

;                 Clear the interrupt source;

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

;                 OSIntExit();

;                 Restore the CPU registers

;                 Return from interrupt.

;********************************************************************************************************

WDT_ISR                                 ; wd timer ISR

   PUSHM.A     #12, R15

   BIC.W       #0x01, SFRIE1           ; disable wd timer interrupt

   CMP.B       #0, &OSIntNesting       ; if (OSIntNesting == 0)

   JNE         WDT_ISR_1

   MOVX.A      &OSTCBCur, R13          ;     save task stack

   MOVX.A      SP, 0(R13)

   MOVX.A      &OSISRStkPtr, SP        ;     load interrupt stack

WDT_ISR_1

   INC.B       &OSIntNesting           ; increase OSIntNesting

   BIS.W       #0x01, SFRIE1           ; enable wd timer interrupt

   EINT                                ; enable general interrupt to allow for interrupt nesting

   CALLA       #OSTimeTick             ; call ticks routine

   DINT                                ; IMPORTANT: disable general interrupt BEFORE calling OSIntExit()

   CALLA       #OSIntExit

   CMP.B       #0, &OSIntNesting       ; if (OSIntNesting == 0)

   JNE         WDT_ISR_2

   MOVX.A      &OSTCBHighRdy, R13      ;     restore task stack SP

   MOVX.A      @R13, SP

WDT_ISR_2

   POPM.A      #12, R15

   RETI                                ; return from interrupt

;********************************************************************************************************

;                                 WD TIMER INTERRUPT VECTOR ENTRY

;

; Interrupt vectors

;********************************************************************************************************

   COMMON      INTVEC

   ORG         WDT_VECTOR

WDT_VEC   DW    WDT_ISR                 ; interrupt vector. Watchdog/Timer, Timer mode

   END

这也是一个WDT产生系统节拍的,我觉得能够执行到    CALLA       #OSTimeTick             ; call ticks routine这条语句,就能够跳转,calla就是把20位PC指针压栈并更改PC指针以实现函数调用功能

anger0925:

回复 Peter_Zheng:

我加了这一段的,     我仿真是 CALLA       #OSTimeTick 到这里了,当是没有进入OSTimeTick ()函数

     COMMON  INTVEC                  ; 定义公共段

           ORG     TIMER1_A1_VECTOR              ; 设置特定的定位指针

TIMER1_VEC     DW      TIMER1_ISR                 ; interrupt vector. Watchdog/Timer, Timer mode

anger0925:

回复 anger0925:

仿真结果就是来这里一次Interrupt这里加1;正常的好像这里一直是1,仿真下来。不知道为什么都到这里了,进不去这个时钟节拍函数

Triton Zhang:

回复 anger0925:

1. 有查过堆栈没?

2. 仿真到   CALLA       #OSTimeTick             ; call ticks routine

  这句话后,继续单步执行,情况是如何的,是程序跳转到未知位置还是其他情况?

Triton Zhang:

回复 anger0925:

使用WDT定时器不行的原因是因为仿真环境中不能对WDT的定时器进行仿真

赞(0)
未经允许不得转载:TI中文支持网 » UCOSII 的问题
分享到: 更多 (0)