Interrupt Là Gì

*

Note này nằm trong series tập hợp các khái niệm xuất hiện khi mới làm quen với lập trình hệ thống nhúng, các khái niệm này có thể bắt nguồn từ tên thiết bị, tên hiện tượng hoặc một kĩ thuật nào đó, ….

Bạn đang xem: Interrupt là gì

Khái niệm đầu tiên mà tôi muốn liệt kê là interrupt. 

Interrupt có thể hiểu là một tín hiệu (tín hiệu vật lý hoặc tín hiệu logic) bắn tới processor. Tín hiệu này gây ra bởi phần cứng hoặc phần mềm, đại diện cho một event cần được xử lí ngay lập tức.

Tín hiệu vật lý có thể hiểu là tín hiệu phát sinh từ các nguồn vật lý (vi điều khiển, nút nhấn, công tắc, …….), có thể đo – đếm được.

Tín hiệu logic có thể hiểu là các lệnh, các lời gọi hàm….

Hardware interrupt: thuộc kiểu asynch. Hành động init hardware interrupt còn gọi là IRQ. Số lượng hardware interrupt bị giới hạn bởi số đường IRQ của processor.

Software interrupt: thuộc kiểu synch, gây ra bởi exceptional condition trong nội tại processor (trường hợp này có thể gọi là exception hoặc trap), hoặc gây ra bởi một instruction đặc biệt trong instruction set. Số lượng software interrupt có vẻ như không bị giới hạn

Interrupt tương tự với signal, khác biệt duy nhất giữa chúng là:

signal được sử dụng cho IPC, có trung gian là kernel (mediated by the kernel) và được xử lí bởi processes (handled by process),

interrupt thì có trung gian là processor (mediated by processor) và xử lý bởi kernel.

Kernel có thể pass một interrupt dưới dạng một signal tới process gây ra nó.

Interrupt là một kĩ thuật phổ biến áp dụng trong computer multitasking, đặc biệt là RTC. Cụ thể, hardware interrupt giúp cải thiện hiệu năng vì nó giúp phần cứng không phải wait trong một vòng lặp vô tận của phương pháp polling. Tức là trong lúc “chờ đợi” interrupt xảy ra, hệ thống vẫn có thể làm các việc khác, nếu có interrupt, hệ thống mới tạm ngưng công việc hiện tại để chuyển qua xử lý interrupt thông qua một Interrupt Handler hoặc Interrupt Service Routine (ISR)

Có thể phân loại interrupt theo 5 nhánh sau:

Maskable Interrupt – IRQ: hardware interrupt có thể bỏ qua nhờ cấu hình một bit trong IMR – interrupt mask register.

Non-maskable Interrupt – NMI: hardware interrupt không có Bit-mask đi kèm. NMI có thể là các interrupt không thể bỏ qua hoặc là interrupt của các task có độ ưu tiên cao nhất (liên quan tới timers và watchdog timer…)

Inter-processor Interrupt IPI: một case đặc biệt của interrupt, IPI được tạo ra bởi một processor để interrupt processor khác (trong hệ thống nhiều processor)

Software interrupt: interrupt do processor tạo ra khi thực thi một lệnh. Software interrupt thường dùng để implement system calls vì nó thường kéo theo một subroutine calls với sự thay đổi trong CPU ring level.

Spurious interrupt: hardware interrupt không mong muốn. thường được tạo ra bởi system condition.

Cũng có thể phân loại interrupt theo 2 kiểu như sau (dựa vào tác đọng của nó lên trạng thái của hệ thống lúc xảy ra interrupt):

precise interrupt: là loại interrupt khi xảy ra thì đảm bảo 4 tính chất sau cho hệ thống:

Thanh ghi PC được lưu lại

Tất cả lệnh nằm trước vị trí hiện thời của PC được thực thi hoàn chỉnh

Các lệnh mà PC chưa trỏ qua thì chưa thực hiện.

Trạng thái thực thi các lệnh mà PC đã trỏ qua được lưu lại

imprecise interrupt là loại interrupt khi xảy ra không đảm bảo 4 tính chất trên cho hệ thống.

Ta vẫn còn một cách khác để phân loại interrupt như sau:

Level- triggered – ngắt theo mức: Là một interrupt báo hiệu việc xuất hiện của nó bởi việc duy trì interrupt line ở mức logic cao hoặc thấp. Một thiết bị muốn bắn ra level-triggered interrupt sẽ duy trì IRQ line của nó ở mức ACTIVE (có thể là high hoặc low tùy định nghĩa của nsx), và duy trì level đó cho đến khi ISR hoàn tất. Level-triggered interrupt line có thể đựa chia sẽ giữa các thiết bị. Line này cần có pull-up hoặc pull-down resistor để line này tự động về giá trị mặc định khi không có interrupt xảy ra. Điểm hạn chế của kiểu interrupt này là interrupt của các thiết bị có mức ưu tiên cao có thể “che mất” interrupt của các thiết bị có mức ưu tiên thấp hơn….

Edge-triggered – ngắt sườn: Là một kiểu interrupt xảy ra khi có sự thay đổi của interrupt line (đi từ cao-thấp hoặc thấp – cao), hay nói cách khác là khi interrupt signal có sự thay đổi giá trị (tăng hoặc giảm). Các thiết bị có thể chia sẻ 1 edge-triggered interrupt line.

Hybrid Interrupt – kiểu lai: Một số hệ thống sử dụng kết hợp cả 2 loại ngắt vừa nêu ở trên. Kiểu lai này thường áp dụng với NMI input (non-maskable interrupt).

Xem thêm: Hướng Dẫn Cài Đặt Autocad 2014 Bản Full Active + Hướng Dẫn Cài Đặt

Message – signaled – interrupt dựa trên message: Interrupt kiểu này không sử dụng hardware interrupt line như các interrupt vừa liệt kê. Thay vào đó, nó gửi một message trên một kênh liên lạc chung (thường là bus của hệ thống) để request for service. Mesage-signaled có nhiều nét tương đồng với edge-triggered interrupt,.

Doorbell: Khái niệm này dùng để mô tả một cơ chế khi mà phần mềm có thể “thông báo” với phần cứng rằng “còn một số việc cần hoàn thành”. Thông thường phần mềm sẽ đựat dữ liệu vào một vùng nhớ đã được “thống nhất” và “rung chuông báo hiệu” bằng cách ghi vào vùng nhớ khác với vùng nhớ đã được thống nhất. Vùng nhớ khác này còn được gọi là doorbell region. Có nhiều doorbell phục vụ các mục đích khác nhau

Độ ưu tiên giữa các interrupts – interrupt priorities

Do interrupt là asynch event (hardware interrupt) nên processor cần định nghĩa ra các mức độ ưu tiên cho các interrupt để xử lý tình huống nhiều interrupt xảy ra đồng thời. Các mức độ ưu tiên này được ghi trong doc của processor.

Trong trường hợp interrupt có độ ưu tiên thấp đang được xử lý thì xảy ra interrupt có ưu tiên cao hơn thì interrupt ưu tiên thấp sẽ bị tạm dừng xử lí… hành động này gọi là interrupt nesting,

Cần chú ý kích thước của stack khi nesting interrupt, Mỗi ISR của interrupt được nest cần lưu giá trị các thanh ghi của nó trong stack, việc này có thể dẫn tới stackoverflow nếu không kiểm soát chính xác kích thước stack.

Interrupt priorities được set bởi phần cứng, phần mềm hoặc cả 2.

Ta không thể thao tác với global interrupt flags bằng ngôn ngữ C, thay vào đó, cần dùng asembly.

Interrupt Mapping

Khi một interrupt xảy ra và không bị từ chối xử lý thì processor sẽ nhảy đến ISR – tập hợp các đoạn code được lập trình từ trước để xử lý interrupt tương ứng. Để đảm bảo được ISR tương ứng với interrupt vừa xảy ra, cần có một cơ chế mapping giữa ISR và interrupt source.

Cơ chế mapping này tồn tại dưới dạng interrupt vector table. Nó là một mảng các con trỏ hàm (pointer to function, Processor sẽ sử dụng một con số được gán cho từng interrupt làm index để duyệt mảng này. Và giá trị tại index tương ứng sẽ là con trỏ hàm trỏ tới ISR cần được thực thi.

Việc cài đặt ISR cho tất cả interrupt là cần thiết, kể cả với những interrupts chưa được sử dụng trong hệ thống (tránh tình trạng hệ thống going off into the weeds – mất kiểm soát). Nếu cảm thấy việc cài đặt ISR cho từng interrupt chưa sử dụng là một việc tốn thời gian, chung sta có thể cài đặt một ISR chung cho các interrupt chưa sử dụng.

ISR – Interrupt Service Routine

Mục đích của chúng ta là không để interrupt ảnh hưởng tới quá trình processor thực thi chương trình hiện tại nên chúng ta cần viết ISR càng ngắn gọn càng tốt. Nếu cần thêm một số thao tác xử lý đối với một interrupt cụ thể nào đó, hãy làm việc này ở ngoài ISR bằng một hàm khác…. Hàm này được gọi là DSR – deffered service routine.

Thường thì ISR không nhận tham số truyền vào và không có giá trị trả về. Một ISR căn bản sẽ thực hiện những công việc sau:

Saving processor context

Acknowleding the interrupt

Restoring processor context

Một khái niệm đi liền với interrupt là interrupt latency – đây là thông số đo khoảng thời gian từ khi interrupt xảy ra cho đén khi processor bắt đầu thực hiện ISR tương ứng.

Shared data & race conditions

Việc chia sẻ dữ liệu (share data) giữa ISR và main program là một vấn đề khi thiết kế embedded software có sử dụng interrupt.

Race condition là một tình huống xảy ra khi kết quả thay đổi dựa trên thứ tự thực hiện các lệnh trong main code và ISR. Cần tránh tình huống này.

Race condition được xem là rất khó phát hiện bởi interrupt là asynch event và race condition thì không phải lúc nào cũng xuất hiện….

Khái niệm race condition kéo theo khái niệm critical section. Critical section là một đoạn chương trình phải được thực hiện liên tục từ đầu đến cuối, không được phép xảy ra interrupt ở giữa (Trong ngôn ngữ C có thể chỉ là một dòng lệnh nhưng trên thực tế, cần tới 4-5 dòng lệnh asm tương tự…).

Giải pháp cho race condition chính là disable interrupt trước khi đi vào thực thi critical section và enable interrupt khi đã thực thi xong critical section dồng thời hạn chế tối đa số lượng và độ dài của critical section.