PendSV

先了解下如何使用PendSV异常。(为何要使用PendSV而不是其他的异常,请参考《cortex-M3权威指南》)

 

PendSV异常

 

​ PendSV,即可悬起的系统调用,OS可以利用它缓期执行一个异常,直到其它重要的任务完成后才执行操作。触发PendSV只需往NVIC的PendSV悬起寄存器的第28为置1即可;其典型用于上下文切换。

1,如何设定PendSV优先级?

NVIC_SYSPRI14 EQU 0xE000ED22

NVIC_PENDSV_PRI EQU 0xFF

    LDR R0, =NVIC_SYSPRI14 LDR R1, =NVIC_PENDSV_PRI

    STRB R1, [R0]

2,如何触发PendSV异常?

往ICSR第28位写1,即可将PendSV异常挂起。若是当前没有高优先级中断产生,那么程序将会进入PendSV handler

NVIC_INT_CTRL EQU 0xE000ED04

NVIC_PENDSVSET EQU 0x10000000

 

LDR R0, =NVIC_INT_CTRL

LDR R1, =NVIC_PENDSVSET

STR R1, [R0]




触发PendSV中断异常。
复制代码

#defineNVIC_INT_CTRL 0xE000Ed04 //PendSV中断控制器地址 #defineNVIC_PENDSV_SET 0x10000000 //PendSV触发的值 #defineNVIC_SYSPRI2 0xE000Ed22 //PendSV优先级控制地址 #defineNVIC_PENDSV_PRI 0x000000ff //PendSV设置为最低优先值 #defineMEM32(addr) *(volatile unsigned long *)(addr) #defineMEM8(addr) *(volatile unsigned char *)(addr) // 触发PendSV中断异常 void trigger_PendSV(void) { MEM32(NVIC_INT_CTRL) = NVIC_PENDSV_SET;//触发PendSV MEM8(NVIC_SYSPRI2) =NVIC_PENDSV_PRI; //设置PendSV优先级 }
复制代码

CPU何时响应PendSV异常

我们都知道,「高优先级的中断会打断低优先级的中断」,这也是系统实时性的一个重要保障,所以就引入了一个问题:

相比起GPIO中断、定时器中断、串口中断这些外部中断,PendSV异常的优先级更高呢?还是更低呢?

想象这样一种情况:

① CPU正在开心的运行着任务1……

② 此时你按下了按键,产生了一个GPIO中断,CPU收到后马上跑去执行中断处理函数……

③ 处理过程中,此时系统产生了一个PendSV异常,CPU收到后,嘲讽了一句:“我就是从普通任务跑来处理中断的,还没处理完,现在又让我执行下一个普通任务,脑子抽风了?”,说完继续处理中断……

所以说,无论任务的优先级有多高,它都没有中断高,「系统的PendSV异常优先级必须设为最低的」,以避免在外部中断服务函数中产生任务切换。

设置PendSV异常优先级的寄存器如下,值可以为0-255:

tos中在启动调度时设定pendsv异常的优先级,源码如下:

NVIC_SYSPRI14   EQU     0xE000ED22
NVIC_PENDSV_PRI EQU     0xFF

同样,设置pendSV异常优先级为最低的汇编代码如下:

; set pendsv priority lowest
; otherwise trigger pendsv in port_irq_context_switch will cause a context switch in irq
; that would be a disaster
MOV32   R0, NVIC_SYSPRI14
MOV32   R1, NVIC_PENDSV_PRI
STRB    R1, [R0]







进入PendSV ISR时,cortex-M3做了什么?

1,入栈。会有8个寄存器自动入栈。入栈内容及顺序如下:

在步骤一中,我们已经设置了PSP,那这8个寄存器就会自动入栈到PSP所指地址处。

2,取向量。找到PendSV ISR的入口地址,这样就能跳到ISR了。,

3,更新寄存器内容

做完这三步后,程序就进入ISR了。

进入ISR前,我们已经完成了步骤一,cortex-M3已经帮我们完成了步骤二的一部分,剩下的需要我们手动完成。

 

进入OS前的两步之PendSV(任务切换)

 

RTOS内功修炼记(二)—— 优先级抢占式调度到底是怎么回事?

 

posted on   tycoon3  阅读(1188)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 三行代码完成国际化适配,妙~啊~
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
历史上的今天:
2020-02-15 EVPN&OpenFlow方案--VXLAN的控制平面

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示