LPC23xx port problem

wella wrote on Wednesday, November 25, 2009:


I am trying to run a LPC23xx (an ARM7TDMI-S core)port with CodeSourcery and FreeRTOS v6.0.0. My startup code setups stacks for each mode and ends with SVC mode.

                MSR     CPSR_c, #Mode_SVC|I_Bit|F_Bit
                MOV     SP, R0
                SUB     R0, R0, #SVC_Stack_Size       

+ an option to gcc -fomit-frame-pointer is set.

However during startup FreeRTOS(vTaskStartScheduler(), no more tasks are created) it always crashes in a PrefetchAbort ISR(more explained below).
During debugging I have discovered a strange behavior in pxPortInitialiseStack in prvIdleTask.
As a last operation of vTaskStartScheduler is called a macro portRESTORE_CONTEXT(). The problem is in the instruction

/* Restore all system mode registers for the task. */

"LDMFD LR, {R0-R14}^

The register LR points on saved stack(0x4000128C) of prvIdleTask. Memory from debugger is:
0x4000128C  00000000 01010101 02020202 03030303 04040404 
0x400012A0  05050505 06060606 07070707 08080808 09090909 
0x400012B4  10101010 11111111 12121212 400012C8 00000000 
0x400012C8  00005CDC A5A5A5A5 40009180 00007EA8 00000000 

The instruction loads to LR a 15th value, the zero. Next instruction will jump to the restored return address.
Because LR is zero, this jump is mostly to some abort ISR start address. No abort is generated. It seems like a one stack shift to the right.

Please could someone help me with this issue?
Thank you very much

rtel wrote on Wednesday, November 25, 2009:

I see what you say about Supervisor mode being the last stack to get set up so the CPU should be in Supervisor mode.  Normally otherwise I would say that the most likely cause would be that the CPU was simply in the wrong mode.  Its worth checking in the debugger all the same, at the point where the task context is resumed.

Which memory allocation scheme is being used?  Heap_1.c, heap_2.c, heap_3.c or something else?  Is it possible that the memory being allocated is clashing with something else?

Are you running the standard demo from the FreeRTOS download?  Has it been modified in any way?

Can you also check that the task stack is truly 8 byte aligned, and not on an odd boundary in particular.


wella wrote on Thursday, November 26, 2009:

Hi Richard,

The scheme is heap2.c and I no am using a standard demo. The codesourcery is using CS3 and I cannot compile demo for gcc. I have adopted startup code, set paths and compiled without warnings as a new project.
There is something wrong about this instruction.
ldm   lr, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr}^
If I understand it correctly, it will loads data to registers from address stored in lr to registers r0 - r14(lr). We should be now in system(1F) mode due to instruction msr   SPSR_fc, r0(0x1F). The lr contains value 0x4000128C and memory listing is the same like in my previous post.

If I count correctly, the 15th(lr value) from 0x4000128C is 0x00000000, not
00005CDC (start address of pvrIdleTask).
The stack is 8 byte aligned, adress is 0x400011E0 (tskIDLE_STACK_SIZE == 60).

Here must be some bad dwarf :). I do not understand at all why others can run examples….


wella wrote on Thursday, November 26, 2009:


I am taking all back. I do not know why but after one to one copy of startup file from ARM7_LPC2368_Eclipse it works now. It seems that there was a problem with ARM mode, I was not in SVC…
Thank you for help and pointing out.


davedoors wrote on Thursday, November 26, 2009:

http://www.freertos.org/FAQHelp.html .  Its number 4 :wink:

The instruction you reference is the expanded version of ldm lr, {r0-r14}^ which loads r0 to r14 from the Supervisor mode link register into the System/User mode link register. Assuming the LPC is already in Supervisor mode.

davedoors wrote on Thursday, November 26, 2009:

Correction - it loads the bytes starting from the address held in the Supervisor mode link register into the System/User mode registers r0 to r14.