Search code examples
cortex-mucos

On the cortex-m3 platform, why does UCOS-III not use SVC to perform pendsv?


Recently, I am reading the source code of UCOS-III, and I have an question about UCOS-III's task switching when it running on the Cortex-M3 platform. It use PendSV for task switching by directly writing register SCB_ICSR(Interrupt control and state register), but accessing register SCB_ICSR Requires privilege operation level. This means that the processor is runing in the process mode at privilege operation level without exceptions and interrupts, which I don't think it's safe. Why does UCOS-III not use SVC to perform pendsv? Is it a matter of efficiency? Could somebody please explain this for me? Thanks.

Background: Software:UCOS-III

Hardware:Cortex-M3(STM32F103)

Code:

.thumb_func
OSStartHighRdy:
LDR     R0, =NVIC_SYSPRI14                                  @ Set the PendSV 
exception priority
LDR     R1, =NVIC_PENDSV_PRI
STRB    R1, [R0]

MOVS    R0, #0                                              @ Set the PSP to 0 for initial context switch call
MSR     PSP, R0

LDR     R0, =OS_CPU_ExceptStkBase                           @ Initialize the MSP to the OS_CPU_ExceptStkBase
LDR     R1, [R0]
MSR     MSP, R1

LDR     R0, =NVIC_INT_CTRL                                  @ Trigger the PendSV exception (causes context switch)
LDR     R1, =NVIC_PENDSVSET
STR     R1, [R0]

CPSIE   I                                                   @ Enable interrupts at processor level

I think this method is better: Cortex-M3 task switch using SVC and Pensv

  1. Task A calls SVC for task switching (for example, waiting for some work to complete).
  2. The OS receives the request, prepares for context switching, and pends the PendSV exception.
  3. When the CPU exits SVC, it enters PendSV immediately and does the context switch.
  4. When PendSV finishes and returns to Thread level, it executes Task B.
  5. An interrupt occurs and the interrupt handler is entered.
  6. While running the interrupt handler routine, a SYSTICK exception (for OS tick) takes place.
  7. The OS carries out the essential operation, then pends the PendSV exception and gets ready for the context switch.
  8. When the SYSTICK exception exits, it returns to the interrupt service routine.
  9. When the interrupt service routine completes, the PendSV starts and does the actual context switch operations.
  10. When PendSV is complete, the program returns to Thread level; this time it returns to Task A and continues the processing.

Solution

  • Unless you are using the MPU extensions there really does not make that much difference between running in user or privileged mode. Yes it is a bit safer running in user mode as you cannot modify all the registers, but you then have to provide an SVC call to be able to raise the privilege and have the ability to create tasks that are either user mode or privileged mode. I expect this is provided when you have the MPU extensions.

    I don't know UCOS-III but I would assume that all tasks are running privileged as do most Cortex-M RTOS, unless they support the MPU.