Trong một hệ thống thời gian thực một tác vụ có thể rơi vào một trong các trạng thái sau đây (xem hình 10.6):
- Sẵn sàng để chạy.
- Chạy.- Bị chặn.
- Chạy.- Bị chặn.
Khi một tác vụ lúc đầu được tạo ra, nó thường ở trạng thái sẵn sàng để chạy và được nhập vào trong danh sách tác vụ. Từ trạng thái này, tùy thuộc vào các thuật toán lập lịch trình, nhiệm vụ có thể trở thànhmột nhiệm vụ đang chạy. Theo các điều kiện của lịch ưu tiên, nhiệm vụ sẽ chạy nếu nó là nhiệm vụ ưu tiên cao nhất trong hệ thống và không phải đợi một nguồn tài nguyên. Một nhiệm vụ chạy trở thành một nhiệm vụ chặn nếu nó cần một nguồn tài nguyên chưa có sẵn. Ví dụ, một tác vụ có thể cần dữ liệu từ một bộ chuyển đổi A/D (bộ chuyển đổi từ tương tự sang số) và bị chặn cho đến khi bộ chuyển đổi A/D hoàn tất. Một khi các nguồn tài nguyên có thể được truy suất, các nhiệm vụ bị chặn trở thành một nhiệm vụ chạy nếu nó là nhiệm vụ ưu tiên cao nhất trong hệ thống, nếu không nó chuyển sang trạng thái sẵn sàng.Chỉ một nhiệm vụ đang chạy có thể bị chặn. Một nhiệm vụ sẵn sàng chạy không thể bị chặn.
Khi một nhiệm vụ chuyển từ trạng thái này sang trạng thái khác, bộ vi xử lý lưu bối cảnh của nhiệm vụ đang chạy vào trong bộ nhớ, nạp bối cảnh nhiệm vụ mới từ bộ nhớ, và sau đó thực thi lệnh mới như yêu cầu.
Khi một nhiệm vụ chuyển từ trạng thái này sang trạng thái khác, bộ vi xử lý lưu bối cảnh của nhiệm vụ đang chạy vào trong bộ nhớ, nạp bối cảnh nhiệm vụ mới từ bộ nhớ, và sau đó thực thi lệnh mới như yêu cầu.
Hình 10.6 Trạng thái nhiệm vụ
Các hạt nhân kernel thường cung cấp một giao diện để thao tác các hoạt động công việc. Nhiệm vụ điển hình hoạt động là:
- Tạo một tác vụ- Xóa một tác vụ- Thay đổi các ưu tiên của một tác vụ- Thay đổi trạng thái của một tác vụ
10.3 Trình phục vụ RTOS
Trình phục vụ RTOS là tiện ích được cung cấp bởi các kernel có thể giúp các nhà phát triển tạo ra các tác vụ thời gian thực hiệu quả. Ví dụ, một công việc có thể sử dụng các trình phục vụ thời gian để có được ngày và thời gian hiện tại. Một số các trình phục vụ này là:
- Trình phục vụ ngắt
- Trình phục vụ thời gian- Trình phục vụ quản lý thiết bị- Trình phục vụ quản lý bộ nhớ- Trình phục vụ đầu vào-đầu ra
- Trình phục vụ thời gian- Trình phục vụ quản lý thiết bị- Trình phục vụ quản lý bộ nhớ- Trình phục vụ đầu vào-đầu ra
10.4 Đồng bộ hóa và Công cụ thông điệp
Đồng bộ hóa và công cụ thông điệp là các cấu trúc hạt nhân giúp các nhà phát triển tạo ra các ứng dụng thời gian thực. Một số các dịch vụ này là:
- Semaphores : cờ hiệu
- Event flags: Cờ sự kiện
- Event flags: Cờ sự kiện
- Mailboxes : hộp thư
- Pipes: Đường ống
- Message queues : hàng đợi thông điệp
Semaphores được sử dụng để đồng bộ truy cập vào tài nguyên chia sẻ, chẳng hạn như khu vực dữ liệu chung. Cờ sự kiện được sử dụng để đồng bộ hóa các hoạt động tác vụ nội bộ. Hộp thư, đường ống, và hàng đợi thông điệp được sử dụng để gửi tin nhắn giữa các tác vụ.
10.5 Trình biên dịch PIC C CCS hỗ trợ RTOS
rtos_run () khởi tạo các hoạt động của RTOS. Tất cả các hoạt động kiểm soát tác vụ được thực thi sau khi gọi hàm này
rtos_terminate () Chức năng này kết thúc việc thực thi tất cả các tác vụ RTOS. Quyền kiểm soát được trả về chương trình gốc không có RTOS.
rtos_enable () nhận tên của một tác vụ như là một đối số. Hàm này cho phép một tác vụ thực thi tại tốc độ chỉ định. Tất cả tác vụ được cho phép theo mặc định.
rtos_disable() nhận tên của tác vụ như là một đối số. Hàm này vô hiệu hóa tác vụ để nó không còn được gọi bởi rtos_run() trừ khi nó được cho phép lại bằng hàm rtos_enable ()
rtos_ yield() khi gọi từ bên trong một tác vụ, trả lại điều khiển cho phần tiếp nhận. Tất cả các tác vụ nên gọi hàm này để giải phóng vi xữ lý để các tác vụ khác có thể sử dụng thời gian đê xữ lý tiếp
rtos_msg_send() nhận tên tác vụ và 1 byte làm đối số. Hàm này gửi byte đến tác vụ chỉ định, nó được đặt trong hàng đợi thông điệp của tác vụ.
rtos_msg_read() đọc byte đặt trong hàng đợi thông điệp của tác vụ
rtos_msg_poll () trả về true nếu có dữ liệu trong hàng đợi thông điệp của tác vụ. Hàm này nên gọi trước khi đọc 1 byte từ hàm đợi thông điệp của tác vụ
rtos_signal () nhận một tên cờ hiệu (semaphore) và tăng cờ hiệu.
rtos_wait() nhận một tên semaphore và chờ tài nguyên có liên quan đến cờ hiệu có giá trị. Giá trị cờ hiệu giảm để cho tác vụ có thể chờ tài nguyên
rtos_await() Chức năng này chỉ có thể được sử dụng trong một tác vụ RTOS. Chức năng này chờ biểu thức là đúng trước khi tiếp tục thực hiện phần mã còn lại của của tác vụ RTOS. Chức năng này cho phép các tác vụ khác thực hiện nhiệm vụ trong khi chờ đợi cho biểu thức là đúng.
rtos_overrun () nhận một tên nhiệm vụ như một tham số, và hàm trả về true nếu công việc đó đã bị quá thời gian được phân bổ.
rtos_stats () trả về số liệu thống kê cụ thể về một nhiệm vụ cụ thể. Các số liệu thống kê thời gian chạynhiệm vụ tối thiểu và tối đa và tổng thời gian tác vụ chạy. Tên tác vụ và các loại thống kê được quy định như đối số cho hàm.
10.5.1 Chuẩn bị cho RTOS
Ngoài các chức năng trên, các lệnh tiền xử lý rtos #use () phải được quy định tại phần đầu của chương trình trước khi gọi bất kỳ chức năng RTOS. Các định dạng của lệnh tiền xử lý này là: rtos #use (timer = n,minor_cycle=m)
nơi timer được gán từ 0 đến 4 và xác định bộ định thời được sử dụng bởi RTOS và minor_cycle là thời gian dài nhất bất kỳ tác vụ sẽ chạy. Số đã nhập ở đây phải được theo sau bởi s, ms, us, hoặc ns.
Ngoài ra, một tùy chọn statistics (tùy chọn thống kê), khai báo sau tùy chọn minor_cycle, khi đó chương trình biên dịch sẽ theo dõi thời gian tối đa và tối thiểu tác vụ sử dụng tại mỗi lần được gọi và tổng thời gian tác vụ sử dụng
10.5.2 Khai báo tác vụ
#task(rate=n, max=m, queue=p)
Nơi Rate chỉ định độ thường xuyên mà tác vụ được gọi, đi kèm theo sau là đơn vị s, ms, us, hoặc ns. max chỉ định một tác vụ sẻ có bao nhiêu thời gian xữ lý sẻ sữ dụng trong một thực thi của tác vụ . Thời gian chỉ định ở đây phải bằng hoặc nhỏ hơn thời gian chỉ định trong minor_cycle. queue là một tùy chọn, nó quy định số bye để dành cho tác vụ để nhận thông điệp từ tác vụ khác. Giá trị mặt định là 0
Ví dụ minh họa dưới đây, một tác vụ gọi my_ticks sau mỗi 20 ms, và quy định không sử dụng quá 100 ms thời gian xữ lý , và không sử dụng tùy chọn queue
#task(rate=20ms, max=100ms)
void my_ticks()
{
...........
...........
}
void my_ticks()
{
...........
...........
}
No comments:
Post a Comment