2012-01-11 6 views
6

Sto considerando una situazione imminente in un progetto Linux incorporato (non ancora hardware) in cui due chip esterni dovranno condividere una singola linea IRQ fisica. Questa linea è capace nell'hardware di trigger di fronte ma non di interrupt attivati ​​dal livello.Come vengono evitate le corse IRQ condivise in Linux

Guardando al supporto dell'irq condiviso in Linux, capisco che il modo in cui questo funzionerebbe con due driver separati è che ognuno dovrebbe chiamare il gestore di interrupt, controllare l'hardware e gestire se necessario.

Tuttavia, immagino le seguenti condizioni di gara e vorrei sapere se mi manca qualcosa o cosa potrebbe essere fatto per aggirare questo. Diciamo ci sono due sorgenti interrupt esterni, i dispositivi A e B: si verifica

  1. dispositivo B interrupt, IRQ va attivo
  2. bordo IRQ provoca gestore nucleo Linux interrupt per eseguire
  3. ISR per tirature dispositivo A, reperti nessun interrupt attesa
  4. dispositivo si verifica un interrupt, IRQ rimane maniglie (wire-O)
  5. ISR per tirature dispositivo B, reperti interrompere attesa, attivi e libera
  6. gestore di interrupt
  7. nucleo esce
  8. IRQ rimane attivo, non più bordi vengono generati, IRQ è bloccato

sembra che per questo da fissare, il gestore di interrupt nucleo dovrebbe controllare il livello IRQ dopo l'esecuzione di tutti i gestori, e se ancora attivo, eseguili di nuovo tutti. Linux lo farà? Non penso che il nucleo dell'interrupt sappia come controllare il livello di una linea IRQ.

Questa gara è qualcosa che può effettivamente accadere e, in caso affermativo, come posso affrontare questo?

risposta

2

Fondamentalmente, con l'hardware che hai descritto, fare un cavo o per gli interrupt non funzionerà MAI correttamente.

Se si desidera eseguire cablaggi o, in realtà, è necessario utilizzare ingressi IRQ sensibili al livello. Se ciò non è fattibile, allora forse puoi aggiungere una sorta di controller di interrupt. Quel dispositivo avrebbe preso N input sensibili al livello, e avrebbe un output, e un qualche tipo di 'clear'. Quando il controller di interrupt diventa chiaro, abbasserebbe l'output, quindi riaffermerà l'output se uno dei suoi input fosse ancora asserito.

Per quanto riguarda il software, è possibile eseguire la linea IRQ su un altro ingresso del processore. Questo ti permetterebbe di controllare almeno lo stato, ma la gestione dell'ISR core di Linux non saprà nulla di questo, e quindi dovrai applicare una patch per farla controllare e scorrere di nuovo le ISR. Inoltre, questo significa che in situazioni di caricamento di interruzioni pesanti non uscirai MAI da questo ISR. Dato che stai facendo un cavo o sugli IRQ, suppongo che questi dispositivi non si interrompano troppo spesso.

Un'altra cosa è sembrare davvero difficile con il processore. Potrebbe esserci qualche tipo di trucco che puoi eseguire con l'interrupt setup per fargli riconoscere nuovamente l'interrupt.

Non proverei nulla di troppo complicato, altrimenti separerei le sorgenti su ingressi IRQ separati, passerei a un ingresso sensibile al livello o aggiungerei un chip controller di interrupt.

+1

Grazie per il consiglio. Penso che avremo intenzione di implementare un controller di interrupt in un FPGA che dobbiamo comunque avere sulla lavagna. – blueshift