二进制信号量能够满足任务间的互斥和同步,需要的系统开销最小,因此也称快速信号量。二进制信号量可以看成一个标志,对应资源是可用还是不可用。
本小节就来认识二进制信号量的创建等过程。
首先要添加一个头文件freertos/semphr.h
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
#include "freertos/timers.h"
#include "freertos/semphr.h"
int iCount = 0;
SemaphoreHandle_t semaphoreHandle;
void myTask1(void *pvParam) {
while (1) {
xSemaphoreTake(semaphoreHandle, portMAX_DELAY);
for (int i = 0; i < 10; i++) {
iCount++;
printf("myTask1 iCount = %d!\n", iCount);
vTaskDelay(pdMS_TO_TICKS(1000));
}
xSemaphoreGive(semaphoreHandle);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void myTask2(void *pvParam) {
while (1) {
xSemaphoreTake(semaphoreHandle, portMAX_DELAY);
for (int i = 0; i < 10; i++) {
iCount++;
printf("myTask2 iCount = %d!\n", iCount);
vTaskDelay(pdMS_TO_TICKS(1000));
}
xSemaphoreGive(semaphoreHandle);
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void app_main(void) {
semaphoreHandle = xSemaphoreCreateBinary();
xSemaphoreGive(semaphoreHandle);
xTaskCreate(myTask1, "myTask1", 1024 * 5, NULL, 1, NULL);
xTaskCreate(myTask2, "myTask2", 1024 * 5, NULL, 1, NULL);
}
我们在app_main()中调用xSemaphoreCreateBinary()函数,创建一个二进制信号量,创建完后使用xSemaphoreGive()函数释放创建的信号量,使用xTaskCreate()创建任务。
在myTask1()和myTask2()中先获取信号量,循环打印后释放信号量
对上述代码中一些函数做简单说明:
xSemaphoreCreateBinary()函数:
创建一个二进制信号量,并返回一个句柄
xSemaphoreGive()函数:
释放以前使用调用创建的信号量
xSemaphore:创建的信号量句柄
xSemaphoreTake()函数:
获取创建的信号量
xSemaphore:传入正在使用的信号量
xTicksToWait:要等待的时间