# LPC2129-GCC port.

**URL:** <https://forums.freertos.org/t/lpc2129-gcc-port/5092>\
**Category:** Kernel\
**Created:** [October 19, 2012, 6:24pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092 "2012-10-19T18:24:41Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [October 19, 2012, 6:24pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/1 "2012-10-19T18:24:41Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, October 19, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#0814):

This topic was lost when the forum software was switched back to the old version.&nbsp; I am pasting the entire thread below as a single post so it does not get lost.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [October 19, 2012, 6:25pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/2 "2012-10-19T18:25:36Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, October 19, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#d924):

is it OK to modify the function ‘pxPortInitialiseStack()’ in ‘port.c’ as below while porting FreeRTOS to LPC2129 with GCC tool.  
because without this modification, the scheduler will not start the task due to improper information on stack when it is restored.  
----------------- ORIGINAL FUNCTION -----------------------------  
portSTACK\_TYPE pxPortInitialiseStack( portSTACK\_TYPE pxTopOfStack, pdTASK\_CODE pxCode, void pvParameters ) { portSTACK\_TYPE pxOriginalTOS;  
pxOriginalTOS = pxTopOfStack;

/\* To ensure asserts in tasks.c don’t fail, although in this case the assert  
is not really required. \*/  
pxTopOfStack-;

/\* Setup the initial stack of the task.&nbsp; The stack is set exactly as  
expected by the portRESTORE\_CONTEXT() macro. \*/

/\* First on the stack is the return address - which in this case is the  
start of the task.&nbsp; The offset is added to make the return address appear  
as it would within an IRQ ISR. \*/  
\*pxTopOfStack = ( portSTACK\_TYPE ) pxCode + portINSTRUCTION\_SIZE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
pxTopOfStack-;

\*pxTopOfStack = ( portSTACK\_TYPE ) 0xaaaaaaaa;&nbsp; /\* R14 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) pxOriginalTOS; /\* Stack used when task starts goes in R13. \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x12121212;&nbsp; /\* R12 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x11111111;&nbsp; /\* R11 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x10101010;&nbsp; /\* R10 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x09090909;&nbsp; /\* R9 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x08080808;&nbsp; /\* R8 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x07070707;&nbsp; /\* R7 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x06060606;&nbsp; /\* R6 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x05050505;&nbsp; /\* R5 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x04040404;&nbsp; /\* R4 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x03030303;&nbsp; /\* R3 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x02020202;&nbsp; /\* R2 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x01010101;&nbsp; /\* R1 \*/  
pxTopOfStack-;

/\* When the task starts is will expect to find the function parameter in  
R0. \*/  
\*pxTopOfStack = ( portSTACK\_TYPE ) pvParameters; /\* R0 \*/  
pxTopOfStack-;

/\* The last thing onto the stack is the status register, which is set for  
system mode, with interrupts enabled. \*/  
\*pxTopOfStack = ( portSTACK\_TYPE ) portINITIAL\_SPSR;

if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )  
{  
&nbsp;&nbsp;&nbsp; /\* We want the task to start in thumb mode. \*/  
&nbsp;&nbsp;&nbsp; \*pxTopOfStack |= portTHUMB\_MODE\_BIT;  
}

pxTopOfStack-;

/\* Some optimisation levels use the stack differently to others.&nbsp; This  
means the interrupt flags cannot always be stored on the stack and will  
instead be stored in a variable, which is then saved as part of the  
tasks context. \*/  
\*pxTopOfStack = portNO\_CRITICAL\_SECTION\_NESTING;

return pxTopOfStack;  
}  
------------ MODIFIED FUNCTION ------------  
portSTACK\_TYPE pxPortInitialiseStack( portSTACK\_TYPE pxTopOfStack, pdTASK\_CODE pxCode, void pvParameters ) { portSTACK\_TYPE pxOriginalTOS; portSTACK\_TYPE \*pxTempTOS;  
pxOriginalTOS = pxTopOfStack;

/\* To ensure asserts in tasks.c don’t fail, although in this case the assert  
is not really required. \*/  
pxTopOfStack-;

/\* Setup the initial stack of the task.&nbsp; The stack is set exactly as  
expected by the portRESTORE\_CONTEXT() macro. \*/

/\* First on the stack is the return address - which in this case is the  
start of the task.&nbsp; The offset is added to make the return address appear  
as it would within an IRQ ISR. \*/  
\*pxTopOfStack = ( portSTACK\_TYPE ) pxCode + portINSTRUCTION\_SIZE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
pxTopOfStack-;

pxTempTOS = pxTopOfStack;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0xaaaaaaaa;&nbsp; /\* R14 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) pxOriginalTOS; /\* Stack used when task starts goes in R13. \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x12121212;&nbsp; /\* R12 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x11111111;&nbsp; /\* R11 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x10101010;&nbsp; /\* R10 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x09090909;&nbsp; /\* R9 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x08080808;&nbsp; /\* R8 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x07070707;&nbsp; /\* R7 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x06060606;&nbsp; /\* R6 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x05050505;&nbsp; /\* R5 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x04040404;&nbsp; /\* R4 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x03030303;&nbsp; /\* R3 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x02020202;&nbsp; /\* R2 \*/  
pxTopOfStack-;  
\*pxTopOfStack = ( portSTACK\_TYPE ) 0x01010101;&nbsp; /\* R1 \*/  
pxTopOfStack-;

/\* When the task starts is will expect to find the function parameter in  
R0. \*/  
\*pxTempTOS = (unsigned int \*)pxTopOfStack;  
\*pxTopOfStack = ( portSTACK\_TYPE ) pvParameters; /\* R0 \*/  
pxTopOfStack-;

/\* The last thing onto the stack is the status register, which is set for  
system mode, with interrupts enabled. \*/  
\*pxTopOfStack = ( portSTACK\_TYPE ) portINITIAL\_SPSR;

if( ( ( unsigned long ) pxCode & 0x01UL ) != 0x00 )  
{  
&nbsp;&nbsp;&nbsp; /\* We want the task to start in thumb mode. \*/  
&nbsp;&nbsp;&nbsp; \*pxTopOfStack |= portTHUMB\_MODE\_BIT;  
}

pxTopOfStack-;

/\* Some optimisation levels use the stack differently to others.&nbsp; This  
means the interrupt flags cannot always be stored on the stack and will  
instead be stored in a variable, which is then saved as part of the  
tasks context. \*/  
\*pxTopOfStack = portNO\_CRITICAL\_SECTION\_NESTING;

return pxTopOfStack;  
}  
Thanks,  
GCD

Reply  
Link  
Edit  
Delete  
Attach

Richard  
23 hours ago  
Can you please tell me what it is you changed so I don’t have to go through the two functions line by line.  
I’m not sure why any change would be necessary as the code that starts the first task is written in assembler and expects to find things on the stack exactly as placed on the stack with this code.  
Regards.

Reply  
Link  
Edit  
Delete  
Attach

GCD  
3 minutes ago  
Hi Richard,  
Thanks for the response. Modification is as below  
Statement below Just before storing the data supposed to be in ‘R14’ on the  
stack  
pxTempTOS = pxTopOfStack;  
below statement before storing the dummy contents of ‘R0’  
pxTempTOS = (unsigned int )pxTopOfStack;  
I encountered this issue while debugging for not getting the first task started. unfortunately don’t remember what value was getting corrupted. But got the tasks running after this modification even with FREERTOS version, 7.2.0. I’ll recheck the whole procedure I did to use FREERTOS on LPC2129 with GCC. I apologise if this topic is misleading.  
Thanks

Reply  
Link  
Edit  
Delete  
Attach

Richard

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [October 19, 2012, 7:28pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/3 "2012-10-19T19:28:56Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, October 19, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#6063):

So, if I understand correctly, the code you added:

1) Stores a pointer to the address that R14 will be popped from.

2) Writes 0xaaaaaaaa to the address R14 will be popped from.

3) Writes over 0xaaaaaaaa (the value never gets used) with the address that R0 will be popped from.&nbsp; R0 holds the parameters passed into the function.

So the net effect is, the stack frame is unchanged \*other than\*, when the task starts, R14 holds the address that R0 was popped from.

I don’t understand why this would make a difference.&nbsp; If you compiler conforms to the ARM EABI standard, then the value in R14 should not be used unless you try to return from the task function (which is not allowed).

Which compiler are you using?&nbsp; (I know you said GCC, but which build?)

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [October 20, 2012, 1:06pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/4 "2012-10-20T13:06:32Z")

</div>

**[dcgirish16](https://sourceforge.net/u/dcgirish16/)** wrote on [Saturday, October 20, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#bc2c):

Hi Richard, got it…

Initially I’ll explain the issue why I did the modification.&nbsp; Later i’ll give the compiler details I am using.

a. Issue because of which I had to do the above modification  
actually in function ‘portRESTORE\_CONTEXT()’ in portmacro.h,&nbsp; after restoring the whole stack into system registers (R0 through R14),&nbsp; there are two more instructions to calculate PC values as below,

* * *

## /\* Restore the return address. \*/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; “LDR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LR,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \n\t”&nbsp;&nbsp; \ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /\* And return - correcting the offset in the LR to obtain the \*/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /\* correct address. \*/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "SUBS&nbsp;&nbsp; PC, LR, #4&nbsp;

while trying to restore the return address using first instruction,&nbsp;&nbsp; adding 60 to the content of LR will be erroneous hence I added the address in the stack from where R0 will be popped.&nbsp; So with the modification, along with the address correction using next instruction gets PC value to the proper TOP OF STACK to get the return address.

b. GCC Compiler details.&nbsp; As u said, it looks as L14 is being used to get the right address, may be the compiler is not EABI compliant.&nbsp; but I have no idea how to check whether the compiler conforms to EABI.&nbsp; following are the details of the compiler I am using

* * *

FREE\_RTOS\_LPC\_2129\_v7# arm-softfloat-elf-gcc-4.4.3 -v  
Using built-in specs.  
Target: arm-softfloat-elf  
Configured with: …/configure -target=arm-softfloat-elf -prefix=/usr/local/cross-arm -enable-interwork -enable-multilib -enable-languages=c,c++ -with-newlib -without-headers -disable-shared -with-gnu-as -with-gnu-ld -with-float=soft  
Thread model: single  
gcc version 4.4.3 (GCC)

* * *

however, with the above modification, I could see 3 tasks running but looking for the right way to get the rtos running

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [October 20, 2012, 1:11pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/5 "2012-10-20T13:11:56Z")

</div>

**[dcgirish16](https://sourceforge.net/u/dcgirish16/)** wrote on [Saturday, October 20, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#f135):

------- a correction to one of my statement above ---------

instead of  
“adding 60 to the content of LR will be erroneous hence I added the address in the stack from where R0 will be popped”&nbsp;  
it has to be  
“adding 60 to the content of LR will be erroneous hence I copied the address of the stack location from where R0 will be popped to the location from where R14 is popped.”

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [October 21, 2012, 2:18am UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/6 "2012-10-21T02:18:11Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Sunday, October 21, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#7ddd):

The microcontroller should be in Supervisor mode when the first task is started.&nbsp; The code pops the registers from the initial stack frame into the System mode registers.&nbsp; So, while the CPU is using the Supervisor mode registers, it restores the System mode registers, then switches into System mode when the task starts.

If you are seeing R14 being altered during the start first task execution then my best guest (actually, almost certainly) you are starting the scheduler from the wrong CPU mode.

The easiest way to ensure the CPU is in the right mode is to have your start up code set the mode to Supervisor before main() is called.&nbsp; Then it will be in Supervisor when it starts the first task, and System mode when the task actually executes.

Regards.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [October 21, 2012, 4:35pm UTC](https://forums.freertos.org/t/lpc2129-gcc-port/5092/7 "2012-10-21T16:35:38Z")

</div>

**[dcgirish16](https://sourceforge.net/u/dcgirish16/)** wrote on [Sunday, October 21, 2012](https://sourceforge.net/p/freertos/discussion/382005/thread/df57c94c/#5072):

Hi Richard,  
Thanks, got it working!!
