🌱 RTOS 05. Quản lý bộ nhớ trong RTOS - Heap Memory Management
Ở post trước chúng ta đã cùng tìm hiểu về phần cứng sử dụng để xây dựng một hệ điều hành RTOS. Một hệ điều hành RTOS trên vi điều khiển bao gồm các task được phân bổ bộ nhớ trên vùng nhớ khác nhau, vì vậy việc cấp phát và quản lý bộ nhớ này là vô cùng quan trọng.
💛 Bài viết này là phần tìm hiểu của bạn Đặng Văn Sơn, người anh em cùng team FPT. Mình xin gửi lời cảm ơn của anh em đọc được bài viết này đến bạn.
Các hệ điều hành RTOS thông thường sử dụng cấp phát động (vùng nhớ Heap) bởi vì các task được tạo trong lúc runtime nên cần cấp phát động. Một số cách làm có thể triển khai bộ nhớ tĩnh cho các task khi cố định các task từ lúc compile.
Các nội dung chính
Ý tưởng chung về quản lý bộ nhớ Heap
Về cơ bản, trong RTOS cần quản lý RTOS cho các yếu tố: các Tasks, cho các cơ chế Semaphore, Queue, Mutex, và việc cấp phát động (Dynamic memory allocation). Cách thức cấp phát bộ nhớ sẽ ảnh hưởng lớn đến hiệu suất, độ tin cậy, và tính quyết định (determinism) của toàn hệ thống.
Như đã nói ở trên thì có hai phương án để cấp phát bộ nhớ cho các Task.
- Cấp phát tĩnh: Bộ nhớ được cấp phát trước tại thời điểm biên dịch. Từ đó kích thước sẽ cố định và không phụ thuộc vào runtime, không gây phân mảnh bộ nhớ.Tuy nhiên là tính linh hoạt kém, nếu dùng ít quá so với cấp phát thì lãng phí bộ nhớ, nếu dùng nhiều quá hơn so với cấp phát thì không được.
- Cấp phát động: Bộ nhớ được cấp phát trong runtime từ heap. Ưu điểm là linh hoạt, dễ dàng tạo và free bộ nhớ khi cần thiết.
Nếu các thành phần trong RTOS được cấp phát động thì đôi khi có thể sử dụng các hàm malloc() và free() của thư viện C chuẩn cho mục đích này, nhưng ...
- Các hàm này không phải lúc nào cũng có sẵn trên các hệ thống nhúng,
- Không đảm bảo Thread-Safe,
- Không cố định về thời gian thực thi hàm,
Dưới đây là các cách quản lý bộ nhớ Heap của freeRTOS.
Ví dụ cách quản lý Heap của freeRTOS
👉 Heap_1
Đây là cách cấp phát cơ bản nhất và không cho phép giải phóng bộ nhớ.
- Ưu điểm của phương pháp triên khai này là đơn giản, dễ sử dụng, chỉ cần cấp phát mảng tĩnh cố định trên Heap.
- Nhược điểm của nó là không giải phóng bộ nhớ được, nên chỉ dùng với những ứng dụng mà chúng ta không cần xóa các Task, Semaphore, Mutex, ...
👉 Heap_2
Cho phép giải phóng bộ nhớ, nhưng không đặt các vùng Task cạnh nhau.
👉 Heap_3
Cách này sử dùng các hàm theo thư viện chuẩn C, đó là malloc() và free() để cấp phát và giải phóng bộ nhớ.
👉 Heap_4
Giống như Heap_2 tuy nhiên cho phép sử dụng lại các vùng Free Space.
👉 Heap_5
Không giống như Heap_4, Heap_5 không bị giới hạn trong việc cấp phát bộ nhớ từ một mảng được khai báo tĩnh duy nhất; Heap_5 có thể cấp phát bộ nhớ từ nhiều không gian bộ nhớ riêng biệt.
Điều này khá hữu ích khi RAM được phân cách thành nhiều vùng như hình trên.👉 Các cách phân bổ bộ nhớ trên Heap khác quan trọng khi thiết kế RTOS, tùy vào ứng dụng cụ thể cũng như tài nguyên của hệ thống, chúng ta sẽ có những cách thiết kế khác nhau.