🌱 RTOS 06. Context Switch - Chuyển đổi ngữ cảnh giữa các Task
Một vấn đề quan trọng trong RTOS đó là việc chuyển đổi ngữ cảnh, việc một Task đang chạy phải dừng lại để nhường chỗ cho Task khác, sau đó khi trở lại hoạt động thì Task đó vẫn tiếp tục công việc cũ không hề đơn giản.
Vì vậy cần có những cơ chế riêng để thực hiện việc này, đó chính là cơ chế Context Switch - Chuyển đổi ngữ cảnh.
Các nội dung chính
- Khi nào cần gọi hàm lập lịch - Scheduler()?
- Context Switch - Chuyển đổi ngữ cảnh
- Trigger Context Switch sử dụng PendSV Exception
- PendSV Exception Handler
👉 Khi nào cần gọi hàm lập lịch - Scheduler()?
Khi xây dựng việc lập lịch cho RTOS, chúng ta cần có một list các Task cần được thực hiện, cụ thể, để quy định việc Task nào sẽ được thực hiện tiếp theo, chúng ta sẽ xây dựng một Queue - hàng đợi. Task nào đứng đầu Queue sẽ là task tiếp theo cần thực hiện.
Queue được xây dựng cho các Task sẽ giống như trong hình trên. Các task mới cần được thực hiện sẽ được đưa vào Queue này.
- Task có mức độ ưu tiên cao hơn sẽ được xếp trên các Task có mức độ ưu tiên thấp hơn.
- Task đến trước sẽ đứng trên Task đến sau nếu có cùng mức độ ưu tiên.
- Task có mức độ ưu tiên cao hơn task đang thực thi muốn thực hiện. Khi đó, task này sẽ nhảy lên đầu Queue, task đang thực thi sẽ phải nhường lại quyền điều khiển cho task đó. Lúc này, Kernel sẽ gọi hàm lập lịch Scheduler() để chuyển sang Task có mức ưu tiên cao hơn.
- Khi Task hiện tại kết thúc hoặc chủ động "nhường" tài nguyên, bằng cách gọi các hàm lập lịch như taskYIELD() hoặc vTaskDelay(), khi gọi hàm này, Task hiện tại sẽ ngưng làm việc trong thời gian delay, vì vậy, để tránh lãng phí tài nguyên hệ thống, Kernel sẽ gọi hàm lập lịch Scheduler() để chuyển qua Task khác.
- Khi hết thời gian Time-Slice, Kernel sẽ chuyển sang task tiếp theo để thực thi bằng cách gọi hàm lập lịch Scheduler().
- Task bị block do chờ tài nguyên như chờ semaphore, queue, hoặc mutex.
- Khi một ngắt xảy ra, OS cũng có thể cần gọi lại hàm lập lịch, ví dụ Scheduler có thể được gọi thông qua hàm như portYIELD_FROM_ISR() trong FreeRTOS.
- Sự kiện định kỳ từ Timer khi đếm hết timeout.
👉 Context Switch - Chuyển đổi ngữ cảnh
Việc chuyển đổi ngữ cảnh sinh ra với 2 mục đích:
- Lưu lại ngữ cảnh (dữ liệu) của Task đang thực thi trước khi chuyển qua task khác, ngữ cảnh này sẽ được lưu vào vùng nhớ TCB của Task.
- Lấy lại ngữ cảnh cũ của Task đang chuẩn bị được thực thi để tiếp tục task đó. Việc này ngược lại với việc trên, đó là lấy dữ liệu từ vùng nhớ TCB của Task tương ứng.
- SVC - supervisor call.
- PendSV Exception.
➤ Trigger Context Switch sử dụng PendSV Exception
PendSV (Pending Supervisor Call) là một loại exception đặc biệt trên vi điều khiển lõi ARM Cortex-M, được thiết kế để hỗ trợ quản lý ngữ cảnh (context switching) trong hệ điều hành thời gian thực (RTOS), giúp chuyển đổi giữa các task hiệu quả và đơn giản.
Trong RTOS thì PendSV luôn được cấu hình với mức ưu tiên cao nhất trong các ngắt có thể cấu hình, điều này đảm bảo nó chỉ được thực thi khi không có ngắt khác quan trọng hơn đang diễn ra.
PendSV chỉ được kích hoạt bằng phần mềm, bằng cách ghi vào thanh ghi SCB_ICSR (Interrupt Control and State Register).
➤ PendSV Exception Handler
Trong hàm xử lý ngắt PendSV_Handler cần lưu trạng thái của task cũ và khôi phục trạng thái của task mới, trạng thái nói đến ở đây chính là các thanh ghi của Core, các thanh ghi tính toán, thanh ghi status, thanh ghi chức năng đặc biệt.
Chính vì access đến các thanh ghi Core nên PendSV_Handler thường được viết bằng ngôn ngữ Assembly.
Về cơ bản RTOS Context Switch trong PendSV_Handler sẽ bao gồm 3 bước:
① Store Context of Current Task
Bước này cần lưu lại giá trị các thanh ghi cần thiết, các thanh ghi tính toán trong Stack Frame đã được lưu lại khi xảy ra Exception
② Switch Current Pointer
Cập nhật Process Stack Pointer (PSP) của task mới trước khi chạy task mới!
③ Restore Context of Next Task
Cập nhật ngữ cảnh của Task mới trước khi chạy, tương tự như
- Sau đó tiếp tục chạy task mới
Bài viết hay , dễ hiểu a
Trả lờiXóa