FREERTOS problem on gcc and LPC2138
2005-10-21 by rseku
I found, that asm instructions in freertos are not compiled as exactly
as should be. As a result of execution of below code I get data_abort
exception
First I noticed LDMIA and LDMF difference.
this is RTOS code:
#define portRESTORE_CONTEXT() \
{
extern volatile void * volatile pxCurrentTCB;\
extern volatile unsigned portLONG ulCriticalNesting;\
/* Set the LR to the task stack. */ \
asm volatile ( "LDR R0, %0" : : "m" (pxCurrentTCB) );\
asm volatile ( "LDR LR, [R0]" );\
/* The critical nesting depth is the first item on the stack. */\
/* Load it into the ulCriticalNesting variable. */ \
asm volatile ( "LDR R0, =ulCriticalNesting" );\
asm volatile ( "LDMFD LR!, {R1}" );\
asm volatile ( "STR R1, [R0]" );\
/* Get the SPSR from the stack. */\
asm volatile ( "LDMFD LR!, {R0}" );\
asm volatile ( "MSR SPSR, R0" );\
/* Restore all system mode registers for the task. */\
asm volatile ( "LDMFD LR, {R0-R14}^" );\
asm volatile ( "NOP" );\
/* Restore the return address. */\
asm volatile ( "LDR LR, [LR, #+60]" );\
/* And return - correcting the offset in the LR to obtain the */\ /*
correct address. */\
asm volatile ( "SUBS PC, LR, #4" );\
( void ) ulCriticalNesting;\
}
and this is gcc interpretation:
E1A0C00D mov r12, sp
E92DD800 stmfd sp!, {r11-r12, lr-pc}
E24CB004 sub r11, r12, #0x00000004
/* Simply start the scheduler. This is included here as it can only be
called from ARM mode. */
portRESTORE_CONTEXT();
E59F3038 ldr r3, [pc, #56]
E5930000 ldr r0, [r3]
E590E000 ldr lr, [r0]
E59F024C ldr r0, [pc, #588]
E8BE0002 ldmia lr!, {r1}
E5801000 str r1, [r0]
E8BE0001 ldmia lr!, {r0}
E169F000 msr spsr_cf, r0
E8DE7FFF ldmia lr, {r0-lr}^
E1A00000 nop
E59EE03C ldr lr, [lr, #60]
E25EF004 subs pc, lr, #0x00000004
E59F300C ldr r3, [pc, #12]
E5933000 ldr r3, [r3]