SWDesk/Firmware
[Arduino] ESP32 nano, FreeRTOS 실행 시 메모리 충돌 방지 대책
bizmaker
2025. 3. 14. 05:30
portENTER_CRITICAL() 사용
[예제 코드]
#include <WiFi.h>
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
WiFiServer server(80);
#define LED_PIN 2 // GPIO2를 LED 제어 핀으로 사용
// 🔹 공유 변수 (WiFiTask와 GPIOTask에서 사용)
volatile bool isDataReady = false; // 데이터 준비 여부
String valueString = ""; // WiFi로 전송할 데이터
// 🔹 FreeRTOS Critical Section 관리용 변수
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void WiFiTask(void *parameter);
void GPIOTask(void *parameter);
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
// 🔹 WiFi Task 실행 (Core 0)
xTaskCreatePinnedToCore(WiFiTask, "WiFiTask", 4096, NULL, 1, NULL, 0);
// 🔹 GPIO Task 실행 (Core 1)
xTaskCreatePinnedToCore(GPIOTask, "GPIOTask", 1024, NULL, 1, NULL, 1);
}
void loop() {
// 메인 루프는 비워두거나 다른 작업 가능
}
// 🔹 WiFi Task (Core 0에서 실행)
void WiFiTask(void *parameter) {
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi...");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected!");
server.begin();
while (true) {
WiFiClient client = server.available();
// 🔸 데이터가 준비된 경우에만 WiFi로 전송
portENTER_CRITICAL(&mux); // 🚨 임계 영역 시작
bool dataReady = isDataReady;
isDataReady = false; // 데이터 전송 후 플래그 초기화
portEXIT_CRITICAL(&mux); // 🚨 임계 영역 종료
if (dataReady) {
if (client) {
Serial.println("Sending data: " + valueString);
client.println(valueString);
client.stop(); // 클라이언트 연결 종료
}
}
delay(100); // WiFi Task 실행 주기 설정
}
}
// 🔹 GPIO Task (Core 1에서 실행)
void GPIOTask(void *parameter) {
while (true) {
// 🔸 GPIO를 주기적으로 제어 (예: LED 깜박임)
digitalWrite(LED_PIN, HIGH);
delay(500);
digitalWrite(LED_PIN, LOW);
delay(500);
// 🔸 특정 조건 충족 시 데이터 전송 준비
if (millis() % 5000 < 1000) { // 5초마다 한 번 실행
String tempValue = "Sensor Value: " + String(random(100, 200));
portENTER_CRITICAL(&mux); // 🚨 임계 영역 시작
valueString = tempValue;
isDataReady = true;
portEXIT_CRITICAL(&mux); // 🚨 임계 영역 종료
Serial.println("Data Ready: " + valueString);
}
}
}
반응형