临界区保护

2020-03-01 11:56发布

跨度稍微大一点,现在我们来讨论一个关于共享资源的问题。例如在程序中定义了一个全局数组变量delaytimes[] 这个全局变量除了运行的任务可以访问,中断异常处理也可以访问,那么问题来了,任务1先对delaytimes[] 进行读操作,在任务1读的过程中Systick触发了任务切换,这个时候切换到了任务2,恰巧任务2delaytimes[] 写操作,改变了delaytimes[]的一部分内容,当任务再切换回任务1的时候,接着读取delaytimes[] 中的内容,这样后面再读取的数据就不确定是否正确了。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
dingbo95
1楼-- · 2020-03-01 12:28
具体见下图

647985d0dcf51e735f.png (11.62 KB, 下载次数: 0)

下载附件  保存到相册

2019-6-22 14:48 上传

dingbo95
2楼-- · 2020-03-01 18:21
为了解决任务和任务,任务和中断之间共享资源的问题,我们引入了临界区保护,当要访问共享资源时,该代码段先进入临界区保护,操作完后退出临界区保护。其目的是在临界区保护段不会受到任何打扰,任务不会被切换。那么临界区保护是如何做到的呢?简单的说就是关中断,开中断的操作,进入临界区时关中断不再进行任务切换,退出临界区保护时恢复中断。遇到一个很聪明的学生,他提出了一个关于中断嵌套的问题:如果任务1里面某一段区域先对共享资源1访问,然后再访问资源1操作里又对资源2访问,那简单的关中断,开中断就不再奏效了。
dingbo95
3楼-- · 2020-03-01 18:51
 精彩回答 2  元偷偷看……
dingbo95
4楼-- · 2020-03-01 21:26
特提出了一种解决方式,即是在关中断的时候,保存相关参数,在退出临界保护时用此参数来恢复中断。

396135d0dcfc31c351.png (21.75 KB, 下载次数: 0)

下载附件  保存到相册

2019-6-22 14:50 上传

dingbo95
5楼-- · 2020-03-01 23:37
编写进入临界区和退出临界区函数,具体代码如下,后续在需要的地方添加临界区保护代码来确保整个共享资源被正确的读取和写入。
//进入临界保护区
uint32_t TaskEnterCritical()
{
   uint32_t primask;
         primask = __get_PRIMASK();
         __disable_irq();  //关中断
        return primask;
}
//退出临界保护区
void TaskExitCritical(uint32_t status)
{
  __set_PRIMASK(status);
}
dingbo95
6楼-- · 2020-03-02 05:19
本次临界区保护比较简单,大家明白原理即可。

一周热门 更多>