|
 |
| 목록으로 가기.. |
|
MCU Task관리할때 필요한 세마포어(Semaphore)와 뮤텍스(Mutex) |
김종호
|
삭제하기
|
|
자원관리 할때 반드시 이해하고 활용해야 할 사항으로 오래도록 일해왔다면
저마다 같은 목적, 다른 솔류션들이 있을텐데 규정화 된 것을 알아두는게 좋을수 있어서 적어둠.
content = r"""# STM32 FreeRTOS 세마포어(Semaphore)와 뮤텍스(Mutex) 완벽 정리
## 1. 핵심 요약 비교
| 구분 | 세마포어 (Semaphore) | 뮤텍스 (Mutex) |
| :--- | :--- | :--- |
| **주요 용도** | 태스크 간 **동기화** (이벤트 전달) | 공유 자원 **보호** (상호 배제) |
| **소유권** | 없음 (누구나 Give 가능) | 있음 (Lock한 태스크만 Unlock 가능) |
| **우선순위 상속** | 지원 안 함 | **지원함** (우선순위 역전 방지) |
| **주 사용처** | ISR ➡️ 태스크 동기화 | 다중 태스크의 공용 자원(변수, 통신) 접근 |
---
## 2. 개념 이해하기
### 🚦 세마포어 (Semaphore) - "신호등 / 카운터"
* **목적:** 태스크 간의 **동기화**(순서 제어)나 **한정된 개수의 자원 접근 관리**를 위해 사용합니다.
* **특징:** 소유권 개념이 없어 자원을 해제하는 태스크와 획득하는 태스크가 달라도 됩니다. 이진(Binary)형과 카운팅(Counting)형이 있습니다.
### 🔒 뮤텍스 (Mutex) - "화장실 열쇠"
* **목적:** 공유 자원(UART, 전역 변수 등)을 **오직 하나의 태스크만 독점**하여 안전하게 사용하도록 보호합니다.
* **특징:** **소유권** 개념이 있어 자원을 잠근 태스크만 풀 수 있습니다. 우선순위 상속 기능을 통해 낮은 우선순위 태스크가 높은 우선순위 태스크를 방해하는 문제를 방지합니다.
---
## 3. 코드 예제 (FreeRTOS)
### 💡 세마포어 예제 (이진 세마포어: 동기화)
인터럽트(예: 버튼)가 발생하면 세마포어를 통해 대기 중인 태스크를 깨우는 방식입니다.
```c
SemaphoreHandle_t xBinarySemaphore;
// 1. 세마포어 생성
void MX_FREERTOS_Init(void) {
xBinarySemaphore = xSemaphoreCreateBinary();
}
// 2. 인터럽트 핸들러 (버튼 입력)
void EXTI0_IRQHandler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
// 3. 신호를 기다리는 태스크
void vTaskWork(void *pvParameters) {
while(1) {
if (xSemaphoreTake(xBinarySemaphore, portMAX_DELAY) == pdTRUE) {
// 인터럽트 발생 시 수행할 작업
}
}
}
```c
SemaphoreHandle_t xMutex;
### 💡 뮤텍스 예제 (자원 보호)
여러 태스크가 공유 자원(예: UART 로그 출력)을 안전하게 사용하기 위한 방식입니다.
// 1. 뮤텍스 생성
void MX_FREERTOS_Init(void) {
xMutex = xSemaphoreCreateMutex();
}
// 2. 공유 자원을 사용하는 태스크
void vTaskPrint(void *pvParameters) {
while(1) {
// 뮤텍스 획득 (대기 시간 100ms)
if (xSemaphoreTake(xMutex, (TickType_t)100) == pdTRUE) {
// --- 공유 자원 사용 (크리티컬 섹션) ---
printf("Resource Access Allowed\r\n");
// ------------------------------------
xSemaphoreGive(xMutex); // 뮤텍스 반환
}
vTaskDelay(pdMS_TO_TICKS(500));
}
}
```
|
| 
|