mbed-rtos on CM0 fails to build with "build.py -r -o debug-info"

30 Aug 2014

I'm currently doing offline development with the mbed SDK, and noticed it fails to build under certain condition with a following error:

# python build.py -t GCC_ARM -m LPC1114 -o debug-info -r
...
Building library RTX (LPC1114, GCC_ARM)
Compile: rt_CMSIS.c
[Error] rt_CMSIS.c@588: In function 'osKernelInitialize': r7 cannot be used in asm here
c:\src\mbed\libraries\rtos\rtx\rt_CMSIS.c: In function 'osKernelInitialize':
c:\src\mbed\libraries\rtos\rtx\rt_CMSIS.c:588:1: error: r7 cannot be used in asm here
 }
 ^

Culpit is the following code in rt_CMSIS.c:

#if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS)
#define SVC_Call(f)                                                            \
  __asm volatile                                                                 \
  (                                                                            \
    "ldr r7,="#f"\n\t"                                                         \
    "mov r12,r7\n\t"                                                           \
    "svc 0"                                                                    \
    :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)         \
    :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)         \
    : "r7", "r12", "lr", "cc"                                                  \
  );
#else
...

Cortex-M0 LDR has a limitation that it cannot directly load value into upper register (r12), and that's why r7 is being used as a temporary register. However, that breaks GCC on debug build since GCC is also using r7 as frame pointer.

An easy fix would be to change r7 into something else in lower register, say r6. However, to avoid writing temporary register name in asm, following code may be better:

#define SVC_Call(f) do {                                                       \
  register int tmp;                                                            \
  __asm volatile                                                               \
  (                                                                            \
    "ldr %[tmp],="#f"\n\t"                                                     \
    "mov r12,%[tmp]\n\t"                                                       \
    "svc 0"                                                                    \
    : [tmp] "=r" (tmp), "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)     \
    :                    "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)     \
    : "r12", "lr", "cc"                                                        \
  );                                                                           \
} while (0)
30 Aug 2014

Hello there,

can you report this on github, as an issue in the mbedmicro/mbed repository? If possible, to also send a pull request afterwards? Do you have sources of newer RTX? It might be fixed there already.

Thanks for reporting and proposing a fix !

Regards,
0xc0170

31 Aug 2014

Thanks for picking this up.

As it was not yet fixed in latest code, I have raised a issue and sent in a pull request:

Best Regards,