LPC2129-GCC port.

rtel wrote on Friday, October 19, 2012:

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.  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.  The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;      
pxTopOfStack-;

*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa;  /* R14 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212;  /* R12 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;  /* R11 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010;  /* R10 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909;  /* R9 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808;  /* R8 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707;  /* R7 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606;  /* R6 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505;  /* R5 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404;  /* R4 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303;  /* R3 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202;  /* R2 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101;  /* 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 )
{
    /* We want the task to start in thumb mode. */
    *pxTopOfStack |= portTHUMB_MODE_BIT;
}

pxTopOfStack-;

/* Some optimisation levels use the stack differently to others.  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.  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.  The offset is added to make the return address appear
as it would within an IRQ ISR. */
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;      
pxTopOfStack-;

pxTempTOS = pxTopOfStack;
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa;  /* R14 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212;  /* R12 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;  /* R11 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010;  /* R10 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909;  /* R9 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808;  /* R8 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707;  /* R7 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606;  /* R6 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505;  /* R5 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404;  /* R4 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303;  /* R3 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202;  /* R2 */
pxTopOfStack-;
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101;  /* 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 )
{
    /* We want the task to start in thumb mode. */
    *pxTopOfStack |= portTHUMB_MODE_BIT;
}

pxTopOfStack-;

/* Some optimisation levels use the stack differently to others.  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