4- 信号量& 互斥量
信号量,计数值
问题: 还是那个AB任务互斥调度的问题,B等A执行完毕的过程中,判断标志位会耗费CPU资源
利用信号量,当没有信号的时候,不参与调度
计数信号量(不能用来传输数据)
static SemaphoreData_t xSemCalc;
Xsemcalc=xSemaphoreCreateCounting(10,0);//最大值,初始值
计算完成后信号量+1
当任务1计算还没完成的时候,任务2阻塞在xSemaphoreTake (设置了永远等待直到信号量到来) ,当任务1计算完毕,信号量+1,任务2获取到信号量,打印
#include "semphr.h"
二进制信号量实现互斥,(使用串口)
SemaphoreHandle_t xBinarySemaphore;
xBinarySemaphore = xSemaphoreCreateBinary( );
xSemaphoreGive(xBinarySemaphore) 使串口可以使用
谁要用串口就要先获得信号量
xSemaphoreTake(xBinarySemaphore, portMAX_DELAY)
用完后再释放掉
xSemaphoreGive(xBinarySemaphore) 让其他人可以使用
互斥量
问题:上面的二进制信号量,正常是A用完A解锁,但是异常情况下(比如人编程问题),导致A还没用完就切换出去到C,C执行完毕后把A的信号量解锁了,此时B就有可能拿到信号量去使用串口,就跟A冲突在一起
解决办法: 谁上锁谁解锁(FREERTOS没有实现,只能靠程序员)
问题:优先级反转:
ABC任务优先级递增,A加了锁,B抢占,然后C抢占,C拿不到锁被阻塞,然后B开始运行, 明明C优先级最高,但是得不到执行
解决办法:优先级继承
ABC任务优先级递增,A加了锁,B抢占,然后C抢占,C拿不到锁被阻塞,LOCK的同时使加锁的A继承C的优先级(先执行),A执行后释放锁(又回归原来的优先级),C就可以执行,、
使用条件:使用mutex 自动实现优先级继承解决优先级反转的问题
问题:递归上锁
A执行函数加锁,嵌套的函数又想获得锁,就阻塞了,没办法解锁,形成死锁
解决办法:递归锁 (在锁上后,还可以获得这个锁【同一个】,一一配对解锁就行)
10-1OVER
使用互斥量实现互斥
static SemaphoreHandle_t xSemUART; xSemUART = xSemaphoreCreateMutex(); void TaskGenericFunction(void * param) { while (1) { xSemaphoreTake(xSemUART, portMAX_DELAY); printf("%s\r\n", (char *)param); xSemaphoreGive(xSemUART); vTaskDelay(1); //与 } } xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1); xTaskCreate(Task2Function, "Task2", 100, NULL, 1, NULL);
是个特殊的信号量
二级制信号量初始值是0,创建后需要Give -次; 斥量初始值是1,创建后不需要Give 次。
延时有什么区别vTaskDelay(1) &