Tổng quan về hệ điều hành thời gian thực RTOS

Related Articles

Nếu đã là dân công nghệ tiên tiến, chắc rằng bạn chẳng lạ lẫm gì với hệ quản lý và điều hành hay OS, thế nhưng bạn đã nghe RTOS khi nào chưa ? RTOS là cái gì và cách nó hoạt động giải trí như thế nào ? Tất cả sẽ có trong bài viết ngày ngày hôm nay .

Rtos là gì ?

RTOS là viết tắt của cụm từ Real-time operating system hay hệ điều hành thời gian thực thường được nhúng trong các dòng vi điều khiển dùng để điều khiển thiết bị một cách nhanh chóng và đa nhiệm (multi tasking). Để hiểu rõ ràng nó là gì trước hết hãy làm rõ khái niệm về hệ điều hành đã.

Hệ điều hành (tiếng Anh: Operating System – viết tắt: OS) là một phần mềm dùng để điều hành, quản lý toàn bộ tất cả thành phần (bao gồm cả phần cứng và phần mềm) của thiết bị điện tử.

Nói đơn thuần, hệ điều hành quản lý giống như hội đồng quản trị vậy. Họ có quyền quyết định hành động ai làm gì và thời hạn như thế nào. Các nhân viên cấp dưới cũng như những ứng dụng, nhận lệnh của cấp trên và thực thi những việc làm theo đúng tính năng của mình .

Vậy hệ quản lý thời hạn thực với hệ điều hành quản lý thông thường khác gì nhau ?

  • Hệ điều hành thông thường (non-realtime): như Window, linux, android, ios… chính là thứ mà chúng ta sử dụng hằng ngày. Khi mở một phần mềm trên đó, có thể bạn phải chờ nó tải rất lâu, việc chờ đợi này cũng không ảnh hưởng gì cả. Bởi vì đa số phần mềm đó tương tác với con người chứ ít tương tác với các phần mềm hoặc thiết bị khác
  • Hệ điều hành thời gian thực (realtime): sinh ra cho các tác vụ cần sự phản hồi nhanh của hệ thống, thường được nhúng trong các loại vi điều khiển và không có giao diện (GUI) tương tác với người dùng. Chúng cần phản hồi nhanh bởi vì đa số các tác vụ tương tác với thiết bị, máy móc khác chứ không phải con người. Các tài nguyên bên trong rất hữu hạn nên chỉ một sự chậm trễ cũng có thể làm hệ thống làm việc hoàn toàn sai lệch.

Bạn cứ thử tưởng tượng một hệ quản lý và điều hành đang chạy những tác vụ điều khiển và tinh chỉnh tên lửa mà độ trễ chỉ 2 s. Với vận tốc của tên lửa cũng hoàn toàn có thể bắn lệch từ Hà Nội thành TP Hồ Chí Minh rồi .

Thực tế hệ quản lý và điều hành thời hạn thực còn chia thành 2 loại :

  • Soft-realtime: Sử dụng cho các ứng dụng cruise control (điều khiển hành trình) trong ô tô và các ứng dụng viễn thông
  • Hard-realtime: Sử dụng trong các ứng dụng điều khiển máy bay, động cơ điện

realtimesystem e1497500445332

Khi nào bạn cần sử dụng RTOS ?

Các ứng dụng không cần dùng RTOS

  • Ứng dụng đơn (ứng dụng chỉ có 1 chức năng)
  • Ứng dụng có vòng lặp đơn giản
  • Ứng dụng

Các ứng dụng cần RTOS

  • Ứng dụng nhiều trạng thái máy (States Machine)
  • Ứng dụng lớn
  • Ứng dụng liên quan tới các tác vụ xử lý nhanh, xử lý ảnh, âm thanh.

Nếu ứng dụng của bạn mà size chương trình lớn dần và độ phức tạp tăng lên thì RTOS sẽ rất hữu dụng trong trường hợp này, lúc đó RTOS sẽ chia những ứng dụng phức tạp thành những phần nhỏ hơn và dễ quản trị hơn .

RTOS được sử dụng rất nhiều khi lập trình ESP32, ESP8266, STM32 và những dòng chip khác .

Tại sao lại phải dùng RTOS ?

Chia sẻ tài nguyên một cách đơn thuần : cung ứng chính sách để phân loại những nhu yếu về bộ nhớ và ngoại vi của MCU

Dễ debug và tăng trưởng : Mọi người trong nhóm hoàn toàn có thể thao tác một cách độc lập, những lập trình viên thì hoàn toàn có thể tránh được những tương tác với ngắt, timer, với phần cứng ( cái này mình không khuyến khích lắm vì hiểu được phần cứng vẫn sẽ tốt hơn nhiều )

Tăng tính linh động và thuận tiện bảo dưỡng : trải qua API của RTOS, …

Cách hoạt động giải trí của Rtos

RTOS là một phân đoạn hoặc một phần của chương trình, trong đó nó xử lý việc điều phối những task, lập lịch và phân mức ưu tiên cho task, chớp lấy những thông điệp gửi đi từ task .

RTOS khá phức tạp, nói một cách dễ hiểu hơn là nó thực thi việc giải quyết và xử lý những trạng thái máy ( State Machine ). Các bạn hoàn toàn có thể tìm hiểu và khám phá tại bài viết States Machine và lập trình nhúng

Để xử lý một bài toán nhiều trạng thái máy, thường thì tất cả chúng ta sử dụng code sau :

while(1)
{ switch(state) { case 1: //Code for Task 1; state= 2; case 2: //Code for Task 2; state= 3; case 3: //Code for Task 3; state= 4; case 4: //Code for Task 4; state=1; }
}

Bạn hoàn toàn có thể thấy, chương trình sẽ thực thi từ states 1 tới states 4 sau đó quay vòng lại. Bất kì khi nào states đổi khác, chương trình sẽ nhảy qua ship hàng task đó .

Ví dụ : nếu trong task 1 có lệnh states = 4, thì ngay sau khi Task 1 được thực thi xong chương trình sẽ nhảy qua Task 4 mà bỏ lỡ Task 2 và 3 .

Nhược điểm của giải pháp này đó là tài nguyên sử dụng chung, vận tốc chuyển chậm khi đổi khác states bởi nó phải triển khai xong mỗi Task trước khi chuyển sang Task khác, khó trấn áp khi nhiều tác vụ ( Task )

Vậy nên RTOS sinh ra xử lý những điểm yếu kém trên .

RTOS hoạt động như thế nào

Nhân Kernel sẽ điều phối sự hoạt động giải trí của những tác vụ ( Task ), mỗi task sẽ có một mức ưu tiên ( prioritize ) và thực thi theo chu kì cố định và thắt chặt. Nếu có sự ảnh hưởng tác động như ngắt, tín hiệu hoặc tin nhắn giữa những Task, Kernel sẽ điều phối chuyển tới Task tương ứng với Code đó .

Sự vận động và di chuyển giữa những Task rất linh động, độ trễ thấp mang lại độ đáng tin cậy cao cho chương trình .

Các khái niệm trong hệ quản lý thời hạn thực RTOS

Kernel – Nhân

Kernel hay còn gọi là Nhân có nhiệm vụ quản lý và điều phối các Task. Mọi sự kiện (Even) như ngắt, Timer, data truyền tới… đều qua Kernel xử lý để quyết định xem nên làm gì tiếp theo.

Thời gian xử lý của Kernel thường rất nhanh nên độ trễ rất thấp.

kernel Rtos

Task – Tác vụ

Bạn cứ tưởng tượng một chương trình là một công ty, với ông to nhất là Giám đốc – Kernel. Ông này chỉ quản lý và điều hành và chả biết nhiệm vụ gì cả, để thực thi những nhiệm vụ khác nhau, công ty đó cần những nhân viên cấp dưới. Và những nhân viên cấp dưới đó gọi là những Task .

Nói đơn thuần, Task là một đoạn chương trình thực thi một hoặc nhiều yếu tố gì đó, được Kernel quản trị .

Kernel sẽ quản trị việc quy đổi giữa những task, nó sẽ lưu lại ngữ cảnh của task sắp bị hủy và Phục hồi lại ngữ cảnh của task tiếp theo bằng cách :

  • Kiểm tra thời gian thực thi đã được định nghĩa trước (time slice được tạo ra bởi ngắt systick)
  • Khi có các sự kiện unblocking một task có quyền cao hơn xảy ra (signal, queue, semaphore,…)
  • Khi task gọi hàm Yield() để ép Kernel chuyển sang các task khác mà không phải chờ cho hết time slice
  • Khi khởi động thì kernel sẽ tạo ra một task mặc định gọi là Idle Task.

Task States – Trạng thái Task

Một ông nhân viên cấp dưới thì cũng có lúc này lúc kia, lúc rảnh rỗi, lúc đang thao tác, hay cũng có lúc nghỉ vì … vợ đẻ. Những lúc như vậy Kernel phải điều phối làm thế nào cho chương trình chạy hài hòa và hợp lý .

Không thể bắt ông đang trông vợ đẻ đi làm được, đúng không ?

Một task trong RTOS thường có những trạng thái như sau

Trạng thái Task trong Rtos

  • RUNNING: đang thực thi
  • READY: sẵn sàng để thực hiện
  • WAITING: chờ sự kiện
  • INACTIVE: không được kích hoạt

Scheduler – Lập lịch

Nói đơn thuần thì Scheduler là một bé thư kí hoặc trợ lý của ông giám đốc Kernel. Bé này sẽ có trách nhiệm nhắc nhở ông xếp mình cần làm gì tại những thời gian khác nhau .

Đây là 1 thành phần của kernel quyết định hành động task nào được thực thi. Có 1 số ít luật cho scheduling như :

Cooperative: giống với lập trình thông thường, mỗi task chỉ có thể thực thi khi task đang chạy dừng lại, nhược điểm của nó là task này có thể dùng hết tất cả tài nguyên của CPU

Round-robin: mỗi task được thực hiện trong thời gian định trước (time slice) và không có ưu tiên.

Round robin

Priority base: Task được phân quyền cao nhất sẽ được thực hiện trước, nếu các task có cùng quyền như nhau thì sẽ giống với round-robin, các task có mức ưu tiên thấp hơn sẽ được thực hiện cho đến cuối time slice

Priority based e1497687849850

Priority-based pre-emptive: Các task có mức ưu tiên cao nhất luôn nhường các task có mức ưu tiên thấp hơn thực thi trước.

Priority based pre emptive

Kết nối Inter-task & Chia sẻ tài nguyên

Để cho công ty quản lý và vận hành được trơn chu, thì những nhân viên cấp dưới cũng phải liên lạc và trao đổi với nhau. Làm coder thì cũng phải trò chuyện với ông làm Sales để xem mình code vậy có bán được không, làm nhân viên cấp dưới cũng phải hiểu những nhiệm vụ của nhau, chứ không xung đột tài nguyên là vỡ đầu chảy máu .

Vậy nên task cần phải liên kết và trao đổi tài liệu với nhau để hoàn toàn có thể san sẻ tài nguyên, có 1 số ít khái niệm cần quan tâm :

Với Inter-task Communication :

  • Signal Events – Đồng bộ các task
  • Message queue – Trao đổi tin nhắn giữa các task trong hoạt động giống như FIFO
  • Mail queue – Trao đổi dữ liệu giữa các task sử dụng hằng đợi của khối bộ nhớ

Với Resource Sharing :

  • Semaphores – Truy xuất tài nguyên liên tục từ các task khác nhau
  • Mutex – Đồng bộ hóa truy cập tài nguyên sử dụng Mutual Exclusion

Signal event

Signal sự kiện được dùng để đồng nhất những task, ví dụ như bắt task phải thực thi tại một sự kiện nào đó được định sẵn

Ví dụ : Một cái máy giặt có 2 task là Task A điều khiển và tinh chỉnh động cơ, Task B đọc mức nước từ cảm ứng nước đầu vào

  • Task A cần phải chờ nước đầy trước khi khởi động động cơ. Việc này có thể thực hiện được bằng cách sử dụng signal event
  • Task A phải chờ signal event từ Task B trước khi khởi động động cơ
  • Khi phát hiện nước đã đạt tới mức yêu cầu thì Task B sẽ gửi tín hiệu tới Task A

Với trường hợp này thì task sẽ đợi tín hiệu trước khi thực thi, nó sẽ nằm trong trạng thái là WAITING cho đến khi signal được set. Ngoài ra ta hoàn toàn có thể set 1 hoặc nhiều signal trong bất kể những task nào khác .

Mỗi task có thể được gán tối đa là 32 signal event

Message queue – Hàng đợi tin nhắn

Nói nôm na là một group chat trong một công ty để trao đổi giữa những thành viên .

Message queue là cơ chế cho phép các task có thể kết nối với nhau, nó là một FIFO ( First In First Out) buffer được định nghĩa bởi độ dài (số phần tử mà buffer có thể lưu trữ) và kích thước dữ liệu (kích thước của các thành phần trong buffer).

Một ứng dụng tiêu biểu vượt trội là buffer cho Serial I / O, buffer cho lệnh được gửi tới task

Task hoàn toàn có thể ghi vào hằng đợi ( queue )

  • Task sẽ bị khóa (block) khi gửi dữ liệu tới một message queue đầy đủ
  • Task sẽ hết bị khóa (unblock) khi bộ nhớ trong message queue trống
  • Trường hợp nhiều task mà bị block thì task với mức ưu tiên cao nhất sẽ được unblock trước

Task hoàn toàn có thể đọc từ hằng đợi ( queue )

  • Task sẽ bị block nếu message queue trống
  • Task sẽ được unblock nếu có dữ liệu trong message queue.
  • Tương tự ghi thì task được unblock dựa trên mức độ ưu tiên

Ví dụ :

Message queue ex

Mail queue

Nói nôm na giống như những bạn trao đổi E-Mail giữa những nhân viên cấp dưới với nhau. Các email này sẽ gồm có nhiều thứ như văn bản và những file đính kèm .

Mail queue truyền tài liệu sẽ được truyền dưới dạng khối ( memory block ) thay vì dạng đơn. Mỗi memory block thì cần phải cấp phép trước khi đưa tài liệu vào và giải phóng sau khi đưa tài liệu ra .

Thao tác gửi tài liệu với mail queue

  1. Cấp phát bộ nhớ từ mail queue cho dữ liệu được đặt trong mail queue
  2. Lưu dữ liệu cần gửi vào bộ nhớ đã được cấp phát
  3. Đưa dữ liệu vào mail queue

Thao tác nhận tài liệu trong mail queue bởi task khác

  1. Lấy dữ liệu từ mail queue, sẽ có một hàm để trả lại cấu trúc/ đối tượng
  2. Lấy con trỏ chứa dữ liệu
  3. Giải phóng bộ nhớ sau khi sử dụng dữ liệu

Ví dụ :

Mail queue 2

Semaphore

Nói đơn thuần Semaphore là một thủ quỹ của công ty bạn vậy. Mỗi một công ty sẽ có 1 lượng tiền cố định và thắt chặt, vậy nên nếu nhân viên cấp dưới ông nào cũng đòi tiền để làm cái này cái kia, mà không lấy lại về cho công ty, thì chắc như đinh phá sản .

Trong vi điều khiển và tinh chỉnh tất cả chúng ta có Semaphore để quản trị những tài nguyên ( Resource ) như Ram, ngoại vi …

Được sử dụng để đồng nhất task với những sự kiện khác trong mạng lưới hệ thống. Có 2 loại

Binary semaphore

Semaphore là một mã thông tin giống như một mã thông tin được cho phép một tác vụ triển khai việc thực thi nếu tác vụ nhận được semaphore. Nếu không, tác vụ vẫn ở trạng thái khối và không hề thực thi trừ khi nó có được semaphore nhị phân

  • Có duy nhất 1 token
  • Chỉ có 1 hoạt động đồng bộ

Binary Semaphore defintion

Counting semaphore

Counting semaphore đưa ra những Token cho những Task sử dụng tài nguyên, nếu tài nguyên được sử dụng hết thì những Task còn lại sẽ phải chờ đến khi Tài nguyên được giải phóng trở lại

cc5541a7 c87f 4c4a 8ae5 709801e8ab3a

Couting semaphore được dùng để :

Counting sự kiện

  • Một event handler sẽ ‘give’ semaphore khi có event xảy ra (tăng giá trị đếm semaphore)
  • Một task handler sẽ ‘take’ semaphore khi nó thực thi sự kiện (giảm giá trị đếm semaphore)
  • Count value là khác nhau giữa số sự kiện xảy ra và số sự kiện được thực thi
  • Trong trường hợp counting event thì semaphore được khởi tạo giá trị đếm bằng 0

Resource management

  • Count value sẽ chỉ ra số resource sẵn có
  • Để điều khiển và kiểm soát được resource của task dựa trên count value của semaphore(giá trị giảm), nếu count value giảm xuống bằng 0 nghĩa là không có resource nào free.
  • Khi một task finish với resource thì nó sẽ give semaphore trở lại để tăng count value của semaphore.
  • Trong trường hợp resouce management thì count value sẽ bằng với giá trị max của count value khi semaphore được tạo.

Mutex

Mutex giống như ông thủ kho của công ty bạn vậy. Vì tài nguyên của công ty hữu hạn, giả sử khi nhân viên A đang mượn sử dụng cái đồng hồ bấm giờ, nếu nhân viên B tới mượn chiếc đồng hồ đó thì Mutex sẽ bắt nhân viên B chờ cho tới khi Nhân viên A trả lại.

Sử dụng cho việc loại trừ ( mutial exclution ), hoạt động giải trí như thể một token để bảo vệ tài nguyên được san sẻ. Một task nếu muốn truy vấn vào tài nguyên san sẻ

  • Cần yêu cầu (đợi) mutex trước khi truy cập vào tài nguyên chia sẻ (Sharing Resourse)
  • Đưa ra token khi kết thúc với tài nguyên.

Tại mỗi một thời gian thì chỉ có 1 task có được mutex. Những task khác muốn cùng mutex thì phải block cho đến khi task cũ thả mutex ra .

Về cơ bản thì Mutex giống như binary semaphore nhưng được sử dụng cho việc loại trừ chứ không phải đồng điệu. Ngoài ra thì nó gồm có chính sách thừa kế mức độ ưu tiên ( Priority inheritance mechanism ) để giảm thiểu yếu tố đảo ngược ưu tiên, chính sách này hoàn toàn có thể hiểu đơn thuần qua ví dụ sau :

  • Task A (low priority) yêu cầu mutex
  • Task B (high priority) muốn yêu cầu cùng mutex trên.
  • Mức độ ưu tiên của Task A sẽ được đưa tạm về Task B để cho phép Task A được thực thi
  • Task A sẽ thả mutex ra, mức độ ưu tiên sẽ được khôi phục lại và cho phép Task B tiếp tục thực thi.

Kết

Và đó là tổng thể những kim chỉ nan về hệ quản lý thời hạn thực RTOS, hoàn toàn có thể nghe nói thì rất là mông lung, huyền ảo và có phần hại não. Nhưng thực ra nó cũng không khó chút nào .

Vậy nên hãy liên tục đến với những bài tiếp theo để biết RTOS hoạt động giải trí trên STM32 như thế nào nhé !

Bài viết này được tìm hiểu thêm tại nguồn : học arm, thanhnt, deviot … và 1 số ít nguồn quốc tế khác

Nếu thấy hay, hãy like và tham gia vào nhóm những người đồng đội Nghiện Lập Trình để giao lưu và học hỏi nhé !

4.7 / 5 – ( 8 bầu chọn )

More on this topic

Comments

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Advertismentspot_img

Popular stories