二进制信号量和互斥信号量都是信号量,信号量创建完之后不可以直接Take,要先give,高优先级的任务会打断低优先级的任务,互斥信号量创建完之后可以直接Take,互斥信号量,谁Take,谁Give,Take,Give操作不能分开,任务中间不会被打断。

互斥信号量通过优先级继承机制避免了优先级反转这个问题

二进制信号量是两个任务,如任务A,任务B,A释放信号量给B,互斥锁是任务独享,谁take,谁give。

二进制信号量

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
SemaphoreHandle_t bin_sem;
TaskHandle_t TaskA_Handle;
TaskHandle_t TaskB_Handle;

void TaskA(){
    //释放信号量
    while (1)
    {
        xSemaphoreGive(bin_sem);
        ESP_LOGI("TASKA","TASKA give sem success");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    
}

void TaskB(){
    //获取信号量
    while (1)
    {
        if(pdTRUE==xSemaphoreTake(bin_sem,portMAX_DELAY)){
            ESP_LOGI("TASKB","TASKB take sem success");
            vTaskDelay(pdMS_TO_TICKS(500));
        }
    }
    
}

void app_main(void)
{
    //创建二进制信号量,成功返回信号量句柄,创建完信号量的值为空
    //创建完信号量在低优先级任务释放信号量的瞬间,
    //高优先级会抢占低优先级的任务来执行
    bin_sem=xSemaphoreCreateBinary();
    xTaskCreatePinnedToCore(TaskA,"TASKA",2048,NULL,3,&TaskA_Handle,1);
    xTaskCreatePinnedToCore(TaskB,"TASKB",2048,NULL,3,&TaskB_Handle,1);
    ESP_LOGI("main","Creat TaskA,TasB success");
}

互斥锁

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
TaskHandle_t TaskA_Handle;
TaskHandle_t TaskB_Handle;
SemaphoreHandle_t semaphore_Mutex;
void TaskA(){
    
    while (1)
    {
        xSemaphoreTake(semaphore_Mutex,portMAX_DELAY);
        ESP_LOGI("TaskA","TASKA use source");
        xSemaphoreGive(semaphore_Mutex); 
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    
}

void TaskB(){

    while (1)
    {
        //注意互斥信号量是谁Take,谁Give,挂起要在Give之后进行
        xSemaphoreTake(semaphore_Mutex,portMAX_DELAY);
        ESP_LOGI("TaskB","TASKB use source");
        xSemaphoreGive(semaphore_Mutex); 
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
    
}

void app_main(void)
{
    semaphore_Mutex=xSemaphoreCreateMutex();
    xTaskCreatePinnedToCore(TaskA,"TASKA",2048,NULL,3,&TaskA_Handle,1);
    xTaskCreatePinnedToCore(TaskB,"TASKB",2048,NULL,3,&TaskB_Handle,1);
}

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐