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?