How to create inline assembly functions in C?

417 Views Asked by At

I am using a MSP 432 and have to create an assembly functions in C. I tried creating the functions using __asm void PendSV_Handler{}. But that does not work and says Expected an Identifier.

Also, I am trying to run this assembler command cpsid i but it says CPSID is undefined but CPSIE i works. I am a bit confused at this point. I am fairly new to this and I am still learning.

Below is the code I am trying to make assembly. I try making the function assembly by doing __asm void PendSV_handler.

I was not sure if it would be easier to just create a asm. file with these instructions.

OSThread *volatile OS_curr;
OSThread *volatile OS_next;

void PendSV_Handler(void){


__asm__("cpsid      i"

//if(OS_curr != (OSThread *)0)
        "ldr        r0, =OS_curr"
        "ldr        r0, [r0]"
        "cbz        r0, PendSV_restore");

// Push r4  - r11
__asm__("PUSH {r4-r11}"

        "ldr        r1, =OS_curr"
        "ldr        r1, [r1]"

// OS_curr -> sp = sp;
        "str         sp, [r1]");

PendSV_restore

// sp=OS_next -> sp;
        __asm__("ldr r0, =OS_next;"
                "ldr        r0, [r0]"
                "ldr        r0, [r0]"
                "str        sp, [r13]");

// OS_curr = OS_next;
        __asm__("ldr        r0, =OS_next"
                "ldr        r1, [pc, 0xc]"
                "ldr        r0, =OS_curr"
                "str        r0, [r1]"

//Pop  r4-r11
                "POP        {r4-r11}"

//            __enable_interrupts();
                "cpsie      i"

//return to next thread
                "bx         r14");

}
2

There are 2 best solutions below

2
Clifford On

Inline assembler syntax is not redefined in the C programming language, and its support and syntax is compiler specific. In GCC:

void PendSV_Handler(void) 
{
    __asm__("cpsid      i");

//if(OS_curr != (OSThread *)0)
    __asm__("ldr        r0, =OS_curr");
    __asm__("ldr        r0, [r0]");
    __asm__("cbz        r0, PendSV_restore");

// Push r4  - r11
    __asm__("PUSH {r4-r11}");

    __asm__("ldr        r1, =OS_curr");
    __asm__("ldr        r1, [r1]");

// OS_curr -> sp = sp;
    __asm__("str         sp, [r1]");

PendSV_restore:

// sp=OS_next -> sp;
    __asm__("ldr r0, =OS_next;");
    __asm__("ldr        r0, [r0]");
    __asm__("ldr        r0, [r0]");
    __asm__("str        sp, [r13]");

// OS_curr = OS_next;
    __asm__("ldr        r0, =OS_next");
    __asm__("ldr        r1, [pc, 0xc]");
    __asm__("ldr        r0, =OS_curr");
    __asm__("str        r0, [r1]");

//Pop  r4-r11
    __asm__("POP        {r4-r11}");

//            __enable_interrupts();
    __asm__("cpsie      i");

//return to next thread
    __asm__("bx         r14");
}
0
schwemmdx On

Referencing

Inline assembler syntax is not redefined in the C programming language

I did in the past for a university project

inline void function(param1,param2)
{
   asm volatile ("param1");
   asm volatile ("param2");
}

But, if u are working on ARM, look at the instruction set to see whitch commands are possible

As an example: If you want to write some timing critical stuff, that needs to be in the written order you could do something like this

inline void COLOUR_GLCD_write_address_data(uint8_t address, uint16_t data)
{
  asm volatile ("DMB");
  *(volatile uint16_t*)LCD_CMD_ADDRESS = address; 
  asm volatile ("DMB");
  *(volatile uint16_t*)LCD_DATA_ADDRESS = data; 
}

This was for sending data to an external lcd via the BUS Interface on an Atmel SAME70. Hope that helped =)