信号量
二值信号量
1、创建时初值可以是1或者0
2、创建函数
SemaphoreHandle_t xSemaphoreCreateBinary( void );
计数值初始值为0
vSemaphoreCreateBinary(过时了)
计数值初始值为1
xSemaphoreCreateBinaryStatic(静态创建)
3、删除信号量 void vSemaphoreDelete( SemaphoreHandle_t xSemaphore ); 针对动态创建信号量
4、释放信号量
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
中断 BaseType_t xSemaphoreGiveFromISR( SemaphoreHandle_t xSemaphore, BaseType_t*
pxHigherPriorityTaskWoken );
5、获取信号量
计数信号量
1、创建时初值可以设定
2、创建函数
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
uxMaxCount 最大计数值
uxInitialCount 初始计数值
xSemaphoreCreateCountingStatic
互斥量
正常
/* 创建一个互斥量,返回它的句柄。
* 此函数内部会分配互斥量结构体
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateMutex( void );
静态
* 创建一个互斥量,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个StaticSemaphore_t结构体,并传入它的指针
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer );
释放
/* 释放 */
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
获取
BaseType_t xSemaphoreTake(
SemaphoreHandle_t xSemaphore,
TickType_t xTicksToWait
注意要点
互斥量、互斥锁,本来的概念确实是:谁上锁就得由谁解锁。
但是FreeRTOS并没有实现这点,只是要求程序员按照这样的惯例写代码。
互斥量不能在ISR中使用(包括任何操作)
优先级反转
优先级继承
递归锁
死锁
假设有2个互斥量M1、M2,2个任务A、B:
A获得了互斥量M1 , B获得了互斥量M2, A还要获得互斥量M2才能运行,结果A阻塞, B还要获得互斥量M1才能运
行,结果B阻塞A、B都阻塞,再无法释放它们持有的互斥量死锁发生!
自我死锁
任务A获得了互斥锁M,它调用一个库函数,
库函数要去获取同一个互斥锁M,于是它阻塞:任务A休眠,等待任务A来释放互斥锁!
死锁发生!
递归互斥量
/* 创建一个递归锁,返回它的句柄。
* 此函数内部会分配互斥量结构体
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t
xSemaphoreCreateRecursiveMutex( void );
/* 释放 */
BaseType_t xSemaphoreGiveRecursive(
SemaphoreHandle_t xSemaphore );
/* 获得 */
BaseType_t xSemaphoreTakeRecursive(
SemaphoreHandle_t xSemaphore,
TickType_t xTicksToWait
);
递归锁实现了:谁上锁就由谁解锁。