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

Inline asm error C-197 when disabling interrupt...

Hello,
I have take a piece of source at http://www.arm.com and tried to compile it using the CARM compiler. The code is shown below:

/* NewState=1 will enable IRQ, NewState=0 will disable IRQ */
/* ARM core must be in a privileged mode, e.g. supervisor  */

void ChangeIRQ(unsigned int NewState)
{
  int my_cpsr;

  __asm
    {
     MRS my_cpsr, CPSR
     /* get current program status */

     ORR my_cpsr, my_cpsr,#0x80
     /* set IRQ disable bit flag */

     BIC my_cpsr, my_cpsr, NewState, LSL #7
     /* reset IRQ bit with new value */

     MSR CPSR_c, my_cpsr
     /* store updated program status */
    }
}

void main(void)
{
__asm{MSR CPSR_c, #0x13}
//Go into Supervisor Mode

ChangeIRQ(0);

	while(1)
	{
	}

}
.

I get the asm error at line "MSR CPSR_c, my_cpsr". How is that?

Regards,
Kasper Andersen

Parents
  • The following code should do your job. Please note that the function(s) containing inline-assembly must use the proper mode of operation - either ARM or THUMB mode. If none is specified, CA defaults to thumb which causes ARM-instructions to be illegal . You can specify the mode by using #pragma ARM/THUMB or by explicitely using __arm/__thumb in the function definition as shown in the example (commented out). The LDAV instruction is a pseudo instruction which loads the value of a parameter or an automatic variable. 'my_cpsr' has been replaced by register R0.

    #pragma ARM    // use ARM mode
    void ChangeIRQ (unsigned int NewState) /*__arm*/  {
    //int my_cpsr;               //
    
      __asm  {
         AND    R0,R0,#0         // clear R0 (used for 'my_cpsr')
         MRS    R0,CPSR          // my_cpsr, CPSR
         ORR    R0,R0,#0x80;     // my_cpsr, my_cpsr,#0x80
    
         LDAV   R1,R10,NewState  // load parameter-value 'NewState' into R1
         BIC    R0,R0,R1,LSL #7  // my_cpsr, my_cpsr, NewState, LSL #7
         MSR    CPSR_c, R0       // CPSR_c,my_cpsr
      }
    }
    
    void main(void) /*__arm*/  {
      __asm  {MSR CPSR_c, #0x13}    // Go into Supervisor Mode
      ChangeIRQ (0);
      while (1)  {
      }
    }
    

    Regards,
    Peter

Reply
  • The following code should do your job. Please note that the function(s) containing inline-assembly must use the proper mode of operation - either ARM or THUMB mode. If none is specified, CA defaults to thumb which causes ARM-instructions to be illegal . You can specify the mode by using #pragma ARM/THUMB or by explicitely using __arm/__thumb in the function definition as shown in the example (commented out). The LDAV instruction is a pseudo instruction which loads the value of a parameter or an automatic variable. 'my_cpsr' has been replaced by register R0.

    #pragma ARM    // use ARM mode
    void ChangeIRQ (unsigned int NewState) /*__arm*/  {
    //int my_cpsr;               //
    
      __asm  {
         AND    R0,R0,#0         // clear R0 (used for 'my_cpsr')
         MRS    R0,CPSR          // my_cpsr, CPSR
         ORR    R0,R0,#0x80;     // my_cpsr, my_cpsr,#0x80
    
         LDAV   R1,R10,NewState  // load parameter-value 'NewState' into R1
         BIC    R0,R0,R1,LSL #7  // my_cpsr, my_cpsr, NewState, LSL #7
         MSR    CPSR_c, R0       // CPSR_c,my_cpsr
      }
    }
    
    void main(void) /*__arm*/  {
      __asm  {MSR CPSR_c, #0x13}    // Go into Supervisor Mode
      ChangeIRQ (0);
      while (1)  {
      }
    }
    

    Regards,
    Peter

Children