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

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 */                     nt"   

"LDR    R0, [R0]                                            nt"   

"LDR    LR, [R0]                                            nt"   

                                                                    

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

/* Load it into the ulCriticalNesting variable. */                  

"LDR    R0, 2f      /* =ulCriticalNesting */                nt"   

"LDMFD  LR!, {R1}                                           nt"   

"STR    R1, [R0]                                            nt"   

                                                                    

/* Get the SPSR from the stack. */                                  

"LDMFD  LR!, {R0}                                           nt"   

"MSR    SPSR, R0                                            nt"   

                                                                    

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

"LDMFD  LR, {R0-R14}^                                       nt"   

"NOP                                                        nt"   

                                                                    

/* Restore the return address. */                                   

"LDR    LR, [LR, #+60]                                      nt"   

                                                                    

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

/* correct address. */                                              

"SUBS   PC, LR, #4                                          nt"   

                                                                    

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

"1: .word  pxCurrentTCB                                     nt"   

"2: .word  ulCriticalNesting                                nt"   

);                                                                  

( void ) ulCriticalNesting;                                         

( void ) pxCurrentTCB;                                              
} /———————————————————–/

define portSAVE_CONTEXT()

{ extern volatile void * volatile pxCurrentTCB; extern volatile unsigned portLONG ulCriticalNesting;
                                                                    

asm volatile (                                                      

"b      3f              /* skip data */                     nt"   

"1: .word  pxCurrentTCB                                     nt"   

"2: .word  ulCriticalNesting                                nt"   

"3:                                                         nt"   

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

"STMDB  SP!, {R0}                                           nt"   

                                                                    

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

"STMDB  SP,{SP}^                                            nt"   

"NOP                                                        nt"   

"SUB    SP, SP, #4                                          nt"   

"LDMIA  SP!,{R0}                                            nt"   

                                                                    

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

"STMDB  R0!, {LR}                                           nt"   

                                                                    

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

"MOV    LR, R0                                              nt"   

                                                                    

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

"LDMIA  SP!, {R0}                                           nt"   

                                                                    

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

"STMDB  LR,{R0-LR}^                                         nt"   

"NOP                                                        nt"   

"SUB    LR, LR, #60                                         nt"   

                                                                    

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

"MRS    R0, SPSR                                            nt"   

"STMDB  LR!, {R0}                                           nt"   

                                                                    

"LDR    R0, 2b          /* =ulCriticalNesting */            nt"   

"LDR    R0, [R0]                                            nt"   

"STMDB  LR!, {R0}                                           nt"   

                                                                    

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

"LDR    R0, 1b          /* =pxCurrentTCB */                 nt"   

"LDR    R0, [R0]                                            nt"   

"STR    LR, [R0]                                            nt"   

);                                                                  

( 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                               nt"   

"LDR        R0, [R0]                                        nt"   

"LDR        LR, [R0]                                        nt"   

                                                                    

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

/* Load it into the ulCriticalNesting variable. */                  

"LDR        R0, =ulCriticalNesting                          nt"   

"LDMFD  LR!, {R1}                                           nt"   

"STR        R1, [R0]                                        nt"   

                                                                    

/* Get the SPSR from the stack. */                                  

"LDMFD  LR!, {R0}                                           nt"   

"MSR        SPSR, R0                                        nt"   

                                                                    

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

"LDMFD  LR, {R0-R14}^                                       nt"   

"NOP                                                        nt"   

                                                                    

/* Restore the return address. */                                   

"LDR        LR, [LR, #+60]                                  nt"   

                                                                    

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

/* correct address. */                                              

"SUBS   PC, LR, #4                                          nt"   

);                                                                  

( 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}                                           nt"   

                                                                    

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

"STMDB  SP,{SP}^                                            nt"   

"NOP                                                        nt"   

"SUB    SP, SP, #4                                          nt"   

"LDMIA  SP!,{R0}                                            nt"   

                                                                    

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

"STMDB  R0!, {LR}                                           nt"   

                                                                    

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

"MOV    LR, R0                                              nt"   

                                                                    

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

"LDMIA  SP!, {R0}                                           nt"   

                                                                    

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

"STMDB  LR,{R0-LR}^                                         nt"   

"NOP                                                        nt"   

"SUB    LR, LR, #60                                         nt"   

                                                                    

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

"MRS    R0, SPSR                                            nt"   

"STMDB  LR!, {R0}                                           nt"   

                                                                    

"LDR    R0, =ulCriticalNesting                              nt"   

"LDR    R0, [R0]                                            nt"   

"STMDB  LR!, {R0}                                           nt"   

                                                                    

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

"LDR    R0, =pxCurrentTCB                                   nt"   

"LDR    R0, [R0]                                            nt"   

"STR    LR, [R0]                                            nt"   

);                                                                  

( void ) ulCriticalNesting;                                         

( void ) pxCurrentTCB;                                              
} ~~~~~~

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

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.