任务间通信方式:消息队列、信号量(二值、互斥、计数)、事件、任务通知
1、消息队列(可以携带信息在任务间通信)
先创建队列(确定消息的个数和每个消息大小),一个任务通过队列发消息,一个任务通过队列收消息,消息携带信息
2、信号量:坑位和钥匙
2.1、二值信号量(一个坑位,一把钥匙)
创建信号量,任务A、任务B都是要获取到信号量xSemaphereTake才运行下面的程序,获取不到就阻塞。如果任务 A先获取到信号量,任务A就开始运行,运行完值后,如果任务A不xSemaphereGive这个信号量,任务B就不会运行,一直阻塞。
2.2、互斥信号量(一个坑位,一把钥匙)
2.2.1、优先级继承
假定有H、M、L三个任务在运行,H在运行时,突然遇到二值信号量了,需要获取信号量才能下一步,而 这个信号量是由L释放的。这个时候H任务进入vTaskDelay,阻塞了。时间片切换到L运行,L还没有运行到释放信号量时,就该 切换时间片了,此时M优先级高于L,所以M任务开始运行,又由于优先级原因每次切时间片都轮不到L运行,这就出现了,H任 务一直阻塞等待L任务释放信号量,L任务又被M任务的优先级干得运行不了,总体表现为H任务和M任务优先级发生了翻转。互斥量解决了这一问题。当H被阻塞需要L释放信号量时,时间片切换到L运行,L此时的优先级暂时变成H的优先级,在下一个时间片切换时,L任务就不会因为任务优先级被M任务干掉,L继续运行直到H任务获得信号量。
2.2.2、互斥量和二值信号量的区别
互斥量具有优先级继承的优点。相同点:都是一个坑位,查这个坑位 有没有钥匙。一个任务到坑位拿走信号量后,另一个任务过来,看到坑位没有钥匙,就会死等。
2.3、计数信号量
假如一开始创建计数信号量给了两把钥匙,任务A拿一把,任务B拿一把,任务C再去拿,看到两个坑位的钥匙都拿走了,此时,就必须有一个任务先xSemaphereGive出一个钥匙到坑位才行。