This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ARM 7 Assembly and C coding mix up

Hi

I am new TO ARM7 And KEIL uVISION4 IDE.

I am using AT91FR40162S ATMEL COntroller.

When i created a project using KEIL IDE and selected AT91FR40162S ATMEL COntroller from the device list. Automatically startup.s file is added to the project.

In startup.s file Interrupts are Enabled and Disabled by following assembly code:

To Disable the interrupts

I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled

; Enter Undefined Instruction Mode and set its Stack Pointer

MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
so interrupts are disabled here as corresponding bits in CPSR are set.

To Enable the interrupts

; Enter User Mode and set its Stack Pointer MSR CPSR_c, #Mode_USR

So interrupts are enabled

then after all the settings in startup.s it will jump to main.c file

QUESTION:

1. I want to enable and disable the interrupts in my main.c file. So How will i be able to access the CPSR register in my c coding.

  • The use of inline and embedded assembler is somewhat restricted concerning the use of special registers like CPSR and SP. I recommend the use of plain assembler. Example for file intendis.s:

      EXPORT DisableInterrupts
      EXPORT EnableInterrupts
    
            AREA    ||.text||, CODE, READONLY, ALIGN=3
            ARM
      PRESERVE8
    
    DisableInterrupts PROC
          STMDB SP!, {R0}           ; Push R0
          MRS   R0, CPSR            ; Get CPSR.
          ORR   R0, R0, #0xC0       ; Disable IRQ, FIQ.
          MSR   CPSR_cxsf, R0       ; Write back modified value.
          LDMIA SP!, {R0}           ; Pop R0
          BX    LR                  ; return
          ENDP
    
    EnableInterrupts PROC
          STMDB SP!, {R0-R1}        ; Push R0,R1
          MRS   R0, CPSR            ; Get CPSR.
          AND   R1, R0, #0x0000001f ; R1 = R0 & 0x1f (mode bits)
          CMP   R1, #0x00000012     ; Test for IRQ mode
          BICNE   R0, R0, #0x80     ; Enable IRQ, but not in IRQ-Mode (no nesting)
          MSR   CPSR_cxsf, R0       ; Write back modified value.
          LDMIA SP!, {R0-R1}        ; Pop R0,R1
          BX    LR                  ; return
          ENDP
    
    
          END                       ; End of file
    
    

    Of cause you need a header file intendis.h then:

    #ifndef INTENDIS_H
    #define INTENDIS_H
    
    // this pair of functions has the following characteristics:
    // - disables all ints
    // - enables only IRQ, but not during interrupt service
    void DisableInterrupts(void);
    void EnableInterrupts(void);
    
    #endif /* INTENDIS_H */
    

    Hope that helps.

    Martin

  • I agree with the statement about inline assembler, but in which way is embedded assembler restricted?

    But to answer the original question:
    > I want to enable and disable the interrupts in my main.c file. So How will i be able
    > to access the CPSR register in my c coding.

    Two ways (both require running in privileged mode, of course):

    1. Use compiler intrinsics __disable_irq()/__disable_fiq() and __enable_irq()/__enable_fiq()
    2. Use named register variables (see manual)

    Hope this helps
    --
    Marcus
    http://www.doulos.com/arm/

  • Thanx a Lot Martin

    I got the idea from ur code. But i need to be in supervisor mode to alter the CPSR register.

    When i entered to the main function i was in USR mode so was not able to alter the CPSR register.

    I want to know if i am in USR mode in my application main.c then if i want to change the CPSR register i need to change the MODE to SUPERVISOR mode.

    So To alter CPSR bits How to change from USR mode to SUPERVISOR mode.

    Thanx a lot in advance

  • Thanx a lot Marcus

    From ur help also i got a clear idea. it works fine if i am in privileged mode.

    My question is If I am in not privileged mode, How to change to privileged mode.

    If i am in USR mode i can not alter CPSR bits so can not change SUPERVISOR mode from USR mode .

  • Thanx a lot Marcus and John also for responding so quickly

    TO Marcus -

    From ur help also i got a clear idea. it works fine if my code is running in privileged mode.

    My question is If my code is not running in non privileged mode, How to change to privileged mode?

    If my code is running in USR mode i can not alter CPSR bits so can not change MODE from USR to SUPERVISOR.

    So how to change the mode from USR to SUPERVISOR.

    Thanx In Advance

  • > So how to change the mode from USR to SUPERVISOR.

    Have a look at the SVC instruction.

    --
    Marcus