Giáo trình Real time - Chương 2: Polling và Interrupt

Polling v.s Interrupt  
CHƯƠNG II:  
Polling và Interrupt  
Một hệ thống thời gian thực được gọi là “điều khiển sự kiện” có nghĩa là hệ thống  
đó phải có chức năng chính là phản ứng lại các sự kiện xảy ra trong môi trường  
của hệ thống. Vậy thì hệ thống phản ứng lại các sự kiện như thế nào. Hiện nay có  
hai phương pháp tiếp cận vấn đề này. Phương pháp đầu tiên là Polling hay Vòng  
lặp Polling.  
Hình 1 – Vòng lặp Polling  
Hãy xem đoạn code trong hình 1. Chương trình được bắt đầu bằng một vài cài đặt  
ban đầu cho hệ thống rồi truy cập vào trong một vòng lặp vô hạn, trong đó, các sự  
kiện mà hệ thống có thể phản ứng lại được kiểm tra. Khi có một sự kiện xảy ra,  
dịch vụ phản ứng lại sự kiện đó được kích hoạt.  
Tiến trình thực hiện của vòng lặp trên tỏ ra khá đơn giản và thích hợp với những  
hệ thống nhỏ không đòi hỏi quá gắt gao về mặt thời gian. Tuy nhiên, cũng có một  
số vấn đề cần bàn đến:  
- Thời gian phản ứng lại sự kiện phụ thuộc rất lớn vào vị trí mà chương trình  
đang thực hiện trong vòng lặp. Lấy ví dụ: Nếu sự kiện event_1 xảy ra ngay  
trước câu lệnh if(event_1) thì thời gian phản ứng là rất ngắn. Nhưng nếu sự  
kiện event_1 xảy ra ngay sau khi câu lệnh kiểm tra đó, chương trình lúc này  
phải quét toàn bộ vòng lặp và quay trở về điểm đầu và thực hiện dịch vụ  
của sự kiện event_1.  
- Và cũng là một hệ quả tất yếu, thời gian phản ứng cũng là một hàm của số  
lượng sự kiện được kích hoạt tại một thời điểm và sau đó là thời gian thực  
hiện các dịch vụ trong một lần quét vòng lặp của chương trình.  
Võ Duy Thành – coinsking208@yahoo.com  
1/6  
Polling v.s Interrupt  
- Tất cả các sự kiện được chương trình đối xử một cách bình đẳng và không  
có sự ưu tiên nào cả.  
- Khi có một đặc tính mới, do đó là dịch vụ mới, được thêm vào chương trình,  
thời gian phản ứng lại dài thêm ra.  
Phương pháp tiếp cận thứ 2 là ngắt (Interrupt). Rất hữu dụng và cũng gây không ít  
khó khăn cho người lập trình. Ý tưởng của ngắt: sự xuất hiện của một sự kiện có  
thể “ngắt” tiến trình thực hiện của chương trình, “nhồi” thêm và thực hiện một tiến  
trình khác vào như hình 2. Khi tiến trình nhồi thêm được thực hiện xong, chương  
trình chính lại được thực hiện tiếp từ thời điểm bị ngắt. Tiến trình của sự kiện ngắt  
được thực hiện ngay lập tức mà không phải quan tâm đến chương trình chính.  
Những tiến trình như thế người ta gọi là “chương trình con dịch vụ ngắt”  
(Interrupt Service Routine) viết tắt ISR.  
Các thế hệ vi xử lý hiện nay thường thực hiện 3 loại ngắt khác nhau  
- Câu lệnh INT, hay nhiều khi còn được nhắc đến với cái tên là TRAP (bẫy).  
Nó như một câu lệnh để gọi một chương trình con đặc biệt. Chúng ta sẽ đề  
cập đến nó sau.  
- Các trường hợp đặc biệt của bộ xử lý. Các điều kiện lỗi như lỗi chia 0, lỗi  
truy cập bất hợp pháp vào bộ nhớ có thể được điều khiển thông qua cơ chế  
ngắt.  
Hình 2 - Ngắt  
Hai loại ngắt kể trên đồng bộ với việc thực hiện lệnh. Trong đó, INT chính là một  
câu lệnh và các lỗi đặc biệt của bộ xử lý chính là kết quả trực tiếp của việc thực  
hiện lệnh.  
Võ Duy Thành – coinsking208@yahoo.com  
2/6  
Polling v.s Interrupt  
Loại ngắt thứ 3 được tạo ra bởi sự kiện xảy ra bên ngoài bộ xử lý. Loại ngắt này  
được tạo ra bởi các I/O phần cứng và xảy ra không đồng bộ với việc thực hiện  
lệnh.  
Các ngắt ngoài không đồng bộ này:  
- Làm tối đa hoá hiệu suất và thông lượng của hệ thống máy tính  
- Gây ra phần lớn các lỗi và rắc rối cho người lập trình  
Hầu hết các bộ xử lý đều sử dụng lược đồ ngắt giống nhau. Hình 3 chỉ ra kiến trúc  
ngắt của Intel x86. 1kilo byte đầu tiên của bộ nhớ được giành cho bảng véctơ ngắt  
(Interrupt Vector Table). Mỗi một véctơ có 4 byte thể hiện địa chỉ (segment và  
offset) của chương trình con dịch vụ ngắt. Các véctơ này mang những ý nghĩa,  
chức năng khác nhau và được định nghĩa bởi kiến trúc của bộ xử lý. Ví dụ: véctơ 0  
là lỗi chia 0, véctơ 3 là breakpoint (lệnh ngắt INT 1byte)…  
Hình 3 - Ngắt - Bảng véctơ ngắt  
Một số véctơ được dành cho các ngắt ngoài. Trong PC, các véctơ 8 đến 15 và  
0x70 đến 0x77 được dành cho phần cứng.  
Tất cả các véctơ được truy cập thông qua lệnh ngắt , trong đó,
). Phần mềm hệ thống thường thiết lập các quy ước  
liên quan đến nhiều véctơ này. Ví dụ: PC BIOS sử dụng một số ngắt cho các dịch  
vụ phần cứng và LINUX sử dụng ngắt INT 0x80 để gọi dịch vụ của kernel.  
Sau đây là một ví dụ về việc sử dụng ngắt INT 0x80 của Linux.  
- Bộ xử lý lưu lại giá trị hiện thời của thanh ghi bộ đếm chương trình  
Program Counter (PC) và Code Segment (CS) vào ngăn xếp stack cùng với  
từ điều khiển trạng thái bộ xử lý Proccesor Status Word (PSW).  
Võ Duy Thành – coinsking208@yahoo.com  
3/6  
Polling v.s Interrupt  
- Byte thứ 2 trong câu lệnh INT là một chỉ số trong bảng véctơ ngắt để từ đó  
tìm được địa chỉ của chương trình con dịch vụ ngắt (ISR). Bộ xử lý nạp địa  
chỉ này vào thanh ghi PC và CS và việc thực hiện chương trình con được  
thực hiện từ điểm này.  
Hình 4 - Ngắt và hoạt động của ngắt  
- Kết thúc của ISR là câu lệnh IRET (Interrupt Return). Nó giải phóng PC và  
CS để nạp lại giá trị của chương trình chính và thực hiện tiếp lệnh tiếp theo  
sau lệnh INT.  
Lệnh INT cũng tương tự như lệnh gọi chương trình con CALL nhưng có đôi chút  
khác biệt: trong khi địa chỉ đích của lệnh CALL được nhúng vào trong câu lệnh đó  
thì với INT, ta không cần quan tâm đến địa chỉ của ISR. Địa chỉ của nó nầm trong  
bảng véctơ ngắt. Đây là một điểm thuận lợi cho việc truyền thông giữa chương  
trình được biên dịch và chương trình được tải, ví dụ như chương trình ứng dụng và  
hệ điều hành.  
Các ngắt ngoài có cách thức thực hiện như thể hiện trong hình 5. Một thiết bị bên  
ngoài đưa ra một “yêu cầu ngắt” Interrupt Request (IRQ). Khi bộ xử lý phản ứng  
lại bằng một xác nhận “chấp nhận ngắt” Interrupt Acknowledge (IAK), thiết bị đó  
sẽ gửi số thứ tự của véctơ ngắt lên bus dữ liệu. Bộ xử lý sau đó sẽ thiết lập một  
lệnh ngắt INT với chỉ số véctơ ngắt đã được cung cấp.  
Võ Duy Thành – coinsking208@yahoo.com  
4/6  
Polling v.s Interrupt  
Hình 5 – Ngắt cứng  
Trong thực tế, hầu hết các hệ thống đều sát nhập thêm một thiết bị ngoại vi đặc  
biệt được gọi là bộ điều khiển ngắt Interrupt Controller để quản lý các công việc  
chi tiết chẳng hạn như
g sẽ được ưu tiên hơn thiết bị khác ít quan trọng  
hơn.  
Ngắt có thể được
ạệu một cách có chọn lọc ở cả bộ điều khiển ngắt 8259  
hay ở chính thiết bị đó. Trên thực tế, việc kích hoạt và vô hiệu ngắt chính là điểm  
mấu chốt để thiết kế và thực thi một phần mềm thời gian thực.  
Cũng không có gì đáng ngạc nhiên khi nói rằng ngắt không đồng bộ có những vấn  
đề đáng bàn của nó. Để ý một ứng dụng thu thập dữ liệu dựa trên bộ A/D đa kênh  
như trên hình 6. Cứ mỗi khi bộ chuyển đổi A/D thu thập một tập hợp dữ liệu trên  
các kênh, nó ngắt bộ xử lý. Chương trình con dịch vu ngắt đọc dữ liệu và cất vào  
bộ nhớ đệm, nơi mà chương trình khác (còn gọi là chương trình nền) sẽ tiếp tục xử  
lý.  
Hình 6 – Ví dụ về ngắt  
Võ Duy Thành – coinsking208@yahoo.com  
5/6  
Polling v.s Interrupt  
Hoạt động điều khiển ngắt cho phép chúng ta phản ứng lại A/D một cách nhanh  
chóng trong khi bộ nhớ đệm tách chương trình nền khỏi nguồn dữ liệu, ví dụ,  
chương trình nền không cần quan tâm đến dữ liệu được từ đâu mà có được.  
Bây giờ hãy xem đến đoạn mã lệnh được ghi trong hình 6. Giả thiết chỉ là thí  
nghiệm, chúng ta cung cấp một tín hiệu biến đổi liên tục vào cả kênh 5 và 6. Đồng  
thời, giả thiết rằng chương trình sẽ không bị “fail” khi đang thực hiện đo tín hiệu  
đồng nhất.  
Trong thực tế, chương trình như đã viết chắc chắn sẽ bị “fail” bởi vì một ngắt có  
thể xảy ra trong khi cập nhật biến Cur_temp và cập nhật biến Set_temp với kết quả  
là giá trị của biến Cur_temp được cập nhật từ tập hợp dữ liệu cũ trước đó, còn giá  
trị của biến Set_temp được cập nhật từ tập hợp dữ liệu hiện thời. Như vậy, khi tín  
hiệu đầu vào thay đổi theo thời gian và các tập hợp dữ liệu được tách rời nhau ở  
các thời gian xác định, giá trị các biến sẽ khác nhau và do đó, chương trình sẽ  
“fail”.  
Đây chính là bản chất của vấn đề lập trình thời gian thực.
Có một giải pháp, dù không hay cho lắm, để giải quyết vấn đề này. Ta có thể dùng  
một lệnh vô hiệu hoá ngắt (CLI) trước khi cập nhật biến Cur_temp và kích hoạt  
ngắt bằng lệnh STI sau khi cập nhật biến Set_temp. Việc làm này giúp các ngắt  
tránh khỏi phiền phức của việc cập nhật liên tục như đã đề cập. Có vẻ như chúng  
ta đã sáng suốt khi sử dụng các lệnh CLI và STI như một chìa khoá cho một giải  
pháp đúng đắn, nhưng nếu chỉ đơn giản là rải các lệnh CLI và STI trong code của  
chương trình thì cũng chẳng khác gì việc sử dụng các lệnh “go to” và các biến  
toàn cục.  
Võ Duy Thành – coinsking208@yahoo.com  
6/6  
pdf 6 trang Thùy Anh 17200 Free
Bạn đang xem tài liệu "Giáo trình Real time - Chương 2: Polling và Interrupt", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfgiao_trinh_real_time_chuong_2_polling_va_interrupt.pdf