OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4434|回复: 7

关于UCOSIII直接发布和延迟发布保护临界段代码的疑惑

[复制链接]

6

主题

20

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-5-25
在线时间
12 小时
发表于 2017-3-22 11:46:32 | 显示全部楼层 |阅读模式
5金钱
最近在看《嵌入式实时操作系统uC/OS-III》一书,想深入研究了一下UCOSIII,在中断管理的直接发布和延迟发布模块遇到了一个问题想不通,想请教一下各位前辈,还望不吝赐教:

直接发布和延迟发布中都有一个值得关注的话题,那就是临界代码段的保护,也就是保护处于OS_CRITICAL_ENTER与OS_CRITICAL_EXIT之间的代码,之间的代码是原子性质的、连续的、不可被打断的(比如从SD卡中读数据),直接发布采用关中断的方式进行保护,延迟发布采用调度器上锁的方式保护。我的疑惑如下:
void  AppTask(void *p_arg)
{
         ......                                       (1)
        OS_CRITICAL_ENTER();              (2)
        .......                                       (3)
        OS_CRITICAL_EXIT();                (4)
        ......                                        (5)
}
OS_CFG_ISR_POST_DEFERRED_EN = 0;
直接发布:上述(2)执行完毕后中断关闭----->假若:在(3)执行期间发生中断,结果是临界区代码不被打断;在(3)执行期间更高优先级的任务就绪,结果是发生任务调度(4)执行完毕                后,中断被开启并发生任务切换,期间发生中断则跳转执行中断函数。
               结果:如果在临界区(3)执行期间发生的是中断,则临界区代码不被打断,起到保护作用;如果是高优先级的任务就绪,发生任务切换,则临界区代码被打断

OS_CFG_ISR_POST_DEFERRED_EN = 1;
延迟发布:上述(2)执行完毕后调度器上锁,假设在(3)执行期间发生中断,结果临界区代码被打断转而执行中断函数;在(3)执行期间更高优先级的任务就绪,结果不会发生任务调度。
              结果:如果在临界区(3)执行期间发生的是中断,则临界区代码被打断,没有起到保护作用;如果是高优先级的任务就绪,发生任务切换,则临界区代码不被打断
上面的两种发布模式,分析的结果,好像都无法有效的保护临界区,请问一下我的分析哪里出问题了?

最佳答案

查看完整内容[请看2#楼]

这种方式的目的就是临界区不会影响到中断的发生。在这种目的下,临界区会被中断打断,但是前提是 1.中断处理不会与临界区的数据处理发生冲突。2.中断需要修改临界区处理的数据,只能发个消息给Intq task,在该task里面修改来保证不产生冲突。是的,这个原子性是靠这些处理技巧才能保证。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

头像被屏蔽

8

主题

95

帖子

0

精华

禁止发言

积分
349
金钱
349
注册时间
2016-12-8
在线时间
88 小时
发表于 2017-3-22 11:46:33 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

头像被屏蔽

8

主题

95

帖子

0

精华

禁止发言

积分
349
金钱
349
注册时间
2016-12-8
在线时间
88 小时
发表于 2017-3-22 14:38:52 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

6

主题

20

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-5-25
在线时间
12 小时
 楼主| 发表于 2017-3-22 14:55:59 | 显示全部楼层
charlefu 发表于 2017-3-22 14:38
这都翻译的是神马鬼。闭着眼睛把文档翻译一下就完了?问题是原文档这个情景描述和CRITICAL SECTION没关系啊 ...

你好,我觉得你分析的有道理,我也赞同,但是,我想弄明白的是,这两种方式怎么就保护临界段代码了?关中断的方式(OS_CFG_ISR_POST_DEFERRED_EN = 0)保护临界段代码我想通了,没有问题,因为既然OS_CRITICAL_ENTER()和OS_CRITICAL_EXIT()之间的代码是用户想要保护的,自然不会在这之间放入能够导致发起任务调度的OS服务函数,高优先级的任务即使就绪了也要再任务调度点处才能获得CPU使用权,所以直接发布的方式确实能保护临界段代码。可是延迟发布还是不对啊,OS_CFG_ISR_POST_DEFERRED_EN = 1时只是给调度器上锁,在(3)的位置发生中断的话,还是会被中断出去的呀,也就不能保证(3)的原子性了
回复

使用道具 举报

6

主题

20

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-5-25
在线时间
12 小时
 楼主| 发表于 2017-3-22 15:01:48 | 显示全部楼层
charlefu 发表于 2017-3-22 14:38
这都翻译的是神马鬼。闭着眼睛把文档翻译一下就完了?问题是原文档这个情景描述和CRITICAL SECTION没关系啊 ...

而且你说的“后者只是关闭了调度,所以只会被中断打断,打断完后由于调度被关闭,临界区的代码不会被更高优先级的线程打断”这句话,我想说的是,如果中断是在(3)的位置发生,立即打断,转去执行中断函数这个过程,只要转去执行中断函数不就是意味着破坏临界区了吗?这这地方又该如何理解?
回复

使用道具 举报

6

主题

20

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-5-25
在线时间
12 小时
 楼主| 发表于 2017-3-22 16:34:57 | 显示全部楼层
嗯嗯,谢谢你的讲解。那个我还是觉得不太对,想和你再探讨一下,你别介意。我举个例子嘛,假设上面的(3)正在为某个资源在外部内中申请一块内存,外部内存分配涉及FSMC的8080并口时序嘛,这期间突然来了个外部中断,如果使用延时发布OS_CFG_ISR_POST_DEFERRED_EN = 1这种方式,还是会中断出去的,中断执行完毕返回时,虽然会恢复退出中断之前CUP个寄存器保存在该任务堆栈中的数据,但是,已经错过FSMC的8080的并口时序,显然分配内存会失败的,也就是保护临界代码是没有实现的,这样的例子很多的啊,再比如读取SD卡的数据,因为使用SDIO协议或者SPI协议,也是有着时序的问题再里面,固然任务中断前的数据以及状态等参数可以从该任务的任务堆栈中恢复,时序是“不等人”的,,这个,你怎么看
回复

使用道具 举报

头像被屏蔽

8

主题

95

帖子

0

精华

禁止发言

积分
349
金钱
349
注册时间
2016-12-8
在线时间
88 小时
发表于 2017-3-22 16:42:48 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

6

主题

20

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2016-5-25
在线时间
12 小时
 楼主| 发表于 2017-3-23 10:59:20 | 显示全部楼层
charlefu 发表于 2017-3-22 16:42
临界区的目的大多还是保证数据读写的原子性,这种情况用我说的方式是可以保证的。而你这种情况,如果要选 ...

好的,谢谢你
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-13 08:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表