参考文档与视频百问网《FreeRTOS入门与工程实践-基于STM32F103》教程-基于DShanMCU-103(STM32F103) | 百问网
互斥量
下面先简单的理解一下互斥量是个什么东东
简单看来互斥量就是信号量最多为一的信号量,下面是互斥量的应用范围
可以很简单的知道,互斥量正常是使用在资源有限而需要共享的情况(比如串口或者IIC)
下面利用AI写一个串口程序,其中使用ESP32S3中的CORE1和CORE0创建打印任务,然后使用互斥量进行隔离
代码如下
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "driver/uart.h"
#include "esp_log.h"
static const char *TAG = "UART_Example";
// 互斥量
SemaphoreHandle_t xMutex;
// 串口配置
#define UART_PORT_NUM UART_NUM_0
#define UART_BAUD_RATE 115200
// 任务 1
static void task1(void *pvParameters)
{
while (1)
{
// 获取互斥量
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
// 打印消息
printf("Task 1: Hello from Core %d\n", xPortGetCoreID());
// 释放互斥量
xSemaphoreGive(xMutex);
}
// 延迟
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// 任务 2
static void task2(void *pvParameters)
{
while (1)
{
// 获取互斥量
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE)
{
// 打印消息
printf("Task 2: Hello from Core %d\n", xPortGetCoreID());
// 释放互斥量
xSemaphoreGive(xMutex);
}
//延迟
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
// 初始化串口
void uart_init(void) {
const uart_config_t uart_config =
{
.baud_rate = UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
// 配置串口
uart_param_config(UART_PORT_NUM, &uart_config);
uart_driver_install(UART_PORT_NUM, 1024 * 2, 0, 0, NULL, 0);
// // 重定向标准输出到串口
// setvbuf(stdout, NULL, _IONBF, 0);
// esp_rom_uartAttachTxUart2();
// esp_rom_uart_tx_wait_idle(UART_PORT_NUM);
}
// 主函数
void app_main(void)
{
// 初始化串口
uart_init();
// 创建互斥量
xMutex = xSemaphoreCreateMutex();
if (xMutex == NULL)
{
ESP_LOGE(TAG, "Failed to create mutex");
return;
}
// 创建任务 1 并绑定到核心 0
xTaskCreatePinnedToCore(task1, "Task 1", 2048, NULL, 5, NULL, 0);
// 创建任务 2 并绑定到核心 1
xTaskCreatePinnedToCore(task2, "Task 2", 2048, NULL, 5, NULL, 1);
// 主循环
while (1)
{
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
可以看到打印信息交替打印,特别的完美
下面我们尝试一下删去互斥量,看会是什么结果
首先修改的代码部分如下(删去两个task中对互斥量的GIVE和TAKE,并把延时时间降低)
实验现象会有大概率可能发生看门狗报错
此时如果把注释的代码改回去,程序恢复正常