首页
|
新闻
|
新品
|
文库
|
方案
|
视频
|
下载
|
商城
|
开发板
|
数据中心
|
座谈新版
|
培训
|
工具
|
博客
|
论坛
|
百科
|
GEC
|
活动
|
主题月
|
电子展
注册
登录
论坛
博客
搜索
帮助
导航
默认风格
uchome
discuz6
GreenM
»
MCU 单片机技术
»
ARM
» 一步步写STM32 PendSV与堆栈操作
返回列表
回复
发帖
发新话题
发布投票
发布悬赏
发布辩论
发布活动
发布视频
发布商品
一步步写STM32 PendSV与堆栈操作
发短消息
加为好友
yuyang911220
当前离线
UID
1029342
帖子
9914
精华
0
积分
4959
阅读权限
90
在线时间
286 小时
注册时间
2014-5-22
最后登录
2017-7-24
论坛元老
UID
1029342
性别
男
1
#
打印
字体大小:
t
T
yuyang911220
发表于 2014-11-22 21:11
|
只看该作者
一步步写STM32 PendSV与堆栈操作
寄存器
,
优先级
,
手工
一、什么是PendSV
PendSV是可悬起异常,如果我们把它配置最低优先级,那么如果同时有多个异常被触发,它会在其他异常执行完毕后再执行,而且任何异常都可以中断它。更详细的内容在《Cortex-M3 权威指南》里有介绍,
下面我摘抄了
一段。
OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动 作。悬起 PendSV 的方法是:手工往 NVIC的 PendSV悬起寄存器中写 1。悬起后,如果优先级不够 高,则将缓期等待执行。
PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。例如,一个系统中有两个
就绪的任务,上下文切换被触发的场合可以是:
1、执行一个系统调用
2、系统滴答定时器(SYSTICK)中断,(轮转调度中需要)
让我们举个简单的例子来辅助理解。假设有这么一个系统,里面有两个就绪的任务,并且通过SysTick异常启动上下文切换。但若在产生 SysTick 异常时正在响应一个中断,则 SysTick异常会抢占其 ISR。在这种情况下,OS是不能执行上下文切换的,否则将使中断请求被延迟,而且在真实系统中延迟时间还往往不可预知——任何有一丁点实时要求的系统都决不能容忍这 种事。因此,在 CM3 中也是严禁没商量——如果 OS 在某中断活跃时尝试切入线程模式,将触犯用法fault异常。
为解决此问题,早期的 OS 大多会检测当前是否有中断在活跃中,只有在无任何中断需要响应 时,才执行上下文切换(切换期间无法响应中断)。然而,这种方法的弊端在于,它可以把任务切 换动作拖延很久(因为如果抢占了 IRQ,则本次 SysTick在执行后不得作上下文切换,只能等待下 一次SysTick异常),尤其是当某中断源的频率和SysTick异常的频率比较接近时,会发生“共振”, 使上下文切换迟迟不能进行。现在好了,PendSV来完美解决这个问题了。PendSV异常会自动延迟上下文切换的请求,直到 其它的 ISR都完成了处理后才放行。为实现这个机制,需要把 PendSV编程为最低优先级的异常。如果 OS检测到某 IRQ正在活动并且被 SysTick抢占,它将悬起一个 PendSV异常,以便缓期执行 上下文切换。
使用 PendSV 控制上下文切换个中事件的流水账记录如下:
1. 任务 A呼叫 SVC来请求任务切换(例如,等待某些工作完成)
2. OS接收到请求,做好上下文切换的准备,并且悬起一个 PendSV异常。
3. 当 CPU退出 SVC后,它立即进入 PendSV,从而执行上下文切换。
4. 当 PendSV执行完毕后,将返回到任务 B,同时进入线程模式。
5. 发生了一个中断,并且中断服务程序开始执行
6. 在 ISR执行过程中,发生 SysTick异常,并且抢占了该 ISR。
7. OS执行必要的操作,然后悬起 PendSV异常以作好上下文切换的准备。
8. 当 SysTick退出后,回到先前被抢占的 ISR中,ISR继续执行
9. ISR执行完毕并退出后,PendSV服务例程开始执行,并且在里面执行上下文切换
10. 当 PendSV执行完毕后,回到任务 A,同时系统再次进入线程模式。
。
我们在uCOS的PendSV的处理代码中可以看到:
[url=]
[/url]
OS_CPU_PendSVHandler CPSID I
;
关中断
;
保存上文
;
.......................
;
切换下文
CPSIE I
;
开中断
BX LR
;
异常返回
[url=]
[/url]
它在异常一开始就关闭了中端,结束时开启中断,中间的代码为
临界区代码
,即不可被中断的操作。PendSV异常是任务切换的堆栈部分的核心,由他来完成上下文切换。PendSV的操作也很简单,主要有设置优先级和触发异常两部分:
[url=]
[/url]
NVIC_INT_CTRL EQU 0xE000ED04
;
中断控制寄存器
NVIC_SYSPRI14 EQU 0xE000ED22
;
系统优先级寄存器(优先级14).
NVIC_PENDSV_PRI EQU 0xFF
;
PendSV优先级(最低).
NVIC_PENDSVSET EQU 0x10000000 ; PendSV触发值
;
设置PendSV的异常中断优先级
LDR R0, =NVIC_SYSPRI14 LDR R1, =NVIC_PENDSV_PRI STRB R1, [R0]
;
触发PendSV异常
LDR R0, =NVIC_INT_CTRL LDR R1, =NVIC_PENDSVSET
STR
R1, [R0][url=]
[/url]
收藏
分享
评分
继承事业,薪火相传
回复
引用
订阅
TOP
返回列表
电商论坛
Pine A64
资料下载
方案分享
FAQ
行业应用
消费电子
便携式设备
医疗电子
汽车电子
工业控制
热门技术
智能可穿戴
3D打印
智能家居
综合设计
示波器技术
存储器
电子制造
计算机和外设
软件开发
分立器件
传感器技术
无源元件
资料共享
PCB综合技术
综合技术交流
EDA
MCU 单片机技术
ST MCU
Freescale MCU
NXP MCU
新唐 MCU
MIPS
X86
ARM
PowerPC
DSP技术
嵌入式技术
FPGA/CPLD可编程逻辑
模拟电路
数字电路
富士通半导体FRAM 铁电存储器“免费样片”使用心得
电源与功率管理
LED技术
测试测量
通信技术
3G
无线技术
微波在线
综合交流区
职场驿站
活动专区
在线座谈交流区
紧缺人才培训课程交流区
意见和建议