原文地址:http://www.cnblogs.com/god-of-death/p/6917837.html

1、二值信号量

就像一个标志位,事件产生置一,事件处理后直零

用于任务之间的同步,即一个任务 give token,另一个任务 take token

特别提醒:

V7.X版本中使用vSemaphoreCreateBinary函数,使用该函数创建的信号量初始值为“满”
V8.X版本以后版本中使用xSemaphoreCreateBinary函数,使用该函数创建的信号量初始值为“空”

2、计数信号量

事件产生加一,事件处理减一,减到零表示事件处理完毕

3、中断推迟处理

把一部分原本放在中断服务函数的程序放在中断外,减少中断服务函数运行时间

由于中断服务函数越短越好(处理时间越短越好),把关键处理放中断服务函数,其他放到外面,外面可以是一个任务(灵活性大,因为会用到二值信号量或计数信号量,需要为每个信号量创建一个任务,耗用资源多),也可以是定时器守护任务的回调函数xTimerPendFunctionCallFromISR()(定时器守护任务使用到一个命令队列,只要向队列发送信号就可以执行相应代码,所以可以实现“中断推迟处理”功能;只用到定时器守护任务这一个任务,节省资源,但建议回调函数执行时间短一些,否则影响其他定时器回调函数的执行周期)

4、任务通知

任务通知一定程度上可以替代二值信号量、计数信号量、事件组或队列。

任务通知优点:更快、占用RAM少

任务通知缺点:数据不能从任务发送到ISR(也就是ISR中不能读取任务通知);接收处理任务通知只能在本任务中;任务通知只能通过32位无符号整数传递数据;当任务为“pending”,发送任务通知API不会等待任务变为“not-pending”而阻塞,也就是数据可能丢失

任务状态:接收到通知为处理为“pending”,读取通知值状态变为“not-pending”

xTaskNotifyGive() 是xTaskNotify() 的阉割版

ulTaskNotifyTake() 是xTaskNotifyWait() 的阉割版

调用发送函数产生的影响:

调用xTaskNotifyGive()后,通知值加一,ucNotifyState变为"pending"

调用xTaskNotify()后,通知值可以不变、指定位置一、加一、强制重写通知值或者ucNotifyState为"not-pending"状态时写通知值,ucNotifyState变为"pending"。第三个参数如果是eSetBits ,是使 notification value 的某一位置一,可以同时对notification value 的某几位置一,然后同时处理几件事情;如果第三个参数是eSetValueWithOverwrite ,是设置 notification value 为某个值。

接收函数如何判断是否接收到未读通知:

ulTaskNotifyTake()判断是否有未读通知是根据通知值ulNotifiedValue是否为零,该函数可以实现通知值减一或清零。相对来说,该函数实现主要是针对信号量那种类型(xClearCountOnExit 为pdTRUE替代二值信号量;为pdFALSE替代计数信号量);

xTaskNotifyWait()判断是否有通知是依据通知状态ucNotifyState, 该函数可以实现清除指定位。这里,通知值才算真正承载了有用的通知内容。

5、互斥

当一个资源不能被同时使用时使用互斥,比如打印机。一般使用情况是在某个任务中 take token,并且在这个任务中 give toke

使用互斥可能出现的问题:

1、互斥可能会导致高优先级任务等待低优先级任务,如下图:

2、也可能导致互锁,两个任务都各自持有对方想要的互斥信号,导致两个任务都无法进行,所以建议任务等待互斥信号的时间不要无限长,超时可以做一些处理,可以发现死锁情况

3、也可能导致自锁,比如某个函数对任务进行递归调用;可以通过递归互斥(recursive mutexes)解决

4、也可能某个任务一直没执行,如下图,但是可以通过调用taskYIELD() 解决

6、Gatekeeper Tasks

对资源进行保护,使得只有一个任务能直接访问资源

互斥量是为了保护“打印机”类型的事件不被破坏,看门人任务和队列或者计数信号量配合也可以实现这个功能,具体就是只有看门人任务可以直接使用“打印机”,看门人任务大多时间阻塞等待打印数据到来,任何其他任务想使用打印机只能向看门人任务发送打印数据

7、挂起调度器、关闭中断、进入临界区

使某些关键代码段不被打断的进行

可以使用的API如下:

1、taskDISABLE_INTERRUPTS() 和 taskENABLE_INTERRUPTS()

屏蔽可屏蔽中断,包括调度器也不能工作(即不能任务切换,因为调度器也是基于中断),保证某个代码段不被打断的执行;但是不支持嵌套(即如果调用了两个DISABLE,调用一个ENABLE也可以使中断正常工作,嵌套的意思是一对DISABLE和ENABLE里面包含了其他对DISABLE和ENABLE);当调度器挂起,FreeRTOS API不可以被调用

2、taskENTER_CRITICAL() 和 taskEXIT_CRITICAL()

和1的区别就是支持嵌套,即调用了几个ENTER,就要调用几个EXIT才能使能中断;当调度器挂起,FreeRTOS API不可以被调用
3、vTaskSuspendAll() 和 xTaskResumeAll()
             只是不能进行任务切换,但是没有屏蔽中断;1和2不仅不能任务切换,还不能响应中断;当调度器挂起,FreeRTOS API不可以被调用

8、队列

携带信息进行任务间通信

1、不同于二值信号量和计数信号量,队列的原理是FIFO,可以存放数据

2、创建队列时队列的元素个数和元素的类型就已经确定了,只能往队列存放规定的元素类型

3、可以创建队列集合,队列集合里面可以放队列、计数信号量或二值信号量,使用队列集合适用于多个任务向某个任务发送数据,而数据类型不相同,不同数据类型的数据存放在不同的队列集合成员里。

4、队列可以实现邮箱功能,即多个任务可以读取长度为1的队列里的数据,但不会清除数据,即使队列有数据但没有更新,调用xQueuePeek()也不会阻塞;任务往此队列写数据是覆盖里面的数据。适用于向多个任务发送数据,即一对多通信,即广播。

9、事件组

任务间、任务与中断等多个事件的同步

事件组可以用于某个任务等待几个条件都满足或某个条件满足才解除阻塞的情景(多个发送,一个接收,即多对一通信),或者几个任务互相等待条件满足才进一步执行任务,比如task A,B,C需要进一步执行各自的任务,需要task A,B,C都满足条件(多个发送,多个接收,即多对多通信)。

调用这个函数xEventGroupSetBitsFromISR() ,实际是在定时器守护任务中执行,说有configUSE_TIMERS 和 INCLUDE_xTimerPendFunctionCall 需要置一

10、内存动态申请

如果单片机的RAM比较小,分配给FreeRTOS的heap比较少,可以使用内存动态申请pvPortMalloc定义大数组,从而减小分配给任务栈的大小

FreeRTOS - 如何根据FreeRTOS提供的功能(信号量、任务通知、队列等)设计程序的更多相关文章

  1. 十五天精通WCF——第三天 client如何知道server提供的功能清单

     通常我们去大保健的时候,都会找姑娘问一下这里能提供什么服务,什么价格,这时候可能姑娘会跟你口述一些服务或者提供一份服务清单,这样的话大 家就可以做到童嫂无欺,这样一份活生生的例子,在wcf中同样是一 ...

  2. 中国区Windows Azure 提供的功能以及与国外的差异

    当前中国服务提供的功能 目前,中国服务中包括以下 Azure 功能. 计算 - 虚拟机(用于 IaaS 服务) 计算 - 云服务(用于 PaaS 服务) 计算 - 网站 数据服务 - 存储(用于 Bl ...

  3. springdata 动态查询 是用来查询的 仅提供查询功能

    springdata 动态查询 是用来查询的 仅提供查询功能

  4. SQLAlchemy-Utils,提供choice功能

    SQLAlchemy操作数据库建表时,无法像Django一样提供choice方法,我们开头导入SQLAlchemy-Utils来为我们提供这个功能 pip3 install sqlalchemy-ut ...

  5. [转]十五天精通WCF——第三天 client如何知道server提供的功能清单

     通常我们去大保健的时候,都会找姑娘问一下这里能提供什么服务,什么价格,这时候可能姑娘会跟你口述一些服务或者提供一份服务清单,这样的话大 家就可以做到童嫂无欺,这样一份活生生的例子,在wcf中同样是一 ...

  6. ETL工具的功能和kettle如何来提供这些功能

    不多说,直接上干货! 大家会有一个疑惑,本系列博客是Kettle,那怎么扯上ETL呢? Kettle是一款国外开源的ETL工具,纯java编写,可以在Window.Linux.Unix上运行. 说白了 ...

  7. Mybatis内置的日志工厂提供日志功能

    Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具: SLF4J Apache Commons Logging Log4j 2 Log4j JDK logging 具体选择哪个日志 ...

  8. K8S-OVS使用Openvswitch为提供SDN功能支持单租户模式和多租户模式

    k8s-ovs ============================== 最近在寻求一些工作机会,如果有kubernetes相关研发招聘的朋友,欢迎随时联系我.我的个人简历可以通过百度网盘:htt ...

  9. C#的常见集合接口提供的功能

    C#的常见集合接口提供的功能 这里的功能都是泛型版本的常见功能,列出来,也许后面用得上吧,没有放非泛型版本,因为觉得用得不多,也就没有整理 IEnumerable<T> ICollecti ...

随机推荐

  1. sql server存储特殊字符解决办法

    好久没来院子了,最近在学java了,再加上项目比较紧,最近都没怎么上,其实这几天在项目中学到不少东西,都能写下来,但是久而久之就忘了,还是得养成及时总结的好习惯啊,还有有时间一定要把那个小项目整理下来 ...

  2. 吴恩达深度学习 反向传播(Back Propagation)公式推导技巧

    由于之前看的深度学习的知识都比较零散,补一下吴老师的课程希望能对这块有一个比较完整的认识.课程分为5个部分(粗体部分为已经看过的): 神经网络和深度学习 改善深层神经网络:超参数调试.正则化以及优化 ...

  3. 阿里校招内推C++岗位编程题第一题 空格最少的字符串

    给定一个字符串S和有效单词的字典D,请确定可以插入到S中的最小空格数,使得最终的字符串完全由D中的有效单词组成.并输出解. 如果没有解则应该输出n/a 例如: 输入: S = “ilikealibab ...

  4. Centos6配置开启FTP Server

    vsftpd作为FTP服务器,在Linux系统中是非常常用的.下面我们介绍如何在centos系统上安装vsftp. 什么是vsftpd vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...

  5. centos环境配置(nginx,node.js,mysql)

    1.安装 Install GCC and Development Tools on a CentOS yum group install "Development Tools" n ...

  6. mysql mariadb 密码设置

    原文:https://my.oschina.net/uyunsky/blog/109532 一.初始安装 Method 1:在/usr/local/mysql/bin/下:./mysqladmin - ...

  7. C语言实训——扑克牌洗牌程序

    说明此程序本来是21点扑克程序的一个被调函数,在这里我单独将它拿出来作为一个小程序. #include<stdio.h> #include<time.h> #include&l ...

  8. 用纯css改变下拉列表select框的默认样式(转)

    用纯css改变下拉列表select框的默认样式 分享到 分类 JS学习   关键字 前端   发布 kris  2015-04-01 注意 转载须保留原文链接,译文链接,作者译者等信息.     在这 ...

  9. python学习摘要(4)--列表简单处理

    列表打印,访问列表元素 alist = [a,b,c,d,e] print(alist) friends_name = ['alex','bill','castle','dale'] c = 1 wh ...

  10. PHP实现大文件分割上传与分片上传

    转载:http://www.zixuephp.com/phpstudy/phpshilie/20170829_43029.html 服务端为什么不能直接传大文件?跟php.ini里面的几个配置有关 u ...