Skip to main content

Một số khái niệm hay dùng khi làm việc với RTOS

Brief
Góp nhặt một số kiến thức hay dùng khi làm việc với các hệ điều hành thời gian thực.
1. Mutex
Mutex là gì?
Mutual exclusion:
Trên một hệ điều hành thường có nhiều chương trình (hay tác vụ - task) chạy đồng thời. Mutex giúp ngăn chặn việc hai task cùng truy cập vào 1 tài nguyên (memory, register gọi chung là critical section) của hệ thống trong cùng một thời điểm.

Ví dụ, ta có 1 cái FIFO, task 1 đang read FIFO, task 2 lại write FIFO, nếu task 1 chưa lấy xong phần dữ liệu cần thiết mà task 2 lại write đè vào đúng vị trí task 1 đang read, nó sẽ làm sai lệch dữ liệu mà task 1 đang đọc.

Lưu ý: Cơ chế mutex được dùng trong cả thiết kế hardware và software.

Dùng trong chương trình như thế nào?
Hiểu đơn giản, mutex giống như cái khóa tủ dùng chung khi vào hiệu sách hay siêu thị. Để mở được tủ thì phải có khóa. Dùng xong tủ thì phải trả lại chìa khóa lại cho thằng khác dùng
ví dụ 1:
void task1()
{
       //Đợi lấy chìa khóa để mở tủ
       osMutexWait(); 
       //Cất mủ, cặp, túi sách...
       @to do
       //Trả chìa khóa khi xong việc
       osMutexRelease();
}


Semaphore là gì?
Semaphore là 1 cái advance mutex. Dùng để quản lý và bảo vệ tài nguyên dùng chung(share resource)
Mutex được gọi là 1 cái binary semaphore.
Nguyên tắc hoạt động của semaphore như hình dưới:
Nó giống như 1 cái hàng đợi (queue). Các thread/task khác nhau khi có yêu cầu sử dụng tài nguyên dùng chung sẽ bị tống vào hàng đợi này. Khi nhận được semaphore token thì thread nào được tống vào queue trước thì sử dụng tài nguyên trước. Sau đó nó lại release ra cho thread khác dùng.


Dùng như thế nào?
Cách dùng tương tự giống mutex

Sự khác nhau giữa Semaphores và mutexes

Semaphore hỗ trợ multi process. Như trên ví dụ 1:với mutex thằng nào(task/process) lock tủ thì chính thằng đó phải ra unlock tủ. Thằng semaphore cho phép thằng khác unlock cái tủ đó nếu cần thiết
Mutex hỗ trợ cái priority inversion (nôm na là mỗi khi gọi hàm os_wait_mutex (đợi chìa khóa) - hàm này làm tăng độ ưu tiên của task chứa nó, độ ưu tiên của task này sẽ bằng độ ưu tiên của task đang chạy, giúp tránh tình trạng deadlock của hệ thống). Xem thêm
Khi một task đang giữ mutex. Hệ điều hành cho phép xóa cái mutex đó khi cần thiết. Semaphore không hỗ trợ cơ chế này.

Semaphores vs. mutexes

mutex is essentially the same thing as a binary semaphore and sometimes uses the same basic implementation. The differences between them are:
  1. Mutexes have a concept of an owner, which is the process that locked the mutex. Only the process that locked the mutex can unlock it. In contrast, a semaphore has no concept of an owner. Any process can unlock a semaphore.
  2. Unlike semaphores, mutexes provide priority inversion safety. Since the mutex knows its current owner, it is possible to promote the priority of the owner whenever a higher-priority task starts waiting on the mutex.
  3. Mutexes also provide deletion safety, where the process holding the mutex cannot be accidentally deleted. Semaphores do not provide this.


Mailbox là gì?
Nó là 1 cái "hôp thư" :D. Một mailbox chứa nhiều lá thư (messages).
Thực ra nó là một cái FIFO viết cho RTOS.
Nó thường dùng để trung chuyển dữ liệu giữa các task.



Ví dụ: Cách sử dụng mailbox trong RTX
Định nghĩa một mailbox gồm 20 messages
os_mbx_declare (mailbox1, 20);
Khởi tạo mailbox
os_mbx_init (&mailbox1, sizeof(mailbox1));
Kiểm tra mailbox còn chỗ trống để cho tiếp message mới vào không?
if (os_mbx_check (&mailbox1) == 0) {
    printf("Mailbox is full.\n");
  }
Cho thêm message mới vào mailbox
os_mbx_send (&mailbox1, msg, 0xFFFF);
Lấy message ra để xử lý. Sau đó size của mailbox sẽ giảm đi 1.
  void *msg;
   ..
  if (os_mbx_wait (&mailbox1, &msg, 10) == OS_R_TMO) {
    printf ("Wait message timeout!\n");
    }
  else {
    /* process message here */
    free (msg);
  }

4. Deadlock
Đây là khái niệm mô tả 1 trong những trạng thái treo của hệ thống. Nó xảy ra khi hai (hoặc nhiều) luồng đứng đợi luồng kia chạy xong rồi mới hoạt động tiếp. Giống như là 2 thằng nhân viên cùng làm việc trong 1 phòng và cùng nói một câu:
"Mày làm xong việc của mày thì tao mới làm tiếp được"
Kết quả là: công việc mãi không được hoàn thành đến khi thằng sếp về và cho cả 2 thằng out of jobs (reset hệ thống :D).

5. Round-Robin (Hay Round - Robin Scheduling)
Nó là gì?
Là một thuật toán giúp quản lý các task (process hoặc job...vvv) chạy "đồng thời" hay là chạy song song thì đúng hơn.
Chương trình sẽ phân chia ra các "time slice"(hoặc time slot) giống như chia 1 cái bánh hình tròn. Về cơ bản, cái bánh cứ quay tròn, đến lượt thằng task nào thì thằng ấy gặm (sử dụng CPU và cái tài nguyên khác)  hết phần của mình thì thôi.
Thường thì, các miếng bánh được cắt bằng nhau cho tất cả các task, và các task cũng được thực hiện một cách tuần tự. Vấn đề nảy sinh là?
- Thời gian thực hiện task lớn hơn time-slice?
Task đó chạy hết time-slice, nó sẽ hold-on (suspended, hay bị CPU seize). Đến vòng lặp sau, thì nó lại tiếp tục chạy tiếp...cứ như thế đến khi xong task thì thôi
Ví dụ: Time slot là 100 ms, Task A chạy mất 270 ms
Vòng 1 nó(Task A) được cấp phát 100 ms, nó chạy 100 ms đầu của 270 ms
Vòng 2 nó lại được cấp phát 100ms, nó chạy tiếp 100 ms của task
Vòng 3 nó cũng được cấp 100 ms để làm việc, nó chỉ sử dụng 70 ms là task done, sau đó CPU sẽ "ngồi chơi" trong khoảng 30 ms cho hết time-slot, sau đó nó lại chuyển sang time-slot của task tiếp theo
- Thời gian thực hiện task nhỏ time-slice?
Điều này đơn giản, ta làm xong việc sớm thì ta được ngồi chơi..

Trong thực tế có vài biến thể của RRS,
- Trong bàn ăn, sẽ có thằng đói ít, thằng đói nhiều, mức độ muốn ăn ngay của bọn nó luôn luôn khác nhau . Ta gọi cái "mức độ muốn ăn ngay" này là priority của task.
Để xử lý vấn đề này, sau khi task 1 hoàn thành, RRS sẽ quyết định task nào được chạy tiếp theo phụ thuộc vào priority của task, thằng nào có priority cao hơn thì thằng đó được chạy trước. Nếu có hơn 2 task có cùng priority, thì thằng nào có TaskId thấp hơn thì được gọi trước. (Ngoài ra còn 1 số cách phân xử nữa..tùy thuộc OS)
- Để giải quyết vấn đề "ngồi chơi"
khi task xong sớm?
Người ta tạo ra các RRS có time-slot không đều nhau. RRS sẽ call thằng task nào ready (hoặc có priority cao hơn) thực hiện ngay sau khi một task done
Ví dụ về RRS(Hình 2)
- Hình 1 là cách lập lịch cho các task dựa hoàn toàn vào priority của task. Trong bất kỳ 1 thời điểm của hệ thống, task nào raise priority lên cao nhất thì task đó được chạy.
- Hình 2, mặc dù priority cao hơn running-task nhưng, task đó vẫn phải đợi running task complete thì mới được thực hiện.

Dùng như thế nào?
- Với trường hợp sử dụng RTOS, sẽ có một hằng số trong file nào đó mô tả giá trị của time_slot
Với RTX thì thông số về Round-Robin sẽ đặt trong file RTX_config.c
#define OS_ROBIN       1 // allow use Round Robin or not
#define OS_ROBINTOUT   5 //It is specified in number of system timer ticks, chính là giá trị của time-slice

- Non-OS: ...


Một số từ mới:
Concurrent:


Comments

Post a Comment

Popular posts from this blog

[Git] Handle trailing space when patching with git

After complete coding one module in development branch. Next phase is merging. Obviously, you can merge source code automatically without no errors happen. However, life is not dream. Create a patch git diff HEAD > newTariff.patch Apply patch git apply newTariff.patch then problem happens Problem git apply newTariff.patch:106: trailing whitespace. patch does not apply Route cause: Nguyên nhân: Do trong source code có những dấu space thừa (ô vuông màu đỏ hình dưới) Some whitespaces is existed in your patch. (red area in below pictures) Fix Clean white space and patch again. Cách khắc phục Xóa những dấu space này đi và thực hiện patch lại Make up after complete coding. Find and clean whitespace before create patch file. Sửa sau khi code xong Kiểm tra sau khi code xong có lỗi này không git diff HEAD --check Prevent whitespace by manually when typing source code Sửa ngay khi đang code =>Bật chức năng hiển thị các dấu whitespace, hoặc remove trailing ...

How to test frame buffer in linux

The intended goal of this article is to provide the user with enough information so they can display an image onto a screen of their choosing. How to re-build frame buffer testing application. Base knowledge http://trac.gateworks.com/wiki/OpenEmbedded/Video_Out Frame buffer test application - rebuild fb-test-app step 1: Download soure code ( git installed on your machine and account in git-hub is required) https://github.com/prpplague/fb-test-app Command in git: git init git clone https://github.com/prpplague/fb-test-app.git step 2: Change makefile vi Makefile //open Makefile by vim editor :set nu //show line number replace from line 6 to line 12 by folow code: CC=arm-linux-gnueabi-gcc CFLAGS=-02 -Wall Save change command :wq step 3: Rebuid Type “make” command step 4: Copy execute file to target system by filezilla or something like that step 5: Remote target by root account, change mode of execute file (what copied from host) ...

[Vi] Công nghệ phát triển ngược đời - How is AI harming my world

Tiếng cười khanh khách của mấy cậu sinh viên quốc tế người Bắc Ấn sau bài kiểm tra cuối khóa (a final exam) làm gã thấy buồn một góc tâm hồn. Sự trống rỗng ngay lập tức xâm chiếm lấy tâm trí gã sau khi nộp bài môn thi cuối cùng của kỳ học. Gã hiểu gã quá mà, gã đang cố gắng giải thích cho nỗi nhục của chính bản thân ở bên trong. Đầu gã thoáng nghĩ về cái lần thi cuối kỳ một môn học ở bậc thạc sỹ nơi quê nhà hơn mười năm về trước, cái ánh mắt khinh bỉ đến ám ảnh của một anh dọn vệ sinh dành cho những học viên cao học đang quay cóp trong giờ thi của một trường đại học hàng đầu quốc gia như vết dao khứa vào lòng tự trọng của gã. Vết thương vẫn nhói đau lại khi những mùa thi đến. Một lão già sinh viên quốc tế ranh ma. Gã đang học lại cái thứ mà gã đã học từ hai mươi năm về trước với một thứ ngôn ngữ không mới và cái tâm bằng sắt nung. Kinh nghiệm làm việc chuyên môn lâu năm cộng với việc vừa được trang bị thứ vũ khí khoa học tối tân AI (Trí truệ nhân tạo) khiến lão trở thành sát thủ trong ...