This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Push without Pop in SWI handler in for in os_portasm.s the Halcogen Generated Code for freeRTOS.

Other Parts Discussed in Thread: HALCOGEN

There appears to be a push-without-pop error in the SWI handling code in os_portasm.s which is generated by Halcogen when using FreeRTOS.  You can reproduce the issue by running the "blinky" sample project using the GCC toolchain.  

Here's the main function:

int main(void) {
/* USER CODE BEGIN (3) */

/* Set high end timer GIO port hetPort pin direction to all output */
gioSetDirection(hetPORT1, 0xFFFFFFFF);

/* Create Task 1 */
if (xTaskCreate(vTask1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1,
&xTask1Handle) != pdTRUE) {
/* Task could not be created */
while (1)
;
}

/* Start Scheduler */
vTaskStartScheduler();    <<<<< CRASH IN THIS CALL HERE >>>>>>

/* Run forever */
while (1)
;
/* USER CODE END */
}

Here's the problem I see when debugging through os_portasm.s:

<snip>

@ SWI Handler, interface to Protected Mode Functions

.weak vPortSWI
.type vPortSWI, %function

vPortSWI:
stmfd sp!, {r12,lr}         <---- 1. push r12, lr onto the stack
mrs r12, spsr
ands r12, r12, #0x20
ldrbne r12, [lr, #-2]
ldrbeq r12, [lr, #-4]
ldr r14, table
ldr r12, [r14, r12, lsl #2] <---- 2. Jump to swiPortExitCritical
blx r12                     <---- 5. Return Here
ldmfd sp!, {r12,pc}^        <---- 6. Pop from mismatched stack and throw invalid instruction

table:
.word jumpTable

jumpTable:
.word swiPortYield @ 0 - vPortYield
.word swiRaisePrivilege @ 1 - Raise Priviledge
.word swiPortEnterCritical @ 2 - vPortEnterCritical
.word swiPortExitCritical @ 3 - vPortExitCritical
.word swiPortTaskUsesFPU @ 4 - vPortTaskUsesFPU
.word swiPortDisableInterrupts @ 5 - vPortDisableInterrupts
.word swiPortEnableInterrupts @ 6 - vPortEnableInterrupts

<snip>


@ swiPortExitCritical

swiPortExitCritical:
stmfd sp!, {r0}             <---- 3. Enter here and push R0 onto the stack
ldr r0, ulCriticalNestingConst
ldr r12, [r0]
cmp r12, #0
bxeq r14
subs r12, r12, #1
str r12, [r0]
bxne r14                    <---- 4. return here (without the pop)
mrs r0, SPSR
bic r0, r0, #0x80
msr SPSR_c, r0
ldmfd sp!, {r0}
bx r14

I was able to work-around the code in the short-term by patching the two places that exit without pop by using the following code:

@ swiPortExitCritical

swiPortExitCritical:
stmfd sp!, {r0}
ldr r0, ulCriticalNestingConst
ldr r12, [r0]
cmp r12, #0
ldmfdeq sp!, {r0}
bxeq r14
subs r12, r12, #1
str r12, [r0]
ldmfdne sp!, {r0}
bxne r14
mrs r0, SPSR
bic r0, r0, #0x80
msr SPSR_c, r0
ldmfd sp!, {r0}
bx r14

This appears to be a bug to me.  Can I get confirmation of the bug and if possible some idea of when the fix may be coming?