suspected compiler optimization bug

Asked by Marc Schafer

I am trying to build an application with gcc-arm-none-eabi-4_8-2013q4 and the RTX operating system for an STM32F3Discovery board and I have discovered what I think is a compiler optimization bug. I downloaded the latest Keil MDK and got the RTX source and library from:
C:\Keil_v5\ARM\Pack\ARM\CMSIS\3.20.4\CMSIS_RTX

I created an application with a few threads, semaphores, and a message queue that all works fine. However, when I added a timer to my code, I found that the application crashes as soon as the timer goes off. I eventually traced the problem to the function below in the file rt_CMSIS.c. Turning off optimization for just this function eliminates the crash, but it is still present with O1, O2, or O3.

The problems appears to be that the caller expects the function pointer and argument to be returned in r0 and r1 respectively which seems to be the correct behavior according to the AAPCS. Optimization causes these values to be returned in r2 and r3 leading to the crash when the caller tries to branch to what it thinks is the function pointer.

The function body:

/// Get timer callback parameters
os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
  os_timer_cb *pt;
  osCallback ret;

  pt = rt_id2obj(timer_id); <-------- returns timer_id in the crashing case
  if (pt == NULL) { <-------- always false in the crashing case
    ret.fp = NULL;
    ret.arg = NULL;
    return osCallback_ret;
  }

  ret.fp = (void *)pt->timer->ptimer;
  ret.arg = pt->arg;

  return osCallback_ret;
}

relevant typedefs from rt_CMSIS.c
#define os_InRegs
typedef uint32_t __attribute__((vector_size(8))) ret64;
#define osCallback_type ret64
#define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}

typedef struct {
  void *fp; // Function pointer
  void *arg; // Function argument
} osCallback;

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Joey Ye (jinyun-ye) said :
#1

Marc,

Here is what I got with -O2 -mcpu=cortex-m3 with 4.8 2013q4 release:
svcTimerCall:
 lsls r3, r0, #30
 bne .L190
 cbz r0, .L190
 ldr r1, [r0, #16]
 ldr r3, [r0, #12]
 ldr r2, [r1]
 mov r1, r3
 mov r0, r2
 bx lr
.L190:
 movs r0, #0
 movs r1, #0
 bx lr

From which I didn't find the issue that r2,r3 are used the pass argument.
Please kindly provide further help to reproduce it.

Thanks,
Joey

On Wed, Mar 12, 2014 at 12:01 AM, Marc Schafer <
<email address hidden>> wrote:

> New question #245327 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/245327
>
> I am trying to build an application with gcc-arm-none-eabi-4_8-2013q4 and
> the RTX operating system for an STM32F3Discovery board and I have
> discovered what I think is a compiler optimization bug. I downloaded the
> latest Keil MDK and got the RTX source and library from:
> C:\Keil_v5\ARM\Pack\ARM\CMSIS\3.20.4\CMSIS_RTX
>
> I created an application with a few threads, semaphores, and a message
> queue that all works fine. However, when I added a timer to my code, I
> found that the application crashes as soon as the timer goes off. I
> eventually traced the problem to the function below in the file rt_CMSIS.c.
> Turning off optimization for just this function eliminates the crash, but
> it is still present with O1, O2, or O3.
>
> The problems appears to be that the caller expects the function pointer
> and argument to be returned in r0 and r1 respectively which seems to be the
> correct behavior according to the AAPCS. Optimization causes these values
> to be returned in r2 and r3 leading to the crash when the caller tries to
> branch to what it thinks is the function pointer.
>
>
> The function body:
>
> /// Get timer callback parameters
> os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
> os_timer_cb *pt;
> osCallback ret;
>
> pt = rt_id2obj(timer_id); <-------- returns timer_id in
> the crashing case
> if (pt == NULL) { <-------- always
> false in the crashing case
> ret.fp = NULL;
> ret.arg = NULL;
> return osCallback_ret;
> }
>
> ret.fp = (void *)pt->timer->ptimer;
> ret.arg = pt->arg;
>
> return osCallback_ret;
> }
>
> relevant typedefs from rt_CMSIS.c
> #define os_InRegs
> typedef uint32_t __attribute__((vector_size(8))) ret64;
> #define osCallback_type ret64
> #define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}
>
> typedef struct {
> void *fp; // Function pointer
> void *arg; // Function argument
> } osCallback;
>
>
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Joey Ye (jinyun-ye) said :
#2

Please provide more information as I can't reproduce it.

Revision history for this message
Marc Schafer (marc-schafer) said :
#3

I am using the uVision project in C:\Keil_v5\ARM\Pack\ARM\CMSIS\3.20.4\CMSIS_RTX\SRC\GCC pointing to my installation of gcc-arm-none-eabi-4_8-2013q4. uVision shows the compiler control string as:

-c -mcpu=cortex-m4 -mthumb -gdwarf-2 -MD -Wall -O3 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -IC:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include -I"C:/Program Files (x86)/GNU Tools ARM Embedded/4.8 2013q4/arm-none-eabi/include" -D__CORTEX_M4F -D__FPU_PRESENT="1" -D__CMSIS_RTOS -Wa,-alhms="./CM4F_LE/*.lst" -o *.o

I think the key difference is hard floating point support. It looks like the value is being returned in floating point register d0 and not r2, r3 as I orignally stated. The listing below shows that I am getting an fmdrr where you have movs from r2 and r3 to r0 and r1.

The listing generated for svcTimerCall is:
2416 .global svcTimerCall
 2417 .thumb
 2418 .thumb_func
 2419 .type svcTimerCall, %function
 2420 svcTimerCall:
 2421 .LFB155:
1073:../rt_CMSIS.c **** os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
 2422 .loc 1 1073 0
 2423 .cfi_startproc
 2424 @ args = 0, pretend = 0, frame = 0
 2425 @ frame_needed = 0, uses_anonymous_args = 0
 2426 @ link register save eliminated.
 2427 .LVL244:
 2428 .LBB490:
 2429 .LBB491:
 464:../rt_CMSIS.c **** if ((uint32_t)id & 3) return NULL;
 2430 .loc 1 464 0
 2431 0000 8307 lsls r3, r0, #30
 2432 0002 06D1 bne .L301
 2433 .LBE491:
 2434 .LBE490:
1078:../rt_CMSIS.c **** if (pt == NULL) {
 2435 .loc 1 1078 0
 2436 0004 28B1 cbz r0, .L301
 2437 .LVL245:
1084:../rt_CMSIS.c **** ret.fp = (void *)pt->timer->ptimer;
 2438 .loc 1 1084 0
 2439 0006 0169 ldr r1, [r0, #16]
1087:../rt_CMSIS.c **** return osCallback_ret;
 2440 .loc 1 1087 0
 2441 0008 C368 ldr r3, [r0, #12]
 2442 000a 0A68 ldr r2, [r1]
1088:../rt_CMSIS.c **** }
 2443 .loc 1 1088 0
 2444 000c 43EC102B fmdrr d0, r2, r3 @ int <----------returning answer in d0
 2445 0010 7047 bx lr
 2446 .LVL246:
 2447 .L301:
1081:../rt_CMSIS.c **** return osCallback_ret;
 2448 .loc 1 1081 0
 2449 0012 0022 movs r2, #0
 2450 0014 0023 movs r3, #0
1088:../rt_CMSIS.c **** }
 2451 .loc 1 1088 0
 2452 0016 43EC102B fmdrr d0, r2, r3 @ int <----------returning answer (NULL) in d0
 2453 001a 7047 bx lr
 2454 .cfi_endproc
 2455 .LFE155:
 2456 .size svcTimerCall, .-svcTimerCall

Revision history for this message
Joey Ye (jinyun-ye) said :
#4

As osCallret is defined as vector type, it looks reasonable to return in
d0. As long as the caller follows the same convention there shouldn't be
anything wrong.
2014-3-25 下午8:16于 "Marc Schafer" <email address hidden>写道:

> Question #245327 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/245327
>
> Status: Answered => Open
>
> Marc Schafer is still having a problem:
> I am using the uVision project in
> C:\Keil_v5\ARM\Pack\ARM\CMSIS\3.20.4\CMSIS_RTX\SRC\GCC pointing to my
> installation of gcc-arm-none-eabi-4_8-2013q4. uVision shows the
> compiler control string as:
>
> -c -mcpu=cortex-m4 -mthumb -gdwarf-2 -MD -Wall -O3 -mcpu=cortex-m4
> -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections
> -IC:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include -I"C:/Program Files
> (x86)/GNU Tools ARM Embedded/4.8 2013q4/arm-none-eabi/include"
> -D__CORTEX_M4F -D__FPU_PRESENT="1" -D__CMSIS_RTOS
> -Wa,-alhms="./CM4F_LE/*.lst" -o *.o
>
> I think the key difference is hard floating point support. It looks
> like the value is being returned in floating point register d0 and not
> r2, r3 as I orignally stated. The listing below shows that I am getting
> an fmdrr where you have movs from r2 and r3 to r0 and r1.
>
> The listing generated for svcTimerCall is:
> 2416 .global svcTimerCall
> 2417 .thumb
> 2418 .thumb_func
> 2419 .type svcTimerCall, %function
> 2420 svcTimerCall:
> 2421 .LFB155:
> 1073:../rt_CMSIS.c **** os_InRegs osCallback_type svcTimerCall (osTimerId
> timer_id) {
> 2422 .loc 1 1073 0
> 2423 .cfi_startproc
> 2424 @ args = 0, pretend = 0, frame = 0
> 2425 @ frame_needed = 0, uses_anonymous_args = 0
> 2426 @ link register save eliminated.
> 2427 .LVL244:
> 2428 .LBB490:
> 2429 .LBB491:
> 464:../rt_CMSIS.c **** if ((uint32_t)id & 3) return NULL;
> 2430 .loc 1 464 0
> 2431 0000 8307 lsls r3, r0, #30
> 2432 0002 06D1 bne .L301
> 2433 .LBE491:
> 2434 .LBE490:
> 1078:../rt_CMSIS.c **** if (pt == NULL) {
> 2435 .loc 1 1078 0
> 2436 0004 28B1 cbz r0, .L301
> 2437 .LVL245:
> 1084:../rt_CMSIS.c **** ret.fp = (void *)pt->timer->ptimer;
> 2438 .loc 1 1084 0
> 2439 0006 0169 ldr r1, [r0, #16]
> 1087:../rt_CMSIS.c **** return osCallback_ret;
> 2440 .loc 1 1087 0
> 2441 0008 C368 ldr r3, [r0, #12]
> 2442 000a 0A68 ldr r2, [r1]
> 1088:../rt_CMSIS.c **** }
> 2443 .loc 1 1088 0
> 2444 000c 43EC102B fmdrr d0, r2, r3 @ int
> <----------returning answer in d0
> 2445 0010 7047 bx lr
> 2446 .LVL246:
> 2447 .L301:
> 1081:../rt_CMSIS.c **** return osCallback_ret;
> 2448 .loc 1 1081 0
> 2449 0012 0022 movs r2, #0
> 2450 0014 0023 movs r3, #0
> 1088:../rt_CMSIS.c **** }
> 2451 .loc 1 1088 0
> 2452 0016 43EC102B fmdrr d0, r2, r3 @ int
> <----------returning answer (NULL) in d0
> 2453 001a 7047 bx lr
> 2454 .cfi_endproc
> 2455 .LFE155:
> 2456 .size svcTimerCall, .-svcTimerCall
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Marc Schafer (marc-schafer) said :
#5

The caller is osTimerThread in the same file and it does not follow the convention. Is this a bug in the code because of mixing the vector type and struct type?

Here is the listing generated for osTimerThread:

3115 .global osTimerThread
 3116 .thumb
 3117 .thumb_func
 3118 .type osTimerThread, %function
 3119 osTimerThread:
 3120 .LFB164:
1177:../rt_CMSIS.c **** __NO_RETURN void osTimerThread (void const *argument) {
 3121 .loc 1 1177 0
 3122 .cfi_startproc
 3123 @ Volatile: function does not return.
 3124 @ args = 0, pretend = 0, frame = 0
 3125 @ frame_needed = 0, uses_anonymous_args = 0
 3126 .LVL309:
 3127 0000 08B5 push {r3, lr}
 3128 .LCFI32:
 3129 .cfi_def_cfa_offset 8
 3130 .cfi_offset 3, -8
 3131 .cfi_offset 14, -4
 3132 0002 0C4E ldr r6, .L393
 3133 .LVL310:
 3134 .L391:
 3135 0004 3568 ldr r5, [r6]
 3136 .L386:
 3137 .LVL311:
 3138 .LBB563:
 3139 .LBB564:
 3140 .LBB565:
 3141 .LBB566:
 383:C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include\core_cmFunc.h **** __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
 3142 .loc 2 383 0
 3143 @ 383 "C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include/core_cmFunc.h" 1
 3144 0006 EFF30584 MRS r4, ipsr
 3145 @ 0 "" 2
 3146 .LVL312:
 3147 .thumb
 3148 .LBE566:
 3149 .LBE565:

ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s page 110

 3150 .LBB567:
 3151 .LBB568:
1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_o
 3152 .loc 1 1688 0
 3153 000a 4FF0FF31 mov r1, #-1
 3154 000e 2846 mov r0, r5
 3155 .LBE568:
 3156 .LBE567:
1773:../rt_CMSIS.c ****
1774:../rt_CMSIS.c **** return osOK;
1775:../rt_CMSIS.c **** }
1776:../rt_CMSIS.c ****
1777:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a Queue
1778:../rt_CMSIS.c **** static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
1779:../rt_CMSIS.c **** OS_RESULT res;
1780:../rt_CMSIS.c **** osEvent ret;
1781:../rt_CMSIS.c ****
1782:../rt_CMSIS.c **** if ((queue_id == NULL) || (millisec != 0)) {
1783:../rt_CMSIS.c **** ret.status = osErrorParameter;
1784:../rt_CMSIS.c **** return ret;
1785:../rt_CMSIS.c **** }
1786:../rt_CMSIS.c ****
1787:../rt_CMSIS.c **** if (((P_MCB)queue_id)->cb_type != MCB) {
1788:../rt_CMSIS.c **** ret.status = osErrorParameter;
1789:../rt_CMSIS.c **** return ret;
1790:../rt_CMSIS.c **** }
1791:../rt_CMSIS.c ****
1792:../rt_CMSIS.c **** res = isr_mbx_receive(queue_id, &ret.value.p);
1793:../rt_CMSIS.c ****
1794:../rt_CMSIS.c **** if (res != OS_R_MBX) {
1795:../rt_CMSIS.c **** ret.status = osOK;
1796:../rt_CMSIS.c **** return ret;
1797:../rt_CMSIS.c **** }
1798:../rt_CMSIS.c ****
1799:../rt_CMSIS.c **** ret.status = osEventMessage;
1800:../rt_CMSIS.c ****
1801:../rt_CMSIS.c **** return ret;
1802:../rt_CMSIS.c **** }
1803:../rt_CMSIS.c ****
1804:../rt_CMSIS.c ****
1805:../rt_CMSIS.c **** // Message Queue Management Public API
1806:../rt_CMSIS.c ****
1807:../rt_CMSIS.c **** /// Create and Initialize Message Queue
1808:../rt_CMSIS.c **** osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
1809:../rt_CMSIS.c **** if (__get_IPSR() != 0) return NULL; // Not allowed in ISR
1810:../rt_CMSIS.c **** if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
1811:../rt_CMSIS.c **** // Privileged and not running
1812:../rt_CMSIS.c **** return svcMessageCreate(queue_def, thread_id);
1813:../rt_CMSIS.c **** } else {
1814:../rt_CMSIS.c **** return __svcMessageCreate(queue_def, thread_id);
1815:../rt_CMSIS.c **** }
1816:../rt_CMSIS.c **** }
1817:../rt_CMSIS.c ****
1818:../rt_CMSIS.c **** /// Put a Message to a Queue
1819:../rt_CMSIS.c **** osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
1820:../rt_CMSIS.c **** if (__get_IPSR() != 0) { // in ISR
1821:../rt_CMSIS.c **** return isrMessagePut(queue_id, info, millisec);

ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s page 111

1822:../rt_CMSIS.c **** } else { // in Thread
1823:../rt_CMSIS.c **** return __svcMessagePut(queue_id, info, millisec);
1824:../rt_CMSIS.c **** }
1825:../rt_CMSIS.c **** }
1826:../rt_CMSIS.c ****
1827:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a Queue
1828:../rt_CMSIS.c **** os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
1829:../rt_CMSIS.c **** if (__get_IPSR() != 0) { // in ISR
 3157 .loc 1 1829 0
 3158 0010 002C cmp r4, #0
 3159 0012 F8D1 bne .L386
 3160 .LVL313:
 3161 .LBB570:
 3162 .LBB569:
1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_o
 3163 .loc 1 1688 0
 3164 @ 1688 "../rt_CMSIS.c" 1
 3165 0014 DFF820C0 ldr r12,=svcMessageGet
 3166 0018 00DF svc 0
 3167 @ 0 "" 2
 3168 .LVL314:
 3169 .thumb
 3170 .LBE569:
 3171 .LBE570:
 3172 .LBE564:
 3173 .LBE563:
1183:../rt_CMSIS.c **** if (evt.status == osEventMessage) {
 3174 .loc 1 1183 0
 3175 001a 1028 cmp r0, #16
 3176 001c F2D1 bne .L391
 3177 .LVL315:
 3178 .LBB571:
 3179 .LBB572:
 3180 .LBB573:
 958:../rt_CMSIS.c **** SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCa
 3181 .loc 1 958 0
 3182 001e 0846 mov r0, r1
 3183 .LVL316:
 3184 @ 958 "../rt_CMSIS.c" 1
 3185 0020 DFF818C0 ldr r12,=svcTimerCall
 3186 0024 00DF svc 0 <-------------------- call to svcTimerCall via svc
 3187 @ 0 "" 2
 3188 .LVL317:
 3189 .thumb
 3190 .LBE573:
 3191 .LBE572:
 3192 .LBE571:
1185:../rt_CMSIS.c **** if (cb.fp != NULL) {
 3193 .loc 1 1185 0
 3194 0026 0446 mov r4, r0 <---- expecting r0 to contain the returned fcn ptr
 3195 .LVL318:
 3196 0028 0028 cmp r0, #0
 3197 002a EBD0 beq .L391
1186:../rt_CMSIS.c **** (*(os_ptimer)cb.fp)(cb.arg);
 3198 .loc 1 1186 0
 3199 002c 0846 mov r0, r1 <---- expecting r1 to contain the returned fcn arg
 3200 .LVL319:

ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s page 112

 3201 002e A047 blx r4 <---- crashes here when it tries to call the function
 3202 .LVL320:
 3203 0030 E8E7 b .L391
 3204 .L394:
 3205 0032 00BF .align 2
 3206 .L393:
 3207 0034 00000000 .word osMessageQId_osTimerMessageQ
 3208 .cfi_endproc

Revision history for this message
Joey Ye (jinyun-ye) said :
#6

Svc call is not following c calling convention. I suspect it is a bug in
rt_cmsis. I'll investigate it tomorrow.

Thanks
Joey
2014-3-25 下午10:36于 "Marc Schafer" <email address hidden>写道:

> Question #245327 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/245327
>
> Status: Answered => Open
>
> Marc Schafer is still having a problem:
> The caller is osTimerThread in the same file and it does not follow the
> convention. Is this a bug in the code because of mixing the vector type
> and struct type?
>
>
> Here is the listing generated for osTimerThread:
>
> 3115 .global osTimerThread
> 3116 .thumb
> 3117 .thumb_func
> 3118 .type osTimerThread, %function
> 3119 osTimerThread:
> 3120 .LFB164:
> 1177:../rt_CMSIS.c **** __NO_RETURN void osTimerThread (void const
> *argument) {
> 3121 .loc 1 1177 0
> 3122 .cfi_startproc
> 3123 @ Volatile: function does not return.
> 3124 @ args = 0, pretend = 0, frame = 0
> 3125 @ frame_needed = 0, uses_anonymous_args = 0
> 3126 .LVL309:
> 3127 0000 08B5 push {r3, lr}
> 3128 .LCFI32:
> 3129 .cfi_def_cfa_offset 8
> 3130 .cfi_offset 3, -8
> 3131 .cfi_offset 14, -4
> 3132 0002 0C4E ldr r6, .L393
> 3133 .LVL310:
> 3134 .L391:
> 3135 0004 3568 ldr r5, [r6]
> 3136 .L386:
> 3137 .LVL311:
> 3138 .LBB563:
> 3139 .LBB564:
> 3140 .LBB565:
> 3141 .LBB566:
> 383:C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include\core_cmFunc.h ****
> __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
> 3142 .loc 2 383 0
> 3143 @ 383
> "C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include/core_cmFunc.h" 1
> 3144 0006 EFF30584 MRS r4, ipsr
> 3145 @ 0 "" 2
> 3146 .LVL312:
> 3147 .thumb
> 3148 .LBE566:
> 3149 .LBE565:
> ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> page 110
>
>
> 3150 .LBB567:
> 3151 .LBB568:
> 1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent,
> osMessageQId, uint32_t, RET_o
> 3152 .loc 1 1688 0
> 3153 000a 4FF0FF31 mov r1, #-1
> 3154 000e 2846 mov r0, r5
> 3155 .LBE568:
> 3156 .LBE567:
> 1773:../rt_CMSIS.c ****
> 1774:../rt_CMSIS.c **** return osOK;
> 1775:../rt_CMSIS.c **** }
> 1776:../rt_CMSIS.c ****
> 1777:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a
> Queue
> 1778:../rt_CMSIS.c **** static __INLINE os_InRegs osEvent isrMessageGet
> (osMessageQId queue_id, uint32_t millisec) {
> 1779:../rt_CMSIS.c **** OS_RESULT res;
> 1780:../rt_CMSIS.c **** osEvent ret;
> 1781:../rt_CMSIS.c ****
> 1782:../rt_CMSIS.c **** if ((queue_id == NULL) || (millisec != 0)) {
> 1783:../rt_CMSIS.c **** ret.status = osErrorParameter;
> 1784:../rt_CMSIS.c **** return ret;
> 1785:../rt_CMSIS.c **** }
> 1786:../rt_CMSIS.c ****
> 1787:../rt_CMSIS.c **** if (((P_MCB)queue_id)->cb_type != MCB) {
> 1788:../rt_CMSIS.c **** ret.status = osErrorParameter;
> 1789:../rt_CMSIS.c **** return ret;
> 1790:../rt_CMSIS.c **** }
> 1791:../rt_CMSIS.c ****
> 1792:../rt_CMSIS.c **** res = isr_mbx_receive(queue_id, &ret.value.p);
> 1793:../rt_CMSIS.c ****
> 1794:../rt_CMSIS.c **** if (res != OS_R_MBX) {
> 1795:../rt_CMSIS.c **** ret.status = osOK;
> 1796:../rt_CMSIS.c **** return ret;
> 1797:../rt_CMSIS.c **** }
> 1798:../rt_CMSIS.c ****
> 1799:../rt_CMSIS.c **** ret.status = osEventMessage;
> 1800:../rt_CMSIS.c ****
> 1801:../rt_CMSIS.c **** return ret;
> 1802:../rt_CMSIS.c **** }
> 1803:../rt_CMSIS.c ****
> 1804:../rt_CMSIS.c ****
> 1805:../rt_CMSIS.c **** // Message Queue Management Public API
> 1806:../rt_CMSIS.c ****
> 1807:../rt_CMSIS.c **** /// Create and Initialize Message Queue
> 1808:../rt_CMSIS.c **** osMessageQId osMessageCreate (const
> osMessageQDef_t *queue_def, osThreadId thread_id) {
> 1809:../rt_CMSIS.c **** if (__get_IPSR() != 0) return NULL; //
> Not allowed in ISR
> 1810:../rt_CMSIS.c **** if (((__get_CONTROL() & 1) == 0) && (os_running
> == 0)) {
> 1811:../rt_CMSIS.c **** // Privileged and not running
> 1812:../rt_CMSIS.c **** return svcMessageCreate(queue_def,
> thread_id);
> 1813:../rt_CMSIS.c **** } else {
> 1814:../rt_CMSIS.c **** return __svcMessageCreate(queue_def,
> thread_id);
> 1815:../rt_CMSIS.c **** }
> 1816:../rt_CMSIS.c **** }
> 1817:../rt_CMSIS.c ****
> 1818:../rt_CMSIS.c **** /// Put a Message to a Queue
> 1819:../rt_CMSIS.c **** osStatus osMessagePut (osMessageQId queue_id,
> uint32_t info, uint32_t millisec) {
> 1820:../rt_CMSIS.c **** if (__get_IPSR() != 0) { //
> in ISR
> 1821:../rt_CMSIS.c **** return isrMessagePut(queue_id, info,
> millisec);
> ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> page 111
>
>
> 1822:../rt_CMSIS.c **** } else { //
> in Thread
> 1823:../rt_CMSIS.c **** return __svcMessagePut(queue_id, info,
> millisec);
> 1824:../rt_CMSIS.c **** }
> 1825:../rt_CMSIS.c **** }
> 1826:../rt_CMSIS.c ****
> 1827:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a
> Queue
> 1828:../rt_CMSIS.c **** os_InRegs osEvent osMessageGet (osMessageQId
> queue_id, uint32_t millisec) {
> 1829:../rt_CMSIS.c **** if (__get_IPSR() != 0) { //
> in ISR
> 3157 .loc 1 1829 0
> 3158 0010 002C cmp r4, #0
> 3159 0012 F8D1 bne .L386
> 3160 .LVL313:
> 3161 .LBB570:
> 3162 .LBB569:
> 1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent,
> osMessageQId, uint32_t, RET_o
> 3163 .loc 1 1688 0
> 3164 @ 1688 "../rt_CMSIS.c" 1
> 3165 0014 DFF820C0 ldr r12,=svcMessageGet
> 3166 0018 00DF svc 0
> 3167 @ 0 "" 2
> 3168 .LVL314:
> 3169 .thumb
> 3170 .LBE569:
> 3171 .LBE570:
> 3172 .LBE564:
> 3173 .LBE563:
> 1183:../rt_CMSIS.c **** if (evt.status == osEventMessage) {
> 3174 .loc 1 1183 0
> 3175 001a 1028 cmp r0, #16
> 3176 001c F2D1 bne .L391
> 3177 .LVL315:
> 3178 .LBB571:
> 3179 .LBB572:
> 3180 .LBB573:
> 958:../rt_CMSIS.c **** SVC_1_2(svcTimerCall, os_InRegs osCallback,
> osTimerId, RET_osCa
> 3181 .loc 1 958 0
> 3182 001e 0846 mov r0, r1
> 3183 .LVL316:
> 3184 @ 958 "../rt_CMSIS.c" 1
> 3185 0020 DFF818C0 ldr r12,=svcTimerCall
> 3186 0024 00DF svc 0
> <-------------------- call to svcTimerCall via svc
> 3187 @ 0 "" 2
> 3188 .LVL317:
> 3189 .thumb
> 3190 .LBE573:
> 3191 .LBE572:
> 3192 .LBE571:
> 1185:../rt_CMSIS.c **** if (cb.fp != NULL) {
> 3193 .loc 1 1185 0
> 3194 0026 0446 mov r4, r0
> <---- expecting r0 to contain the returned fcn ptr
> 3195 .LVL318:
> 3196 0028 0028 cmp r0, #0
> 3197 002a EBD0 beq .L391
> 1186:../rt_CMSIS.c **** (*(os_ptimer)cb.fp)(cb.arg);
> 3198 .loc 1 1186 0
> 3199 002c 0846 mov r0, r1
> <---- expecting r1 to contain the returned fcn arg
> 3200 .LVL319:
> ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> page 112
>
>
> 3201 002e A047 blx r4
> <---- crashes here when it tries to call the function
> 3202 .LVL320:
> 3203 0030 E8E7 b .L391
> 3204 .L394:
> 3205 0032 00BF .align 2
> 3206 .L393:
> 3207 0034 00000000 .word osMessageQId_osTimerMessageQ
> 3208 .cfi_endproc
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Joey Ye (jinyun-ye) said :
#7

Confirmed. It is either a GCC bug or rt_CMSIS bug. I'll follow up.

On Tue, Mar 25, 2014 at 11:16 PM, Joey Ye <
<email address hidden>> wrote:

> Question #245327 on GCC ARM Embedded changed:
> https://answers.launchpad.net/gcc-arm-embedded/+question/245327
>
> Status: Open => Answered
>
> Joey Ye proposed the following answer:
> Svc call is not following c calling convention. I suspect it is a bug in
> rt_cmsis. I'll investigate it tomorrow.
>
> Thanks
> Joey
> 2014-3-25 下午10:36于 "Marc Schafer" <<email address hidden>
> >写道:
>
> > Question #245327 on GCC ARM Embedded changed:
> > https://answers.launchpad.net/gcc-arm-embedded/+question/245327
> >
> > Status: Answered => Open
> >
> > Marc Schafer is still having a problem:
> > The caller is osTimerThread in the same file and it does not follow the
> > convention. Is this a bug in the code because of mixing the vector type
> > and struct type?
> >
> >
> > Here is the listing generated for osTimerThread:
> >
> > 3115 .global osTimerThread
> > 3116 .thumb
> > 3117 .thumb_func
> > 3118 .type osTimerThread, %function
> > 3119 osTimerThread:
> > 3120 .LFB164:
> > 1177:../rt_CMSIS.c **** __NO_RETURN void osTimerThread (void const
> > *argument) {
> > 3121 .loc 1 1177 0
> > 3122 .cfi_startproc
> > 3123 @ Volatile: function does not return.
> > 3124 @ args = 0, pretend = 0, frame = 0
> > 3125 @ frame_needed = 0, uses_anonymous_args
> = 0
> > 3126 .LVL309:
> > 3127 0000 08B5 push {r3, lr}
> > 3128 .LCFI32:
> > 3129 .cfi_def_cfa_offset 8
> > 3130 .cfi_offset 3, -8
> > 3131 .cfi_offset 14, -4
> > 3132 0002 0C4E ldr r6, .L393
> > 3133 .LVL310:
> > 3134 .L391:
> > 3135 0004 3568 ldr r5, [r6]
> > 3136 .L386:
> > 3137 .LVL311:
> > 3138 .LBB563:
> > 3139 .LBB564:
> > 3140 .LBB565:
> > 3141 .LBB566:
> > 383:C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include\core_cmFunc.h
> ****
> > __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
> > 3142 .loc 2 383 0
> > 3143 @ 383
> > "C:/Keil_v5/ARM/PACK/ARM/CMSIS/3.20.4/CMSIS/Include/core_cmFunc.h" 1
> > 3144 0006 EFF30584 MRS r4, ipsr
> > 3145 @ 0 "" 2
> > 3146 .LVL312:
> > 3147 .thumb
> > 3148 .LBE566:
> > 3149 .LBE565:
> > ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> > page 110
> >
> >
> > 3150 .LBB567:
> > 3151 .LBB568:
> > 1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent,
> > osMessageQId, uint32_t, RET_o
> > 3152 .loc 1 1688 0
> > 3153 000a 4FF0FF31 mov r1, #-1
> > 3154 000e 2846 mov r0, r5
> > 3155 .LBE568:
> > 3156 .LBE567:
> > 1773:../rt_CMSIS.c ****
> > 1774:../rt_CMSIS.c **** return osOK;
> > 1775:../rt_CMSIS.c **** }
> > 1776:../rt_CMSIS.c ****
> > 1777:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a
> > Queue
> > 1778:../rt_CMSIS.c **** static __INLINE os_InRegs osEvent isrMessageGet
> > (osMessageQId queue_id, uint32_t millisec) {
> > 1779:../rt_CMSIS.c **** OS_RESULT res;
> > 1780:../rt_CMSIS.c **** osEvent ret;
> > 1781:../rt_CMSIS.c ****
> > 1782:../rt_CMSIS.c **** if ((queue_id == NULL) || (millisec != 0)) {
> > 1783:../rt_CMSIS.c **** ret.status = osErrorParameter;
> > 1784:../rt_CMSIS.c **** return ret;
> > 1785:../rt_CMSIS.c **** }
> > 1786:../rt_CMSIS.c ****
> > 1787:../rt_CMSIS.c **** if (((P_MCB)queue_id)->cb_type != MCB) {
> > 1788:../rt_CMSIS.c **** ret.status = osErrorParameter;
> > 1789:../rt_CMSIS.c **** return ret;
> > 1790:../rt_CMSIS.c **** }
> > 1791:../rt_CMSIS.c ****
> > 1792:../rt_CMSIS.c **** res = isr_mbx_receive(queue_id, &ret.value.p);
> > 1793:../rt_CMSIS.c ****
> > 1794:../rt_CMSIS.c **** if (res != OS_R_MBX) {
> > 1795:../rt_CMSIS.c **** ret.status = osOK;
> > 1796:../rt_CMSIS.c **** return ret;
> > 1797:../rt_CMSIS.c **** }
> > 1798:../rt_CMSIS.c ****
> > 1799:../rt_CMSIS.c **** ret.status = osEventMessage;
> > 1800:../rt_CMSIS.c ****
> > 1801:../rt_CMSIS.c **** return ret;
> > 1802:../rt_CMSIS.c **** }
> > 1803:../rt_CMSIS.c ****
> > 1804:../rt_CMSIS.c ****
> > 1805:../rt_CMSIS.c **** // Message Queue Management Public API
> > 1806:../rt_CMSIS.c ****
> > 1807:../rt_CMSIS.c **** /// Create and Initialize Message Queue
> > 1808:../rt_CMSIS.c **** osMessageQId osMessageCreate (const
> > osMessageQDef_t *queue_def, osThreadId thread_id) {
> > 1809:../rt_CMSIS.c **** if (__get_IPSR() != 0) return NULL;
> //
> > Not allowed in ISR
> > 1810:../rt_CMSIS.c **** if (((__get_CONTROL() & 1) == 0) && (os_running
> > == 0)) {
> > 1811:../rt_CMSIS.c **** // Privileged and not running
> > 1812:../rt_CMSIS.c **** return svcMessageCreate(queue_def,
> > thread_id);
> > 1813:../rt_CMSIS.c **** } else {
> > 1814:../rt_CMSIS.c **** return __svcMessageCreate(queue_def,
> > thread_id);
> > 1815:../rt_CMSIS.c **** }
> > 1816:../rt_CMSIS.c **** }
> > 1817:../rt_CMSIS.c ****
> > 1818:../rt_CMSIS.c **** /// Put a Message to a Queue
> > 1819:../rt_CMSIS.c **** osStatus osMessagePut (osMessageQId queue_id,
> > uint32_t info, uint32_t millisec) {
> > 1820:../rt_CMSIS.c **** if (__get_IPSR() != 0) {
> //
> > in ISR
> > 1821:../rt_CMSIS.c **** return isrMessagePut(queue_id, info,
> > millisec);
> > ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> > page 111
> >
> >
> > 1822:../rt_CMSIS.c **** } else {
> //
> > in Thread
> > 1823:../rt_CMSIS.c **** return __svcMessagePut(queue_id, info,
> > millisec);
> > 1824:../rt_CMSIS.c **** }
> > 1825:../rt_CMSIS.c **** }
> > 1826:../rt_CMSIS.c ****
> > 1827:../rt_CMSIS.c **** /// Get a Message or Wait for a Message from a
> > Queue
> > 1828:../rt_CMSIS.c **** os_InRegs osEvent osMessageGet (osMessageQId
> > queue_id, uint32_t millisec) {
> > 1829:../rt_CMSIS.c **** if (__get_IPSR() != 0) {
> //
> > in ISR
> > 3157 .loc 1 1829 0
> > 3158 0010 002C cmp r4, #0
> > 3159 0012 F8D1 bne .L386
> > 3160 .LVL313:
> > 3161 .LBB570:
> > 3162 .LBB569:
> > 1688:../rt_CMSIS.c **** SVC_2_3(svcMessageGet, os_InRegs osEvent,
> > osMessageQId, uint32_t, RET_o
> > 3163 .loc 1 1688 0
> > 3164 @ 1688 "../rt_CMSIS.c" 1
> > 3165 0014 DFF820C0 ldr r12,=svcMessageGet
> > 3166 0018 00DF svc 0
> > 3167 @ 0 "" 2
> > 3168 .LVL314:
> > 3169 .thumb
> > 3170 .LBE569:
> > 3171 .LBE570:
> > 3172 .LBE564:
> > 3173 .LBE563:
> > 1183:../rt_CMSIS.c **** if (evt.status == osEventMessage) {
> > 3174 .loc 1 1183 0
> > 3175 001a 1028 cmp r0, #16
> > 3176 001c F2D1 bne .L391
> > 3177 .LVL315:
> > 3178 .LBB571:
> > 3179 .LBB572:
> > 3180 .LBB573:
> > 958:../rt_CMSIS.c **** SVC_1_2(svcTimerCall, os_InRegs osCallback,
> > osTimerId, RET_osCa
> > 3181 .loc 1 958 0
> > 3182 001e 0846 mov r0, r1
> > 3183 .LVL316:
> > 3184 @ 958 "../rt_CMSIS.c" 1
> > 3185 0020 DFF818C0 ldr r12,=svcTimerCall
> > 3186 0024 00DF svc 0
> > <-------------------- call to svcTimerCall via svc
> > 3187 @ 0 "" 2
> > 3188 .LVL317:
> > 3189 .thumb
> > 3190 .LBE573:
> > 3191 .LBE572:
> > 3192 .LBE571:
> > 1185:../rt_CMSIS.c **** if (cb.fp != NULL) {
> > 3193 .loc 1 1185 0
> > 3194 0026 0446 mov r4, r0
> > <---- expecting r0 to contain the returned fcn ptr
> > 3195 .LVL318:
> > 3196 0028 0028 cmp r0, #0
> > 3197 002a EBD0 beq .L391
> > 1186:../rt_CMSIS.c **** (*(os_ptimer)cb.fp)(cb.arg);
> > 3198 .loc 1 1186 0
> > 3199 002c 0846 mov r0, r1
> > <---- expecting r1 to contain the returned fcn arg
> > 3200 .LVL319:
> > ARM GAS C:\Users\mschafer\AppData\Local\Temp\ccMuSYW6.s
> > page 112
> >
> >
> > 3201 002e A047 blx r4
> > <---- crashes here when it tries to call the function
> > 3202 .LVL320:
> > 3203 0030 E8E7 b .L391
> > 3204 .L394:
> > 3205 0032 00BF .align 2
> > 3206 .L393:
> > 3207 0034 00000000 .word osMessageQId_osTimerMessageQ
> > 3208 .cfi_endproc
> >
> > --
> > You received this question notification because you are an answer
> > contact for GCC ARM Embedded.
> >
>
> --
> You received this question notification because you are an answer
> contact for GCC ARM Embedded.
>

Revision history for this message
Joey Ye (jinyun-ye) said :
#8

This bug has been fixed in latest CMSIS version 4.2

Can you help with this problem?

Provide an answer of your own, or ask Marc Schafer for more information if necessary.

To post a message you must log in.