← Quay lại Blog

Thiết kế firmware đa nhiệm với FreeRTOS trên ESP32

Khi làm dự án Smart Auto Door, mình gặp vấn đề kinh điển của lập trình nhúng: nếu viết code tuần tự trong một vòng lặp loop() duy nhất, việc đồng bộ Firebase (có độ trễ mạng) sẽ làm nghẽn toàn bộ hệ thống, khiến cửa phản hồi cảm biến chậm. Giải pháp là dùng FreeRTOS để tách các công việc thành các task độc lập.

1. Phân chia task theo trách nhiệm

Mình tách firmware thành các task riêng: đọc cảm biến, điều khiển động cơ, đồng bộ Firebase, và xử lý lỗi. Mỗi task chạy độc lập trên FreeRTOS scheduler, không chờ đợi lẫn nhau.

xTaskCreate(sensorTask, "Sensor", 2048, NULL, 2, NULL);
xTaskCreate(firebaseSyncTask, "FirebaseSync", 4096, NULL, 1, NULL);
xTaskCreate(motorControlTask, "Motor", 2048, NULL, 3, NULL);

2. Ưu tiên task và tránh block

Task điều khiển động cơ cần độ ưu tiên cao nhất vì liên quan trực tiếp đến an toàn vật lý (kẹt cửa, va chạm). Task đồng bộ cloud có độ ưu tiên thấp hơn vì có thể chấp nhận độ trễ vài trăm mili-giây mà không ảnh hưởng trải nghiệm người dùng.

3. Cơ chế phát hiện lỗi (fault detection)

Một bài học quan trọng: hệ thống nhúng chạy thực tế phải tự phát hiện được các trạng thái bất thường — cảm biến báo sai, động cơ kẹt, mất kết nối mạng — và có cơ chế fallback an toàn thay vì chỉ giả định mọi thứ hoạt động đúng như thiết kế.

4. Watchdog timer

Để đảm bảo thiết bị không bị treo vĩnh viễn khi gặp lỗi không lường trước, mình cấu hình watchdog timer tự động reset hệ thống nếu một task không phản hồi trong thời gian quy định — điều bắt buộc với thiết bị IoT chạy ngoài hiện trường không có người giám sát liên tục.

Kết luận

FreeRTOS giúp firmware embedded xử lý nhiều tác vụ đồng thời một cách có tổ chức, nhưng đòi hỏi tư duy thiết kế khác hẳn lập trình tuần tự — phải nghĩ về independence, priority, và fail-safe ngay từ đầu.