5.11. Setting up multiple stacks

To implement multiple stacks, the application must take these actions:

If the privilege of Thread mode is changed from privileged to user, only another ISR, such as SVCall, can change the privilege back from user to privileged.

The stack in Thread mode can be changed from main to process or from process to main, but doing so affects its access to the local variables of the thread. It is better to have another ISR change the stack used in Thread mode. The following shows an example boot sequence:

  1. Call setup routine to:

    1. Set up other stacks using MSR.

    2. Enable the MPU to support base regions, if any.

    3. Invoke all boot routines.

    4. Return from setup routine.

  2. Change Thread mode to unprivileged.

  3. Use SVC to invoke the kernel. Then the kernel:

    1. Starts threads.

    2. Uses MRS to read the SP for the current user thread and save it in its TCB.

    3. Uses MSR to set the SP for the next thread. This is usually SP_process.

    4. Sets up the MPU for the newly current thread, if necessary.

    5. Returns into the newly current thread.

Example 5.4 shows a modification to the EXC_RETURN value in the ISR to return using PSP.

Example 5.4. Modification to the EXC_RETURN value in the ISR

; First time use of PSP, run from a Handler with RETTOBASE == 1    LDR r0, PSPValue       ; acquire value for new Process stack  MSR PSP, r0            ; set Process stack value  ORR lr, lr, #4         ; change EXC_RETURN for return on PSP  BX lr                  ; return from Handler to Thread

Example 5.5 shows how to implement a simple context switcher after the switch to Thread on PSP.

Example 5.5. Implement a simple context switcher

 ; Example Context Switch (Assumes Thread is already on PSP) 	MRS r12, PSP           							; Recover PSP into R12  	STMDB r12!, {r4-r11, LR}   							; Push non-stack registers  	LDR r0, =OldPSPValue 		 					; Get pointer to old Thread Control Block
 	STR r12, [r0] 							; Store SP into Thread Control Block
	LDR r0, =NewPSPValue   							; Get pointer to new Thread Control Block  	LDR r12, [r0] 							; Acquire new Process SP
	LDMIA r12!, {r4-r11, LR}   							; Restore non-stacked registers  	MSR PSP, r12          					 		; Set PSP to R12 	BX lr                  							; Return back to Thread

Note

In Example 5.4 and Example 5.5, the only time the decision to move Thread from MSP to PSP can be made, or the non-stacked registers can be guaranteed not to have been modified by a stacked Handler, is when there is only one active ISR/Handler.

Copyright © 2005, 2006 ARM Limited. All rights reserved.ARM DDI 0337E
Non-Confidential