FreeRTOS STM32C8T6 标准库互斥锁 使用教程 示例代码
时间: 2025-05-26 11:23:52 浏览: 22
### FreeRTOS STM32C8T6 标准库 中互斥锁的使用教程及示例代码
#### 1. 头文件引入
为了在项目中使用互斥锁功能,需要包含 `semphr.h` 文件。这是 FreeRTOS 提供的标准信号量头文件。
```c
#include "semphr.h"
```
#### 2. 定义互斥锁句柄
在程序中定义一个变量来保存互斥锁的句柄。该句柄将在后续的操作中被用来控制资源的访问权限。
```c
SemaphoreHandle_t xMutex;
```
#### 3. 创建互斥锁
通过调用 `xSemaphoreCreateMutex()` 函数可以创建一个新的互斥锁实例。此函数返回一个指向新创建互斥锁的句柄。
```c
xMutex = xSemaphoreCreateMutex();
if (xMutex == NULL) {
// 错误处理逻辑:无法创建互斥锁
}
```
如果返回值为 `NULL`,表示内存不足或其他原因导致未能成功创建互斥锁[^2]。
#### 4. 获取互斥锁
当某个任务需要独占某项共享资源时,可以通过调用 `xSemaphoreTake()` 来获取互斥锁。这个函数会阻塞当前任务直到获得锁为止(除非指定了超时时间)。
```c
if (xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE) {
// 错误处理逻辑:无法获取互斥锁
}
// 访问受保护的资源共享部分...
```
这里使用的参数 `portMAX_DELAY` 表明任务将无限期等待直至得到锁。实际应用可根据需求调整为有限的时间间隔[^2]。
#### 5. 释放互斥锁
完成对共享资源的操作之后,应该立即调用 `xSemaphoreGive()` 将互斥锁交还给系统以便其他任务能够继续执行其操作。
```c
if (xSemaphoreGive(xMutex) != pdTRUE) {
// 错误处理逻辑:无法释放互斥锁
}
// 继续正常流程...
```
注意每次仅允许持有者调用 `xSemaphoreGive()` 方法;否则可能导致未定义行为发生[^2]。
#### 示例代码展示如何利用互斥锁管理两个串口通信过程中的冲突情况:
```c
#include "stm32f10x.h" /* Keil::Device:Startup */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* Define Mutex Handle */
SemaphoreHandle_t xSerialPortMutex;
void vTask1(void *pvParameters);
void vTask2(void *pvParameters);
int main(void){
/* Initialize hardware and peripherals here */
/* Create the mutex that will be used to protect access to the serial ports */
xSerialPortMutex = xSemaphoreCreateMutex();
if( xSerialPortMutex == NULL ){
/* Could not create the mutex */
while(1);
}
/* Start two tasks which both use one of the same UARTs */
xTaskCreate(vTask1,"UART Task 1",configMINIMAL_STACK_SIZE,NULL,tskIDLE_PRIORITY+1,NULL );
xTaskCreate(vTask2,"UART Task 2",configMINIMAL_STACK_SIZE,NULL,tskIDLE_PRIORITY+1,NULL );
/* Now all tasks have been started - start the scheduler. The function does not return unless a task calls vTaskEndScheduler(). */
vTaskStartScheduler();
/* Should never reach here! */
for (;;);
}
/* A simple task using Serial Port with protection by Mutex */
void vTask1(void *pvParameters){
char cTxData[]="Message from Task1\n";
for(;;){
if( xSemaphoreTake( xSerialPortMutex , portMAX_DELAY ) == pdTRUE ){
/* Critical Section Begin */
/* Send message via USART */
HAL_UART_Transmit(&huart1,(uint8_t*)cTxData,strlen(cTxData),HAL_MAX_DELAY);
/* Critical Section End */
xSemaphoreGive( xSerialPortMutex );
}
/* Delay between transmissions */
vTaskDelay(pdMS_TO_TICKS(100));
}
}
/* Another similar but different task also accessing shared resource */
void vTask2(void *pvParameters){
char cTxData[]="Message from Task2\n";
for(;;){
if( xSemaphoreTake( xSerialPortMutex , portMAX_DELAY ) == pdTRUE ){
/* Critical Section Begin */
/* Send message via another USART or same depending on your setup */
HAL_UART_Transmit(&huart2,(uint8_t*)cTxData,strlen(cTxData),HAL_MAX_DELAY);
/* Critical Section End */
xSemaphoreGive( xSerialPortMutex );
}
/* Different delay interval than above task */
vTaskDelay(pdMS_TO_TICKS(200));
}
}
```
上述例子展示了两个独立的任务分别向不同的串行端发送消息前先尝试取得全局互斥锁以防止彼此干扰的情况出现。
---
阅读全文
相关推荐















