目录
一、信号量的特性
- 信号:起通知作用
- 量:还可以用来表示资源的数量
- 当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)
- 当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)
- 支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1
二、两种信号量对比
信号量的计数值都有限制:限定了最大值。如果最大值被限定为1,那么它就是二进制信号量;如果最大值不是1,它就是计数型信号量。
二值信号量 | 计数信号量 |
被创建时初始值为0 | 被创建时初始值可以设定 |
相同 | 相同 |
三、二值信号量
1、信号量函数
1、创建
/* 创建一个二进制信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateBinary( void );
2、删除
/*
* xSemaphore: 信号量句柄,你要删除哪个信号量
*/
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
3、give
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
4、take
BaseType_t xSemaphoreGiveFromISR(
SemaphoreHandle_t xSemaphore,
BaseType_t *pxHigherPriorityTaskWoken
);
2、代码例程
1、创建句柄、创建信号量与任务创建
SemaphoreHandle_t semaphorebinaryhandle;
//semaphore binary
semaphorebinaryhandle = xSemaphoreCreateBinary();
xTaskCreate(task_semaphore_binary1,"task_semaphore_binary1",128,NULL,osPriorityNormal,NULL);
xTaskCreate(task_semaphore_binary2,"task_semaphore_binary2",128,NULL,osPriorityNormal,NULL);
2、任务代码实现
void task_semaphore_binary1(void *param)
{
for( ;; )
{
if(key[0].single_flag == 1)
{
key[0].single_flag = 0;
xSemaphoreGive(semaphorebinaryhandle);
}
}
}
void task_semaphore_binary2(void *param)
{
for( ;; )
{
xSemaphoreTake(semaphorebinaryhandle,portMAX_DELAY);
led_toggle(green);
}
}
四、计数信号量
1、信号量函数
创建
/* 创建一个计数型信号量,返回它的句柄。
* 此函数内部会分配信号量结构体
* uxMaxCount: 最大计数值
* uxInitialCount: 初始计数值
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
2、代码例程
1、创建句柄、创建信号量与任务创建
SemaphoreHandle_t semaphorecounthandle;
semaphorecounthandle = xSemaphoreCreateCounting(10,0);
xTaskCreate(task_semaphore_count1,"task_semaphore_count1",128,NULL,osPriorityNormal,NULL);
xTaskCreate(task_semaphore_count2,"task_semaphore_count2",128,NULL,osPriorityNormal,NULL);
2、任务代码实现
void task_semaphore_count1(void *param)
{
for( ;; )
{
if(key[0].single_flag == 1)
{
xSemaphoreGive(semaphorecounthandle);
key[0].single_flag = 0;
}
}
}
void task_semaphore_count2(void *param)
{
for( ;; )
{
xSemaphoreTake(semaphorecounthandle,portMAX_DELAY);
led_toggle(green);
vTaskDelay(NULL);
}
}