ESP32는 듀얼코어 MCU이며 다음과 같은 구조를 갖습니다:
| 코어 |
이름 |
역할 |
| Core 0 |
PRO CPU |
주로 사용자 코드 (WiFi, Bluetooth도 일부 포함) |
| Core 1 |
APP CPU |
FreeRTOS 백그라운드 + 실시간 제어 적합 |
중요한 점: WiFi, BLE 등의 무선 스택은 기본적으로 Core 0에서 실행됨
→ 실시간성이 필요한 Task는 Core 1에 배치하는 것이 일반적입니다.
| Task 이름 |
우선순위 |
주기 (Hz) |
코어 배치 |
이유 |
SensorTask |
2 |
100~500Hz |
Core 1 |
IMU, GPS, 고속 센서 수집은 실시간성 요구 |
StabilizerTask |
3 |
100~250Hz |
Core 1 |
PID 제어 루프는 지연 없이 빠르게 계산 필요 |
MotorCtrlTask |
3 |
100~250Hz |
Core 1 |
PWM 출력은 제어 주기 정확성이 중요 |
CommandTask |
1 |
~50Hz |
Core 0 |
사용자 입력 (BLE/UART)은 지연 허용 가능 |
TelemetryTask |
1 |
~10Hz |
Core 0 |
WiFi/UART 전송은 비실시간 통신 |
FailsafeTask |
2 |
~5Hz |
Core 1 |
실시간 오류 대응 필요 (예: 신호 끊김 감지 등) |
| Core 0 (PRO CPU) → 비실시간/통신 |
Core 1 (APP CPU) → 실시간 제어 |
| CommandTask (BLE/UART/RC) |
SensorTask (IMU, GPS) |
| TelemetryTask |
StabilizerTask (PID) |
|
MotorCtrlTask (PWM) |
|
FailsafeTask |
- Sensor, Stabilizer, Motor는 정해진 주기(100~500Hz)로 정확히 동작해야 함
- Core 1은 WiFi/BLE 간섭이 적어 실시간 제어 루프에 적합
- BLE, UART, WiFi는 일반적으로 Core 0에서 동작
- 명령 입력/상태 전송은 약간의 지연이 허용됨
| Task |
Core |
Priority |
설명 |
| SensorTask |
1 |
2 |
I2C/SPI 센서 읽기 |
| StabilizerTask |
1 |
3 |
PID 제어 계산 |
| MotorCtrlTask |
1 |
3 |
PWM 출력 |
| FailsafeTask |
1 |
2 |
센서 오류 감지 등 |
| CommandTask |
0 |
1 |
RC/BLE/UART 수신 |
| TelemetryTask |
0 |
1 |
상태 보고 전송 |
xTaskCreatePinnedToCore() 를 반드시 사용하여 Task를 원하는 코어에 고정
- 실시간 Task는
vTaskDelayUntil() 로 정확한 주기를 유지
- 센서 데이터 공유 시 Mutex 사용
- ISR 또는 DMA를 사용하는 센서라면 추가 보호 필요