最近在看UCOS-III的源码,有一个关于UCOS-III在Cortex-M3平台上运行时的任务切换问题。它使用 PendSV 进行任务切换,直接写寄存器 SCB_ICSR(中断控制和状态寄存器),但访问寄存器 SCB_ICSR 需要特权操作级别。这意味着处理器在特权操作级别以进程模式运行,没有异常和中断,我认为这并不安全。为什么 UCOS-III 不使用 SVC 来执行 pendsv?是效率问题吗?有人可以为我解释一下吗?谢谢。
背景:软件:UCOS-III
硬件:Cortex-M3(STM32F103)
代码:
.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
我觉得这个方法比较好: Cortex-M3 task switch using SVC and Pensv
- 任务 A 调用 SVC 进行任务切换(例如,等待某些工作完成)。
- 操作系统接收请求,准备上下文切换,并挂起 PendSV 异常。
- 当 CPU 退出 SVC 时,它立即进入 PendSV 并进行上下文切换。
- 当 PendSV 完成并返回线程级别时,它执行任务 B。
- 发生中断并进入中断处理程序。
- 在运行中断处理程序例程时,会发生 SYSTICK 异常(针对 OS 滴答)。
- 操作系统执行基本操作,然后挂起 PendSV 异常并为上下文切换做好准备。
- 当 SYSTICK 异常退出时,它返回到中断服务程序。
- 当中断服务程序完成时,PendSV 启动并执行实际的上下文切换操作。
- 当 PendSV 完成后,程序返回到 Thread 级别;这次它返回到任务 A 并继续处理。