Khi nào một người nên sử dụng phương pháp bỏ phiếu và khi nào người ta nên sử dụng phương pháp dựa trên ngắt? Có các tình huống trong đó cả hai có thể được sử dụng?Phương pháp bỏ phiếu hoặc gián đoạn
Trả lời
Nếu sự kiện quan tâm là:
- Asynchronous
- khẩn cấp
- ít gặp
sau đó một xử lý ngắt dựa sẽ có ý nghĩa.
Nếu sự kiện quan tâm là:
- Synchronous (tức là bạn biết khi nào nên mong đợi nó trong một cửa sổ nhỏ)
- Không khẩn cấp (tức là một khoảng thời gian bỏ phiếu chậm không có tác động xấu)
- Thường xuyên (nghĩa là phần lớn các chu kỳ bỏ phiếu của bạn tạo ra một 'hit')
thì việc bỏ phiếu có thể phù hợp hơn.
Cân nhắc khác bao gồm việc bạn đang viết trình điều khiển thiết bị cho hệ điều hành hay chỉ viết mã kim loại trần không có hỗ trợ luồng. Trong các tình huống kim loại trần, CPU thường chỉ lặp lại khi nó không bận nên nó cũng có thể đang thăm dò ý kiến gì đó.
câu trả lời ngắn gọn là sử dụng phương pháp ngắt khi bỏ phiếu quá chậm. (do quá chậm, tôi có nghĩa là nếu bỏ phiếu mất dữ liệu, phương pháp ngắt là cần thiết)
Cần tránh sử dụng, vì nó thường ăn nhiều chu kỳ CPU không cần thiết (trừ khi (a) bạn chỉ thăm dò ý kiến trong một thời gian ngắn hoặc (b) bạn có thể đủ khả năng để ngủ trong một thời gian hợp lý trong vòng bỏ phiếu của bạn). Việc lãng phí các chu kỳ CPU không chỉ xấu từ góc độ hiệu năng, mà còn làm tăng tiêu thụ điện năng, điều này cũng có thể là một vấn đề đối với các ứng dụng nhúng chạy bằng pin.
Về cơ bản, chế độ thăm dò được sử dụng trong trường hợp chế độ gián đoạn không khả dụng do một số lý do phần cứng hoặc phần mềm. Vì vậy, chế độ ngắt là thích hợp hơn từ tiêu thụ điện năng, hiệu suất, vv quan điểm (đồng ý với Paul R). Chế độ được thăm dò cũng có thể được sử dụng khi tạo mẫu, đối với các lõi không cần thiết cho thiết bị ngoại vi và cho một số mục đích thử nghiệm.
gì vv tham khảo? –
Tôi muốn thêm, ví dụ, rằng chế độ ngắt cho phần mềm có tổ chức tốt hơn (nhưng nó không phải là một quy tắc). – pmod
Đôi khi bạn thực sự cần sử dụng cả hai. Ví dụ, nếu các sự kiện là lẻ tẻ nhưng đến trong một vụ nổ tốc độ cao; trước tiên bạn có thể cần phải đáp ứng với một ngắt, và sau đó trước khi kích hoạt lại cuộc thăm dò gián đoạn để xem một sự kiện khác đã xảy ra, tránh một số chi phí của việc chuyển đổi bối cảnh ngắt. Tôi tin rằng Giao diện mạng Linux hoạt động ở chế độ này.
trình điều khiển truyền thông 12Mbaud được nhúng của chúng tôi sử dụng một phương pháp như thế này - ngắt khi một nhân vật đến, sau đó thăm dò để lấy càng nhiều ký tự càng tốt từ nămo nhỏ trước khi thoát. – AShelly
@Simon: Bạn có thể làm rõ phiên bản hạt nhân Linux mà bạn đang đề cập đến không? Có kịch bản tương tự với giao diện mạng của hạt nhân Linux 3.16 không? –
Ngắt được ưu tiên khi yêu cầu độ trễ thấp. Nếu bạn bỏ phiếu cho một số điều kiện N lần mỗi giây, sau đó trung bình bạn sẽ khám phá ra rằng tình trạng trong thời gian một nửa số 1/N sau khi nó đã thực sự xảy ra.
Thỉnh thoảng đôi khi được ưu tiên khi yêu cầu thời gian xác định tuyệt đối. Bởi bản chất của họ, ngắt có thể xảy ra vào những thời điểm không thể đoán trước và phân tích thời gian rất phức tạp, trong khi với các hệ thống được thăm dò, nó tương đối dễ dàng để đưa ra những tuyên bố có thể chứng minh về sự hài lòng về thời hạn.
Luôn sử dụng ngắt. Bằng cách đó bạn không bao giờ mất dữ liệu.Trong trường hợp điều khiển hoặc các ứng dụng luồng thậm chí các tín hiệu chậm nhất nên được ngắt điều khiển.
Thời gian duy nhất mà bạn nên sử dụng bỏ phiếu là khi bạn đang sử dụng bộ lập lịch và bộ đệm trên phần cứng của bạn đủ sâu để đảm bảo không mất dữ liệu.
Chế độ hỏi vòng có thể hữu ích trong các hệ thống có sự kiện tần số cao, trong đó chi phí liên quan đến nhập và thoát trình xử lý ngắt sử dụng nhiều chu kỳ CPU hơn là chỉ đơn giản là bỏ phiếu. Ví dụ, bỏ phiếu có thể được sử dụng trong một bộ định tuyến IP để tối đa hóa băng thông CPU có sẵn để xử lý gói.
Khi quyết định khi bỏ phiếu hoặc gián đoạn, bạn phải hiểu đầy đủ bản chất của sự kiện bạn đang cố gắng theo dõi và phản hồi của bạn.
Ngắt yêu cầu không xử lý khi không có gì xảy ra, nhưng yêu cầu tất cả sự chú ý của bạn khi xảy ra sự cố. Nếu sự kiện ở bên ngoài và có các cạnh ồn ào hoặc xung nhanh thì điều này có thể gây đau đầu nghiêm trọng với các ngắt, bạn phải cẩn thận khi thiết lập các ngắt.
Trong ví dụ này, thói quen ngắt được đáp ứng với một chùm tia laser đã trở nên rõ ràng và được thiết lập riêng của mình lên cho một sự kiện mà nó bị tắc nghẽn:
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_EDGE = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
Có 2 điểm yếu của mã này: 1) Nếu chùm tia laser đã bị chặn lại trước khi cờ ngắt được xóa (BEAM_INTR_FLAG = FALSE;). Việc ngắt sẽ bị bỏ qua và mã sẽ không đồng bộ với trạng thái chùm tia laser.
2) Khi thiết lập ngắt ở chế độ nền hoặc ưu tiên cao hơn mức độ ưu tiên của mã này, bạn phải cẩn thận khi bật ngắt. Nếu cờ ngắt đã được thiết lập (không chính xác) trước khi nó được kích hoạt, thì thường trình ngắt sẽ được gọi không chính xác ngay khi nó được kích hoạt và có thể cho sai cạnh.
Cách dễ nhất để khắc phục 1) là kiểm tra kỹ sau khi bạn thiết lập ngắt, nếu xảy ra sau đó buộc ngắt. Để khắc phục 2) di chuyển tạo điều kiện cho các ngắt để sau khi kiểm tra kép:
/*Set the beam interrupt for the next clear to blocked event*/
BEAM_INTR_EDGE = CLEAR_TO_BLOCKED;
BEAM_INTR_FLAG = FALSE; /*Clear the interrupt*/
/*Double check beam state to see if it has already gone blocked*/
if (BEAM_STATE == BEAM_BLOCKED)
{
BEAM_INTR_FLAG = TRUE; /*Force the interrupt to re-enter the ISR after exiting*/
}
BEAM_INTR_EN = TRUE; /*re-enable the beam interrupts*/
Các buộc của ngắt làm cho hệ thống hoạt động với cùng một máy nhà nước, chỉ cần buộc nó vòng tay để trang trải các điểm mù.
Về cơ bản:
Set the edge to detect the next interrupt event
Clear the interrupt flag
if (the event has already occurred)
{
Set the interrupt flag to force the interrupt
}
Enable the interrupt
Nếu thời điểm đối phó với một sự kiện được phải phù hợp (ví dụ 1ms +/- 10us sau khi sau khi dòng đầu vào lên cao, truyền tín hiệu sự kiện) sau đó ngắt thường là tốt nhất.
Nếu thời gian phản hồi sự kiện phải nằm trong một khoảng thời gian nhất định (ví dụ: trong vòng 1ms của dòng đầu vào cao, truyền tín hiệu sự kiện), thì ngắt sẽ là tốt nhất.
Vấn đề với ngắt là bạn phải bắt đầu suy nghĩ về luồng và hai đoạn mã có thể truy cập cùng một dữ liệu cùng một lúc.
Ngắt cũng tốt cho phép bộ xử lý chuyển sang chế độ năng lượng thấp (ngủ/nhàn rỗi, v.v.) trong khi chờ đợi điều gì đó xảy ra.Có nói rằng tất cả các cuộc thăm dò có thể trả lời thời gian rất chặt chẽ cho các sự kiện nếu chỉ có một thứ để bộ vi xử lý làm, thường làm gián đoạn phần cứng mất vài chu kỳ để đáp ứng với một sự kiện trong khi vòng lặp bỏ phiếu chặt chẽ sẽ thực hiện. Page 5
Nếu sự kiện không có thời gian quan trọng và có khả năng gây ồn ào (ví dụ: ai đó nhấn nút chuyển) thì việc bỏ phiếu cho phép lọc đơn giản mà không bị mất hiệu ứng chuyển tiếp dài hạn. Một sai lầm phổ biến là thăm dò ý kiến nhiều lần khi thiết mọi thứ lên:
void fnInitialiseSystem(void)
{
if (MODE_INPUT == MODE_A) /*First polling of the MODE_INPUT*/
{
PR2 = PR2_MODE_A;
}
else
{
PR2 = PR2_MODE_B;
}
OpenTimer2(TIMER_INT_ON &
T2_PS_1_1 &
T2_POST_1_8 );
if (MODE_INPUT == MODE_A) /*Second polling of the MODE_INPUT*/
{
CurrentMode = MODE_A;
PROBE_INT_EDGE = CLEAR_TO_BLOCKED;
}
else
{
CurrentMode = MODE_B;
PROBE_INT_EDGE = BLOCKED_TO_CLEAR;
}
}
Trong ví dụ trên MODE_INPUT là một công tắc bên ngoài, nếu hai lần MODE_INPUT được thăm dò khác nhau thì hành vi này là bất ngờ. Khi đọc các loại tín hiệu này, tốt nhất là sử dụng tính năng lọc để quyết định trạng thái đầu vào dài hạn và thực hiện các tác vụ trên phiên bản đã lọc. Ví dụ với công tắc tắt chỉ cần kiểm tra công tắc thường xuyên (mỗi 1ms?) Và nếu một số (16) khác nhau (công tắc đóng) từ phiên bản đã lọc (mở khóa), sau đó cập nhật kết quả và thực hiện hành động bắt buộc. Hãy cẩn thận với tín hiệu răng cưa, một tín hiệu dao động có thể trông ổn định!
Một ví dụ về việc sử dụng bỏ phiếu và ngắt là một lần nữa, đối với việc sử dụng đầu vào không thay đổi thường xuyên nhưng rất ồn khi nó xảy ra. Tuy nhiên, một lần nữa một switch là một ví dụ tốt về điều này: mã có thể thiết lập ngắt để kiểm tra sự thay đổi trạng thái switch, khi một ngắt xảy ra thì switch có thể được kiểm tra thường xuyên cho đến khi trạng thái chuyển đổi là "ổn định" (hoặc thay đổi nhà nước hoặc trở lại với những gì nó đã được). Điều này mang lại lợi thế về chi phí xử lý thấp khi không có gì xảy ra và lọc nhiễu khi có điều gì đó đang xảy ra.
Có nhiều ràng buộc thiết kế có thể thúc đẩy quyết định. Ứng dụng của tôi có sự kết hợp giữa gián đoạn và bỏ phiếu:
- Nguồn đồng hồ bên ngoài và bên ngoài kích hoạt ngắt - điều quan trọng là chính xác để chúng tôi có thể đồng bộ hóa chúng.
- Tin nhắn nối tiếp đến kích hoạt ngắt. Các FIFO nhận được phải được bảo trì trước khi chúng tràn.
- Tin nhắn gửi đi kích hoạt ngắt khi FIFO bị trống một phần - nó phải được nạp lại trước khi nó bị tràn.
- Các semaphor được đặt của ISR được thăm dò trong nền. Điều này có 2 ưu điểm:
- Tính toán cần thiết để xử lý sự kiện đến có thể kéo dài; nếu nó còn lại trong ISR, nó có thể trì hoãn các ISR khác ngoài thời hạn dịch vụ của họ.
- Sự kiện có thể được sắp xếp theo trình tự. Ví dụ, vòng lặp bỏ phiếu có thể đảm bảo rằng phép tính X luôn xảy ra giữa việc thu thập dữ liệu ADC và phân tích cú pháp thư đến, ngay cả khi đôi khi thông báo đến sớm hơn dự kiến một chút.
Dưới đây là vài liên kết thú vị mà tôi tình cờ gặp trong khi phân tích các điểm bỏ phiếu vs phương pháp ngắt - http://web.engr.oregonstate.edu/~traylor/ece473/lectures/interrupts.pdf - liên kết Rất thú vị http://www.atarimagazines.com/compute/issue149/60_Interrupts_made_easy.php
http://www.electro-tech-online.com/micro-controllers/8440-interrupt-vs-polling.html http://www.microchip.com/forums/m397196-print.aspx http://www.cs.huji.ac.il/course/2006/67630/Lectures/interrupts.pdf http://sunsite.nus.edu.sg/LDP/LDP/tlk/node86.html
Hy vọng điều này là Hữu ích.
Bạn không muốn máy chủ lưu trữ trong vòng lặp bận trong một thời gian dài và việc bỏ phiếu có thể trở nên không hiệu quả khi kiểm tra thường xuyên được thực hiện cho dữ liệu không có thường xuyên. Vì vậy, có cho, nếu t ông chủ và thiết bị đều nhanh, sau đó bỏ phiếu nếu khá nhanh.
Nó là tốt hơn để đi với Interrupt based design
so với polling based
vì bỏ phiếu dựa là thiếu sót trong ý nghĩa rằng nó sẽ yêu cầu dữ liệu được trả về trên tất cả các cuộc thăm dò. Bây giờ, bạn có thể nói rằng tôi sẽ nhận được xung quanh trường hợp này, nơi một cuộc thăm dò duy nhất đã trả lại cho tôi một lỗi nhưng tại sao heck chất thải tất cả các chu kỳ CPU bỏ phiếu cho một cái gì đó khi nó cũng có thể trả về một lỗi ?? Và để mong đợi một cuộc thăm dò có thể thất bại là kịch bản sản phẩm thực tế.
Interrupt based designs
có ý nghĩa hơn nữa khi có nhiều lớp chức năng liên quan đến một cuộc thăm dò đơn lẻ. Đối với tôi một thực tế phổ biến của nó: có bạn tiếp tục hỏi (bỏ phiếu) bạn bè của bạn một lần nữa & lại hàng ngày cho dù ông có thông tin bạn cần HOẶC bạn sẽ chỉ nói với ông rằng interrupt
tôi khi bạn có thông tin tôi cần. Tôi nghĩ chúng ta làm điều đúng đắn trong cuộc sống hàng ngày nhưng không nhận ra.
Nhưng interrupt based architectures
khi triển khai yêu cầu hiểu rõ về số publish-subscribe design principle
. Và, khi được thực hiện trong các miền ứng dụng, chúng yêu cầu một phần của mã gửi các ngắt sẽ thực sự được viết tốt. Điều này tốt vì nó ép phức tạp đến một nơi là tốt.
bổ sung để ở trên, sau đây là những lợi thế khác mà bỏ phiếu dựa trên kiến trúc cung cấp cho bạn miễn phí:
- Asynchrounous
- Phù hợp tốt trong trường hợp các sự kiện không thường xuyên/cập nhật
- Cập nhật chỉ khi có các tình huống có sẵn dữ liệu
- Xử lý lỗi tốt hơn & quản lý
- Sử dụng tốt hơn chu kỳ CPU
- pin tốt hơn cuộc sống Quản lý đ.thoại
- Giữ người nghe miễn phí từ phức tạp bên dưới
Bất cứ khi nào bạn đang thiết kế sw
& bạn có sự lựa chọn này, bạn nên luôn luôn chọn một interrupt
thiết kế dựa trên polling
dựa, bởi vì một interrupt
thiết kế dựa có thể lấp đầy cho polling
tình hình sử dụng người nghe dựa nhưng một thiết kế bỏ phiếu dựa không bao giờ có thể đáp ứng yêu cầu cần interrupt
dựa thiết kế.
Sau đây là một ma trận so sánh ngắn gọn:
-INTERRUPT- -LOOP-
Speed fast slow
Eficiency good poor
CPU waste low high
multitasking yes no
complexity high low
debugging +/- easy easy
critical in time excellent poor
code bloat low impact high impact
Tại sao phương pháp gián đoạn dựa trên không được ưu tiên nếu sự kiện này xảy ra thường xuyên? –
Đó không phải là những gì tôi đã viết. Nếu nó là không thường xuyên sau đó bỏ phiếu nó lãng phí rất nhiều CPU. Nếu nó thường xuyên thì có thể phù hợp dựa trên các yếu tố khác. –
nếu nó rất thường xuyên, bạn có thể phải sử dụng các ISR để đảm bảo bạn có được nó, nhưng sau đó bạn sẽ cần phải đệm nó và đưa nó đi để lặp nền hoặc nhiệm vụ. –