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