Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT




Loading

FreeRTOS 8.0.1 Prefetch Abort on LPC2129 after patching portSAVE, portRESTORE to avoid invalid literal constant

Posted by jsiegel2 on July 1, 2014

Hi,

I recently upgraded from FreeRTOS 6.1.1 to FreeRTOS 8.0.1. In FreeRTOS 6.1.1, I had issues with the "invalid literal constant: pool needs to be closer" error, which was solved by applying a "patch" to portRESTORE and portSAVE. When I use the same code in FreeRTOS 8.0.1, the code compiles fine - but I get a prefetch abort.

I've never used assembly so I have no clue what's going on here! Without JTAG, how can I troubleshoot this? Is there an obvious fix?

The patched code is here:

~~~~~~

define portRESTORE_CONTEXT()

{

extern volatile void * volatile pxCurrentTCB;

extern volatile unsigned portLONG ulCriticalNesting;

                                                                    \

asm volatile (                                                      \

/* Set the LR to the task stack. */                                 \

"LDR    R0, 1f      /* =pxCurrentTCB */                     \n\t"   \

"LDR    R0, [R0]                                            \n\t"   \

"LDR    LR, [R0]                                            \n\t"   \

                                                                    \

/* The critical nesting depth is the first item on the stack. */    \

/* Load it into the ulCriticalNesting variable. */                  \

"LDR    R0, 2f      /* =ulCriticalNesting */                \n\t"   \

"LDMFD  LR!, {R1}                                           \n\t"   \

"STR    R1, [R0]                                            \n\t"   \

                                                                    \

/* Get the SPSR from the stack. */                                  \

"LDMFD  LR!, {R0}                                           \n\t"   \

"MSR    SPSR, R0                                            \n\t"   \

                                                                    \

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

"LDMFD  LR, {R0-R14}^                                       \n\t"   \

"NOP                                                        \n\t"   \

                                                                    \

/* Restore the return address. */                                   \

"LDR    LR, [LR, #+60]                                      \n\t"   \

                                                                    \

/* And return - correcting the offset in the LR to obtain the */    \

/* correct address. */                                              \

"SUBS   PC, LR, #4                                          \n\t"   \

                                                                    \

/* Place the pool behind the code. This is never reached. */        \

"1: .word  pxCurrentTCB                                     \n\t"   \

"2: .word  ulCriticalNesting                                \n\t"   \

);                                                                  \

( void ) ulCriticalNesting;                                         \

( void ) pxCurrentTCB;                                              \

}

/-----------------------------------------------------------/

define portSAVE_CONTEXT()

{

extern volatile void * volatile pxCurrentTCB;

extern volatile unsigned portLONG ulCriticalNesting;

                                                                    \

asm volatile (                                                      \

"b      3f              /* skip data */                     \n\t"   \

"1: .word  pxCurrentTCB                                     \n\t"   \

"2: .word  ulCriticalNesting                                \n\t"   \

"3:                                                         \n\t"   \

/* Push R0 as we are going to use the register. */                  \

"STMDB  SP!, {R0}                                           \n\t"   \

                                                                    \

/* Set R0 to point to the task stack pointer. */                    \

"STMDB  SP,{SP}^                                            \n\t"   \

"NOP                                                        \n\t"   \

"SUB    SP, SP, #4                                          \n\t"   \

"LDMIA  SP!,{R0}                                            \n\t"   \

                                                                    \

/* Push the return address onto the stack. */                       \

"STMDB  R0!, {LR}                                           \n\t"   \

                                                                    \

/* Now we have saved LR we can use it instead of R0. */             \

"MOV    LR, R0                                              \n\t"   \

                                                                    \

/* Pop R0 so we can save it onto the system mode stack. */          \

"LDMIA  SP!, {R0}                                           \n\t"   \

                                                                    \

/* Push all the system mode registers onto the task stack. */       \

"STMDB  LR,{R0-LR}^                                         \n\t"   \

"NOP                                                        \n\t"   \

"SUB    LR, LR, #60                                         \n\t"   \

                                                                    \

/* Push the SPSR onto the task stack. */                            \

"MRS    R0, SPSR                                            \n\t"   \

"STMDB  LR!, {R0}                                           \n\t"   \

                                                                    \

"LDR    R0, 2b          /* =ulCriticalNesting */            \n\t"   \

"LDR    R0, [R0]                                            \n\t"   \

"STMDB  LR!, {R0}                                           \n\t"   \

                                                                    \

/* Store the new top of stack for the task. */                      \

"LDR    R0, 1b          /* =pxCurrentTCB */                 \n\t"   \

"LDR    R0, [R0]                                            \n\t"   \

"STR    LR, [R0]                                            \n\t"   \

);                                                                  \

( void ) ulCriticalNesting;                                         \

( void ) pxCurrentTCB;                                              \

}

~~~~~~

Instead of:

~~~~~~

define portRESTORE_CONTEXT()

{

extern volatile void * volatile pxCurrentTCB;

extern volatile uint32_t ulCriticalNesting;

																	\

/* Set the LR to the task stack. */									\

__asm volatile (													\

"LDR		R0, =pxCurrentTCB								\n\t"	\

"LDR		R0, [R0]										\n\t"	\

"LDR		LR, [R0]										\n\t"	\

																	\

/* The critical nesting depth is the first item on the stack. */	\

/* Load it into the ulCriticalNesting variable. */					\

"LDR		R0, =ulCriticalNesting							\n\t"	\

"LDMFD	LR!, {R1}											\n\t"	\

"STR		R1, [R0]										\n\t"	\

																	\

/* Get the SPSR from the stack. */									\

"LDMFD	LR!, {R0}											\n\t"	\

"MSR		SPSR, R0										\n\t"	\

																	\

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

"LDMFD	LR, {R0-R14}^										\n\t"	\

"NOP														\n\t"	\

																	\

/* Restore the return address. */									\

"LDR		LR, [LR, #+60]									\n\t"	\

																	\

/* And return - correcting the offset in the LR to obtain the */	\

/* correct address. */												\

"SUBS	PC, LR, #4											\n\t"	\

);																	\

( void ) ulCriticalNesting;											\

( void ) pxCurrentTCB;												\

}

/-----------------------------------------------------------/

define portSAVE_CONTEXT()

{

extern volatile void * volatile pxCurrentTCB;

extern volatile uint32_t ulCriticalNesting;

																	\

/* Push R0 as we are going to use the register. */					\

__asm volatile (													\

"STMDB	SP!, {R0}											\n\t"	\

																	\

/* Set R0 to point to the task stack pointer. */					\

"STMDB	SP,{SP}^											\n\t"	\

"NOP														\n\t"	\

"SUB	SP, SP, #4											\n\t"	\

"LDMIA	SP!,{R0}											\n\t"	\

																	\

/* Push the return address onto the stack. */						\

"STMDB	R0!, {LR}											\n\t"	\

																	\

/* Now we have saved LR we can use it instead of R0. */				\

"MOV	LR, R0												\n\t"	\

																	\

/* Pop R0 so we can save it onto the system mode stack. */			\

"LDMIA	SP!, {R0}											\n\t"	\

																	\

/* Push all the system mode registers onto the task stack. */		\

"STMDB	LR,{R0-LR}^											\n\t"	\

"NOP														\n\t"	\

"SUB	LR, LR, #60											\n\t"	\

																	\

/* Push the SPSR onto the task stack. */							\

"MRS	R0, SPSR											\n\t"	\

"STMDB	LR!, {R0}											\n\t"	\

																	\

"LDR	R0, =ulCriticalNesting								\n\t"	\

"LDR	R0, [R0]											\n\t"	\

"STMDB	LR!, {R0}											\n\t"	\

																	\

/* Store the new top of stack for the task. */						\

"LDR	R0, =pxCurrentTCB									\n\t"	\

"LDR	R0, [R0]											\n\t"	\

"STR	LR, [R0]											\n\t"	\

);																	\

( void ) ulCriticalNesting;											\

( void ) pxCurrentTCB;												\

}

~~~~~~


FreeRTOS 8.0.1 Prefetch Abort on LPC2129 after patching portSAVE, portRESTORE to avoid invalid literal constant

Posted by edwards3 on July 1, 2014

I think you have done sort of the right thing in loading the constant addresses from close b memory, but normally the constants would go at the end. Something like

__asm volatile ( LDR R0, _CurrentTCB LDR R0, [R0] LDR LR, [R0]

/* etc. */

/* The rest of the Asm here, then at the end, define the constants / _CurrentTCB: .word pxCurrentTCB / Other constants here. */ }

The syntax might not be quite right but you see the idea. Having the consts at the end means you don't have to do the jumps so won't end up on a bad alignment.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS