Hướng dẫn cơ bản về các API của FreeRTOS, so sánh giữa FreeRTOS và CMSIS-RTOS, cách cấu hình FreeRTOS với CubeMX và ý nghĩa của các thông số thông qua ví dụ minh họa cụ thể.
Như ở bài trước mình có nói về RTOS cơ bản và các khái niệm của nó rồi, hôm nay mình xin đi vào các ví dụ cụ thể để các bạn có thể hình dung được khi chạy thực tế thì RTOS nó sẽ như thế nào, làm sao để biết được task nào đang chạy ?
Tổng quan
Để sử dụng được FreeRTOS, cách cơ bản nhất là bạn phải biết sử dụng các API(nói dễ hiểu là các hàm được cung cấp sẵn) của nó, dưới đây là bảng tổng quan về các API của FreeRTOS và mô tả cụ thể
Phân loại API | FreeRTOS API | Mô tả |
---|---|---|
Tạo task | xTaskCreate | Tạo task mới |
vTaskDelete | Xóa task | |
Control task | vTaskDelay | Delay task |
vTaskPrioritySet | Set quyền cho task | |
vTaskSuspend | Suspend task | |
vTaskResume | Tiếp tục task | |
Control kernel | vTaskStartScheduler | Start kernel scheduler |
vTaskSuspendAll | Suspend taats cả task | |
xTaskResumeAll | Tiếp tục taất cả task | |
taskYIELD | Foce chuyển đổi context | |
taskENTER_CRITICAL | Vào critical section(dùng context switching) | |
taskEXIT_CRITICAL | Thoát khỏi critical section | |
Messagequeues | xQueueCreate | Tạo một queue |
xQueueSend | Gửi data vào queue | |
xQueueReceive | Nhận data từ queue | |
Semaphores | xSemaphoreCreateBinary | Tạo một binary semaphore |
xSemaphoreCreateCounting | Tạo một counting semaphore | |
xSemaphoreCreateMutex | Tạo một mutex semaphore | |
xSemaphoreTake | Take semaphore | |
xSemaphoreGive | Give semaphore | |
Timers | xTimerCreate | Tạo timer |
xTimerStart | Start timer | |
xTimerStop | Stop timer |
CMSIS-RTOS
Với STM32 thì chúng ta sẽ có thêm một phần implement mới là CMSIS-RTOS, phần này được thêm vào trong file cmsis-os.c
( các bạn có thể tìm thấy ở thư mục \Middlewares\Third_Party\FreeRTOS\Source\CMSIS_RTOS
), nếu dùng cái này thì nó sẽ có một số thay đổi so với bản FreeRTOS gốc, có đổi tên một số API, ta cần phải check bảng mapping bên dưới để biết API tương ứng giữa CMSIS-RTOS API và FreeRTOS API.
Phân loại API | CMSIS_RTOS API | FreeRTOS API |
---|---|---|
Control kernel | osKernelStart | vTaskStartScheduler |
Quản lý thread | osThreadCreate | xTaskCreate |
Semaphore | osSemaphoreCreate | vSemaphoreCreateBinaryxSemaphoreCreateCounting |
Mutex | osMutexWait | xSemaphoreTake |
Message queue | osMessagePut | xQueueSendxQueueSendFromISR |
Timer | osTimerCreate | xTimerCreate |
Lưu ý: tên API giữa CMSIS-RTOS API và FreeRTOS API có thể khác nhau nhưng về task state thì được implement dựa trên cùng một model
Với CMSIS-RTOS thì đây là
- Interface RTOS thông thường dành cho các chip ARM cortex-M
- Các thành phần middleware dùng CMSIS-RTOS thì không dùng được FreeRTOS và ngược lại
- CMSIS-RTOS API sẽ định nghĩa một số feature bao gồm
- Thread Management
- Kernel control
- Semaphore management
- Message queue and mail queue
- Memory management
Để có thể biết thêm chi tiết các bạn có thể coi thêm ở nguồn tài liệu CMSIS-RTOS
Thông số cấu hình
Các cấu hình sau khi thực hiện xong sẽ được lưu tại file FreeRTOSConfig.h
Một số cấu hình quan trọng cần lưu ý là
Config option | Mô tả |
---|---|
configUSE_PREEMPTION | Enable Preemption |
configCPU_CLOCK_HZ | Tần số CPU(Hz) |
configTICK_RATE_HZ | Tick rate (Hz) |
configMAX_PRIORITIES | Số lượng priority task tối đa |
configTOTAL_HEAP_SIZE | Tổng heap size cho dynamic allocation |
configLIBRARY_LOWEST_INTERRUPT_PRIORITY | Interrupt priority thấp nhất(0xF khi sử dụng 4 cortex preemption bit) |
configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY | Highest thread safe interrupt priority (higher priorities are lower numeric value) |
Tickless idle mode
Tickless mode là mode được sử dụng cho các ứng dụng low power, nghĩa là các ứng dụng cần tiêu thụ năng lượng thấp, nhất là các ứng dụng có liên quan tới pin.
Với FreeRTOS thì kernel có thể dừng ngắt system tick của hệ thống và đưa MCU vào trạng thái low power, khi thoát khỏi mode này thì mode systick counter sẽ được update.
Để dùng mode này cần cấu hình USE_TICKLESS_IDLE
là 1
Kernel sẽ call macro là SUPPRESS_TICKS_AND_SLEEP()
khi task Idle là task duy nhất có thể chạy(và không có task nào khác được scheduled để xit từ block state sau n tick, giá trị n này được define trong file FreeRTOSconf.h
)
FreeRTOS implement port SUPRESS_TICKS_AND_SLEEP
cho cortex M3/M4 để có thể đưa MCU vào mode sleep low power
Để wakeup từ sleep mode cần có interrupt/event từ hệ thống.
FreeRTOS trong CubeMX
Về lý thuyết mình cũng đã nói nhiều, giờ làm sao để cấu hình FreeRTOS trong CubeMX
Mở CubeMX lên, check vào Enable FreeRTOS tại mục middlewares
Mở thẻ Configuration và ấn vào FreeRTOS để cấu hình
Cấu hình FreeRTOS và kernel
- Thẻ
Config parameters
cho phép ta có thể cấu hình cài đặt ban đầu những thứ liên quan tới kernel và memory - Thẻ
Include parameters
cho phép bật/tắt một số define về Task,Queue, Semaphore,…. - Thẻ
Tasks and Queue
giúp ta có thể tạo/ thêm các task và queue - Thẻ
Timers and semaphores
cho phép thêm Timers, Mutexes, Semaphore, có Mutex và Binary Semaphore mặc định là có thể add thêm mới, với Recursive Mutexes cũng như Binary Semaphore để hiện được nút add thì cần phải enable các define ở thẻInclude parameters
- Thẻ
User Constants
để có thể thêm các constant của user có thể tự định nghĩa vào
Sử dụng preemption
- Bật enable trong tùy chọn để dùng pre-emptive scheduling
- Nếu disbale thì hệ thống sẽ dùng co-operatieve scheduling
Nói qua một chút về khái niệm pre-emptive scheduling và co-operatieve scheduling, cơ bản đây là 2 thuật toán dùng để lập lịch, với các hệ thống hiện đại thì đều phụ thuộc vào các thuật toán lập lịch để thực hiện các tác vụ đa nhiệm hoặc ghép kênh(multiplexing) hiệu quả. Những thuật toán này sẽ thực hiện thỏa hiệp để hoàn thành các mục tiêu cụ thể trong thời gian hạn hẹp.
Với pre-emptive scheduling khi start hệ thống thì task sẽ tiếp tục chạy cho tới khi nó từ bỏ quyền kiểm soát, thường là ở thời điểm đồng bộ hóa của nó.
Với co-operatieve scheduling thì sẽ giữ lại các thuộc tính như task, trạng thái của tas/ queue và mức ưu tiên, task sẽ tiếp tục cho tới khi nó hoàn toàn từ bỏ quyền kiểm soát CPU, tuy nhiên task có thể bị ép phải dừng (suspend) bằng cách dùng ngắt của CPU. Cụ thể hơn như thế nào xin hẹn các bạn ở một bài viết khác.
Tạm kết
Vậy là bạn có thể hiểu được cơ bản về RTOS và các bước để cấu hình RTOS trong CubeMX, để chạy thật thì các bạn chờ tới bài task mình sẽ có ví dụ minh họa cụ thể luôn nhé.
Bonus thêm clip minh họa mình đã làm từ lâu về cách tạo project và chạy thử một project RTOS mẫu với STM32F103