This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28x+FPU context switch issue?

Hello,

I have a problem with some FPU code running inside an ISR on F28335. I have one interrupt that can interrupt itself and ISR code that contains floating-point register comparisons. The problem is that sometimes comparisons dont work properly. If I disable interrupts (SETC INTM / CLRC INTM) around the code in question, the problem seems to disappear. I'm pretty confident my context storing and restoring is good, but I provide code here. Interrupts are globally disabled during context storing/restoring.

Context save:
    ASP
    PUSH    AR1H:AR0H
    PUSH    XAR2
    PUSH    XAR3
    PUSH    XAR4
    PUSH    XAR5
    PUSH    XAR6
    PUSH    XAR7
    PUSH      XT
    MOV32   *SP++, R0H
    MOV32   *SP++, R1H
    MOV32   *SP++, R2H
    MOV32   *SP++, R3H
    MOV32   *SP++, R4H
    MOV32   *SP++, R5H
    MOV32   *SP++, R6H
    MOV32   *SP++, R7H
    MOV32   *SP++, STF
    MOV32   *SP++, STF
    PUSH    RB

Context restore:
    POP     RB
    MOV32   STF, *--SP
    MOV32   STF, *--SP
    MOV32   R7H, *--SP
    MOV32   R6H, *--SP
    MOV32   R5H, *--SP
    MOV32   R4H, *--SP
    MOV32   R3H, *--SP
    MOV32   R2H, *--SP
    MOV32   R1H, *--SP
    MOV32   R0H, *--SP
    POP          XT
    POP     XAR7                                   
    POP     XAR6
    POP     XAR5
    POP     XAR4
    POP     XAR3
    POP     XAR2
    POP     AR1H:AR0H
    NASP

The problematic code (part of the ISR) is:
    MOVF32  R0H, #-6328.0
    MOVF32  R1H, #16384.0
    CMPF32  R1H, R0H
    MOVST0  NF
    BF      $1, LT      
    MOV     @OUT, #0
    BF      $2, UNC
$1
    MOV     @OUT, #-1
$2   

The line "MOV @OUT, #-1" should never be reached however, if I put a brakepoint there, it catches the violation and contents of the involved registers at the brakepoint is:

STF      0x00000214    pointer      hex        NotEdited
R0H      -6328.0        pointer      float      NotEdited
R1H      16384.0        pointer      float      NotEdited

ST0      00AB

So, although registers R0H and R1H are loaded properly and
    R1H - R0H = 16384.0 - (-6328.0) = 22712 > 0
N flags in STF and ST0 are set.                                                                                

If I than set the PC to line "CMPF32 R1H, R0H" and single-step the code, all works fine. My only guess is that interrupt happens between "CMPF32 R1H, R0H" and "MOVST0 NF" lines and corrupts STF. But how is that possible if STF is stored/restored with the rest of the context? Whether this problem happens or not depends on the amount of code on the ISR and interrupt period. This looks to me as if it is the question of where exactly the ISR interrupts itself.

Please help, I'm running out of ideas.

Kind regards,
Josip

  • Josip,

    Are both the ISR's declared in assembly? The FPU has shadowed registers that can be used to context save for the fastest ISR.

    For example let's say in an application you have two ISRs,  Inv_ISR and DPL_ISR, both of which use the FPU. 

    Now you can specify the priority of the interrupts by

    #pragma INTERRUPT (DPL_ISR, HPI)
    #pragma INTERRUPT (Inv_ISR, LPI)

    where the (DPL_ISR, HPI) is a hint to the compiler that use shadowed register for this ISR, are you using this???

    if it is legacy code that you may have in your project, you may want to add the following instruction to your code

            SPM       0                          ; set C28 mode
            CLRC      AMODE       
            CLRC      PAGE0,OVM
         

  • Manish,

    there is only one ISR which is interrupting itself and yes, it is all in assembly. The amount of work done on the ISR is variable. I'm aware of the shadow FPU register but I'm not using them because of the interrupt nesting. Is there any reason manual storing/restoring of FPU registers to/form stack should not work?

    It is a project written fully in assembly so all necessary initializations are performed. Thanks for the hint though.

    Regards,

    Josip

  • Josip,

    An ISR that is interrupting itself?

    How does it interrupt itself? is the processing so long that it is not able to finish?

    How many nesting are possible where ISR is interrupting itself?

    Regards

    Manish Bhardwaj

  • Manish,

    ISR has three levels of processing: short, medium and long. Most of the times it does only short processing, but every now and then it does medium or long task. During these longer executions, the ISR can be interrupted by itself doing the short task. So there is only one level of nesting.

    Josip

  • Hi Josip,

    Did you check how much stack do you use? The way you describe your system it seems that you might have stack overflow problems.

    Regards, Mitja

  • Mitja,

    stack pointer is checked on ISR start (after context store) and no overflows are detected. Unfortunately :(

    Regards, Josip

  • Dear all,

    this is a great problem for me so I'd really appreciate if anyone had some suggestions.

    Josip

  • Josip,

    You said the problematic piece of code is the where the compare is happening, if you keep the code inside DINT and EINT (only the piece of code that you say is the problem) does the issue go away?

  • Manish,

    yes, if I disable interrupts around the problematic code, the error doesn't occur.

    Regards, Josip

  • Josip,

    Few things to try are use only positive numbers for   the compare operation, does the problem still occur?

        MOVF32  R0H, #6328.0
        MOVF32  R1H, #16384.0
        CMPF32  R1H, R0H
        DINT

        MOVST0  NF
        BF      $1, LT      
        MOV     @OUT, #0
        BF      $2, UNC
    $1
        MOV     @OUT, #-1
    $2  

       EINT

    ---------------------------------

    Secondly try to store the ZF on the MOVST0 instruction

    Additionally i would try to disable interrupt close to where the problem is happening,

        MOVF32  R0H, #-6328.0
        MOVF32  R1H, #16384.0

        DINT
        CMPF32  R1H, R0H
        MOVST0  NF
        BF      $1, LT      
        MOV     @OUT, #0
        BF      $2, UNC
    $1
        MOV     @OUT, #-1
    $2  

       EINT

    --------------------------------------------

        MOVF32  R0H, #-6328.0
        MOVF32  R1H, #16384.0
        CMPF32  R1H, R0H
        DINT

        MOVST0  NF
        BF      $1, LT      
        MOV     @OUT, #0
        BF      $2, UNC
    $1
        MOV     @OUT, #-1
    $2  

       EINT

  • Manish,

    thank you for the suggestions. I have tried them and the results are as follows:

    1. Yes, problem occurs for positive numbers also.
    2. Storing ZF flag on MOVST0 makes no difference. This was expected because BF $1, LT only checks N flag, and I already confirmed that it is corrupted in both STF and ST0 when the error happens.
    3. Disabling interrupts close to where the problem is happening;
    1. DINT before CMPF32 – problem doesn’t occur,
    2. DINT between CMPF32 and MOVST0 – problem does occur. 

    It seams to me that these results confirm my suspicions about context issues?

    Regards, Josip

  • Josip,

    This might be a kick in the dark but anyway.

    Does your system keep the stack pointer always pointing to even address? I seem to recall that context save/restore differs slightly if your system allows SP to point to odd address.

    Regards, Mitja

  • Mitja,

    this issue occurred me too, but I checked it and stack pointer is always pointing to an even address.

    Regards, Josip

  • Thinking on this....

    If you examine STF on the stack is it correct? (both copies :))

  • Found it!

    Instruction MOV32 RnH, *--SP modifies STF flags so I corrupted it myself during context restoring. I rearranged storing/restoring so that STF is restored after last MOV32 RnH, *--SP instruction.

    Thank you all for help,

    Josip

  • Great!! Looks like we have some documentation to do on our side.  I regret this caused you headaches.

  • Nice catch,

    I just compiled the FPU cope and it does generate the correct sequence..

    008000:   761B        ASP          
    008001:   FFF0        PUSH         RB
    008002:   0005        PUSH         AR1H:AR0H
    008003:   ABBD        MOVL         *SP++, XT
    008004:   A8BD        MOVL         *SP++, XAR4
    008005:   A0BD        MOVL         *SP++, XAR5
    008006:   C2BD        MOVL         *SP++, XAR6
    008007:   C3BD        MOVL         *SP++, XAR7
    008008:   E20000BD    MOV32        *SP++, STF
    00800a:   E20300BD    MOV32        *SP++, R0H
    00800c:   E20301BD    MOV32        *SP++, R1H
    00800e:   E20302BD    MOV32        *SP++, R2H
    008010:   E20303BD    MOV32        *SP++, R3H
    008012:   E20304BD    MOV32        *SP++, R4H
    008014:   E20305BD    MOV32        *SP++, R5H
    008016:   E20306BD    MOV32        *SP++, R6H
    008018:   E20307BD    MOV32        *SP++, R7H
    00801a:   E6300600    SETFLG       RNDF32=1,RNDF64=1
    00801c:   FE02        ADDB         SP, #2
    00801d:   FF69        SPM          #0
    00801e:   2942        CLRC         OVM|PAGE0
    00801f:   5616        CLRC         AMODE

    and restore

    FE82        SUBB         SP, #2
    00845a:   E2AF07BE    MOV32        R7H, *--SP, UNCF
    00845c:   E2AF06BE    MOV32        R6H, *--SP, UNCF
    00845e:   E2AF05BE    MOV32        R5H, *--SP, UNCF
    008460:   E2AF04BE    MOV32        R4H, *--SP, UNCF
    008462:   E2AF03BE    MOV32        R3H, *--SP, UNCF
    008464:   E2AF02BE    MOV32        R2H, *--SP, UNCF
    008466:   E2AF01BE    MOV32        R1H, *--SP, UNCF
    008468:   E2AF00BE    MOV32        R0H, *--SP, UNCF
    00846a:   E28000BE    MOV32        STF, *--SP
    00846c:   C5BE        MOVL         XAR7, *--SP
    00846d:   C4BE        MOVL         XAR6, *--SP
    00846e:   83BE        MOVL         XAR5, *--SP
    00846f:   8ABE        MOVL         XAR4, *--SP
    008470:   87BE        MOVL         XT, *--SP
    008471:   0003        POP          AR1H:AR0H
    008472:   FFF1        POP          RB
    008473:   7617        NASP         
    008474:   7602        IRET        

  • Hello Manish,

    I couldn't understand why XAR2 and XAR3 are not part of the context save/restore?

    Thank you for clarifying!

    Regards

    Kristian