0

Giới thiệu về AMP, SMP và cơ chế lập lịch của FreeRTOS (Single Core)

AMP và SMP là gì?

Trước tiên, tôi sẽ nói nhanh về 2 mô hình đa nhân phổ biến.

1. (Asymmetric Multi-Processing)

AMP là mô hình CPU có từ 2 core trở lên, NHƯNG

  • Mỗi core có thể chạy tần số khác nhau
  • Mỗi core có thể chạy firmware khác nhau
  • Mỗi core có thể đảm nhiệm một nhiệm vụ riêng biệt

Ví dụ:

Core1 chạy 72MHz xử lý realtime
Core2 chạy 36MHz xử lý giao tiếp

Hai core này hoạt động gần như hai MCU độc lập nằm chung trong một chip.

2. SMP (Symmetric Multi-Processing)

SMP là mô hình CPU có từ 2 core trở lên, NHƯNG

  • Các core chạy cùng tần số
  • Chạy chung một hệ điều hành
  • Chia sẻ chung scheduler

Ví dụ

Core1 chạy 48MHz
Core2 chạy 48MHz

Trong bài viết này, tôi chỉ tập trung vào hệ thống single-core để dễ hiểu bản chất scheduler của FreeRTOS.

Single-core

Theo mặc định, thì freeRTOS sử dụng bộ lập lịch fixed-priority preemptive, với round-robin time-slicing cho các task có cùng độ ưu tiên (piority).

  • fixed-priority: bộ lặp lịch sẽ không thay đổi bất kì độ ưu tiên của task nào mà đã xác định trước, nhưng có thể thay đổi độ ưu tiên của một task tạm thời nhờ vào cơ chế kế thừa ưu tiên (priority inheritance).
  • preemptive: Task đang chạy có thể bị dừng lại ngay lập tức nếu có task ưu tiên cao hơn sẵn sàng chạy.
Danh sách task ready:
TaskA priority = 3 -> Chọn task nay để chạy 
TaskB priority = 2
TaskC priority = 1 

Note: Số càng lớn -> độ ưu tiên càng cao.

Như trong ví dụ trên nếu TaskA bị đưa vào danh sách block thì TaskB sẽ được chạy.

  • round-robin: các task có cùng độ ưu tiên thì sẽ lần lượt được chạy theo một khoảng thời gian.
  • time-slicing: Khoảng thời gian mà một task được phép chạy trước khi chuyển cpu cho task khác.
    • Mỗi task chỉ chạy đúng 1 time-slicing.
    • Sau mỗi tick interrupt→ chuyển sang task tiếp theo

Trong freeRTOS, sẽ sử dụng một timer phần cứng (SysTick, TIMx,...) để tạo ra ngắt định kì gọi là Tick interrupt. Cái này bạn có thể hiểu nó giống như nhịp tim của OS vậy đó.

  • Việc lựa chọn timer phần cứng nào là do bạn. Theo sự hiểu biết của tôi thì trong arduino, vì hk có systick nên đã sử dụng watchdog để tạo ngắt. Còn trong stm32 có systick.

Ví dụ:

#define configTICK_RATE_HZ   1000 // Nằm trong FreeRTOSConfig.h

→ Mỗi giây có 1000 tick → Mỗi tick là 1 ms.

Mỗi lần tick xảy ra

  • RTOS tăng biến đếm nội bộ.
  • Quyết định có cần context switch không.

Có 2 task trong hệ thống

TaskA piority = 2; (Tôi chọn task này chạy trước)
TaskB piority = 2;

image.png

Câu hỏi: "Nếu các task trong hệ thống cùng độ ưu tiên và bị tắt thì làm sao ?" Điều gì sẽ xảy ra

Nếu cấu hình

#define configUSE_TIME_SLICING  0

Thì

  • Scheduler sẽ không tự chuyển task sau mỗi tick.
  • Task nào đang chạy sẽ chạy cho đến khi: block hoặc tự gọi taskYIELD().

Khi đó

  • Task đầu tiên chiếm CPU sẽ chạy mãi.
  • Các task có cùng độ ưu tiên (piority) sẽ bị đói CPU.

Doc: https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/01-Tasks-and-co-routines/04-Task-scheduling#using-a-prioritised-preemptive-scheduler---avoiding-task-starvation


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí