以下转载自安富莱电子: http://forum.armfly.com/forum.php

调度锁
调度锁就是 RTOS 提供的调度器开关函数,如果某个任务调用了调度锁开关函数,处于调度锁开和调
度锁关之间的代码在执行期间是不会被高优先级的任务抢占的,即任务调度被禁止。这一点要跟临界段的
作用区分开,调度锁只是禁止了任务调度,并没有关闭任何中断,中断还是正常执行的。而临界段进行了
开关中断操作。

中断锁
中断锁就是 RTOS 提供的开关中断函数,FreeRTOS 没有专门的中断锁函数,使用 前一节里面介
绍的中断服务程序临界段处理函数就可以实现同样效果。

任务锁
简单的说,为了防止当前任务的执行被其它高优先级的任务打断而提供的锁机制就是任务锁。
FreeRTOS 也没有专门的任务锁函数,但是使用 FreeRTOS 现有的功能有两种实现方法:
 通过给调度器加锁实现
利用 FreeRTOS 的调度锁功能给调度器加锁的话,将关闭任务切换功能,从而高优先级任务也就无法
抢占低优先级任务的执行,同时高优先级任务也是无法向低优先级任务切换的。 另外特别注意,调度
锁只是禁止了调度器工作,并没有关闭任何中断。
 通过关闭任务切换中断 PendSV 和系统时钟节拍中断 Systick

利用 FreeRTOS 的任务代码临界段处理函数就可以关闭 PendSV 中断和 Systick 中断。因为进入临界
段前,操作寄存器 basepri 关闭了所有小于等于宏定义
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 所定义的中断优先级(实现任务切换功能
的 PendSV 中断和滴答定时器中断是最低优先级中断,所以也是被关闭的),这样低优先级任务在执
行临界段代码期间是不会被高优先级任务打断的,从而就实现了任务锁的效果。

FreeRTOS 调度锁开启
使用如下函数可以实现 FreeRTOS 的调度锁开启:
 vTaskSuspendAll()

函数原型:
void vTaskSuspendAll( void );
函数描述:
函数 vTaskSuspendAll 用于实现 FreeRTOS 调度锁开启。
使用这个函数要注意以下问题:
1. 调度锁函数只是禁止了任务调度,并没有关闭任何中断。
2. 调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 一定要成对使用。

3. 切不可在调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 之间调用任何会引起任务切换的 API,比如 vTaskDelayUntil、 vTaskDelay、 xQueueSend 等。 
FreeRTOS 调度锁关闭
使用如下函数可以实现 FreeRTOS 的调度锁关闭:
 xTaskResumeAll ()

函数原型:
BaseType_t xTaskResumeAll(void)
函数描述:
函数 xTaskResumeAll 用于实现 FreeRTOS 调度锁关闭
 调度锁关闭后,如果需要任务切换,此函数返回 pdTRUE,否则返回 pdFALSE。
使用这个函数要注意以下问题:
1. 调度锁函数只是禁止了任务调度,并没有关闭任何中断。
2. 调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 一定要成对使用。
3. 切不可在调度锁开启函数 vTaskSuspendAll 和调度锁关闭函数 xTaskResumeAll 之间调用任何会引起任务切换的 API,比如 vTaskDelayUntil、 vTaskDelay、 xQueueSend 等。

eg:

void vTaskLed1(void *pvParameters)
{
/* 任务都是一个无限,不能返回 */
while()
{
vTaskSuspendAll(); /* 开启调度锁 */
printf("任务vTaskLed1正在运行\r\n");
if(!xTaskResumeAll()) /* 关闭调度锁,如果需要任务切换,此函数返回pdTRUE,否则返回pdFALSE */
{
taskYIELD ();
}
LED3_ON;
/* 阻塞延时,单位ms */
vTaskDelay( );
LED3_OFF;
vTaskDelay( );
}
}

这里需要注意红色部分,就是关闭调度锁的时候,加上了一个if判断,这个判断的目的是什么呢?是不是多余的呢?开启和关闭调度锁不是像下面这样就可的吗:

那为什么官方的demo中有这样一个判断?

先看关闭调度锁返回值的解释:

如果恢复调度造成了上下文切换,返回pdTRUE,否则返回pdFLASE。这里

要满足if,证明没有上下文切换,然后调用taskYIELD(),这个函数是强制上下文转换:

这也就证明了,如果调用xTaskResumeAll()没有进行上下文切换,我们将强制进行上下文切换,如果进行了上下文切换,这个if判断是多余的。官方解释:

另外需要注意,强制进行上下文切换,不代表本任务中xTaskResumeAll()后面的语句就不执行了,这里led灯的亮灭依旧会执行,(除非有高优先级任务打断此刻的任务了)只是调度器重新获得了调度权限,可以在多个任务间进行调度和切换。还有注意调度锁,不能锁中断。

我之前还想,要是在一个低优先级的任务中运行一段不想被高优级打断的程序时freertos怎么做,现在知道了,调度锁和临界段。

实验效果:

FreeRTOS 调度锁,任务锁和中断锁的更多相关文章

  1. Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁

    (1)synchronized 是互斥锁: (2)ReentrantLock 顾名思义 :可重入锁 (3)ReadWriteLock :读写锁 读写锁特点: a)多个读者可以同时进行读b)写者必须互斥 ...

  2. RTX——第11章 临界段,任务锁和中断锁

    以下内容转载自安富莱电子: http://forum.armfly.com/forum.php 临界段代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被 ...

  3. RTX临界段,中断锁与任务锁

    临界段         代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断.为确保临界段代码的执行不被中断,在进入临界段之前须关中断,而临界段代码执行完毕后,要立即开中断.    ...

  4. JAVA锁机制-可重入锁,可中断锁,公平锁,读写锁,自旋锁,

    如果需要查看具体的synchronized和lock的实现原理,请参考:解决多线程安全问题-无非两个方法synchronized和lock 具体原理(百度) 在并发编程中,经常遇到多个线程访问同一个 ...

  5. ReentrantLock可中断锁和synchronized区别

    ReentrantLock中的lockInterruptibly()方法使得线程可以在被阻塞时响应中断,比如一个线程t1通过lockInterruptibly()方法获取到一个可重入锁,并执行一个长时 ...

  6. [数据库锁机制] 深入理解乐观锁、悲观锁以及CAS乐观锁的实现机制原理分析

    前言: 在并发访问情况下,可能会出现脏读.不可重复读和幻读等读现象,为了应对这些问题,主流数据库都提供了锁机制,并引入了事务隔离级别的概念.数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务 ...

  7. v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  8. v80.01 鸿蒙内核源码分析(内核态锁篇) | 如何实现快锁Futex(下) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(内核态锁篇) | 如何实现快锁Futex(下) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  9. Java多线程系列--“JUC锁”05之 非公平锁

    概要 前面两章分析了"公平锁的获取和释放机制",这一章开始对“非公平锁”的获取锁/释放锁的过程进行分析.内容包括:参考代码获取非公平锁(基于JDK1.7.0_40)释放非公平锁(基 ...

随机推荐

  1. 关于OGRE与OSG的简单比较【转】

    关于OGRE与OSG的简单比较 林乃养 lnychina{at}gmail.com 浙江大学CAD&CG实验室 2010年3月27日 1 前言 我曾经细致阅读过OGRE和OSG官方提供的文档, ...

  2. 高性能WEB开发:重排与重绘

    DOM编程可能最耗时的地方,重排和重绘. 1.什么是重排和重绘 浏览器下载完页面中的所有组件——HTML标记.JavaScript.CSS.图片之后会解析生成两个内部数据结构——DOM树和渲染树. D ...

  3. 【C/C++】Linux C,关于刷新printf输出问题

    直接描述吧:int i = 0;while(1){printf("now i = %d\r", i);fflush(stdout);i++;sleep(1);}我想在输出中不仅仅是 ...

  4. 【饿了么】—— Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(三)

    前言:接着上一篇项目总结,这一篇是学习过程记录的最后一篇,这里会梳理:评论组件.商家组件.优化.打包.相关资料链接.项目github地址:https://github.com/66Web/ljq_el ...

  5. Atlassian官方合作伙伴

    Atlassian官方合作伙伴 http://atlassian.csdn.net/m/btc/atlassian/index

  6. Linux下全局符号覆盖问题

    在windows上,默认情况下,动态库中的符号都是对外隐藏的,除非你显示的指出要导出哪些符号,否则外界是看不到的.但是linux下情况刚好相反,对静态变量和全局变量,linux下so里面的符号对外可见 ...

  7. Unity3D 播放视频

    http://blog.csdn.net/jbjwpzyl3611421/article/details/12780625 导入: 影片纹理是通过Apple QuickTime导入的(支持.mov, ...

  8. 〖Linux〗不知谁写的,很实用的Linux命令

    第一部分 . sudo 运行上一条命令 sudo !! . HTTP方式共享当前目录 python -m SimpleHTTPServer . vim保存一个root用户文件 :w !sudo tee ...

  9. dubbo初探(转载)

    1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...

  10. 【TP3.2与TP5.0区别】

    Tp3.2 和 Tp5.0之间的区别   5.0版本和之前版本的差异较大,本篇对熟悉3.2版本的用户给出了一些5.0的主要区别. URL和路由 5.0的URL访问不再支持普通URL模式,路由也不支持正 ...