Raspberry Pi port .. corrupting a register

ldb wrote on Saturday, November 17, 2018:

I have an issue that randomly if I give it long enough I am corrupting a register on the context switch. Almost every Pi port out there uses the same macro for store and restore and every implementation I have tested does it so I would say it’s the save and restore macro.

Now I am quite familiar with the context switches on the Pi I have done them on Xinu and XV6 but FreeRTOS does them differently I think because it tries to make the Pi look like a an old microcontroller. The macros themselves are fine but they play with “ulCriticalNesting” which I am trying to understand. I am guessing it is a re-entrancy count but the question is what does it do in the system, as it seems to be it that is messing things up.

The other part of the question is the Pi has it’s own stack for Irq (Irq Mode) and Tasks (Sys mode) the whole use of the stacks in the TCB is completely unneccessary and just causing more problems than it’s worth. Have you got other processor implementations that don’t use them and as such is there a formal way like a config switch to turn them off … AKA I will do my own task stacks thanks.

ldb wrote on Saturday, November 17, 2018:

It’s okay I found the problem by looking again at the Xinu code

There is a key bit you have to do which is to square the stack back up to align 8

/* According to the document "Procedure Call Standard for the ARM
	 * Architecture", the stack pointer is 4-byte aligned at all times, but
	 * it must be 8-byte aligned when calling an externally visible
	 * function.  This is important because this code is reached from an IRQ
	 * and therefore the stack currently may only be 4-byte aligned.  If
	 * this is the case, the stack must be padded to an 8-byte boundary
	 * before calling dispatch().  */
	and r4, sp, #4
	sub sp, sp, r4

The portSAVE_CONTEXT() macro that everyone is using doesn’t do it and then a call is made to a c function irqHandler();

void vFreeRTOS_ISR( void ) 

So at some point when a task is running you get an interrupt and the stack is align4 not align 8 and the C code mashes up your registers.

Added the change and it’s been running for an hour now without a corruption.