Differences

This shows you the differences between two versions of the page.

Link to this comparison view

so2:teme:tema2:faq [2013/03/30 16:22]
ghennadi.procopciuc [3 - Două buffere]
so2:teme:tema2:faq [2017/03/23 21:48] (current)
adrian.stanciu [3 - Legătura între read/write și întreruperi]
Line 16: Line 16:
 :?: Ce înseamnă că read și write trebuie să fie blocante? :?: Ce înseamnă că read și write trebuie să fie blocante?
  
-:!: Read trebuie să se blocheze dacă nu există date citite ​de pe port(bufferul pentru read este gol) până când vin date, și write trebuie să se blocheze dacă nu ai spațiu de scris în bufferul de write până când se eliberează o parte din el prin scriere pe port. +:!: Read trebuie să se blocheze dacă nu există date de citit (bufferul pentru read este gol) până când vin date (prin citire de pe port), și write trebuie să se blocheze dacă nu este spațiu de scris în bufferul de write până când se eliberează o parte din el (prin scriere pe port)
  
 ==== 3 - Două buffere ==== ==== 3 - Două buffere ====
Line 25: Line 25:
  
 :!: E nevoie de două buffere pentru fiecare device (deci 4 în total), având următoarele funcții: :!: E nevoie de două buffere pentru fiecare device (deci 4 în total), având următoarele funcții:
-Bufferul pentru operația read: scrii în acest buffer datele primite pe portul serial (luate cu inb în handlerul de întrerupere) și le iei din acest buffer și le scrii în bufferul din userspace (în funcția ''​read''​ a device-ului). +  * Bufferul pentru operația read: scrii în acest buffer datele primite pe portul serial (luate cu inb în handlerul de întrerupere) și le iei din acest buffer și le scrii în bufferul din userspace (în funcția ''​read''​ a device-ului). 
-Bufferul pentru operatia write: scrii în el din bufferul din userspace (în funcția ''​write''​ a device-ului) și iei din el în handler-ul de întrerupere și scrii pe port (cu outb).+  ​* ​Bufferul pentru operatia write: scrii în el din bufferul din userspace (în funcția ''​write''​ a device-ului) și iei din el în handler-ul de întrerupere și scrii pe port (cu outb).
  
 Nu se poate folosi același buffer pentru ambele operații având în vedere că se referă la date diferite, unul la datele scrise pe port și altul la datele citite de pe port, date care de obicei sunt diferite. Nu prea te interesează să citești de pe portul serial ce tocmai ai scris pe el, ci ce s-a scris la celălalt capăt. ​ Nu se poate folosi același buffer pentru ambele operații având în vedere că se referă la date diferite, unul la datele scrise pe port și altul la datele citite de pe port, date care de obicei sunt diferite. Nu prea te interesează să citești de pe portul serial ce tocmai ai scris pe el, ci ce s-a scris la celălalt capăt. ​
Line 35: Line 35:
  
 :?: Se generează doar una/câteva întreruperi apoi se opresc. Care ar fi motivul? :?: Se generează doar una/câteva întreruperi apoi se opresc. Care ar fi motivul?
 +
 :!: În întrerupere trebuie neapărat să citești IIR, altfel nu se va genera ack pentru întreruperea în curs și nu o să mai primești întreruperi. :!: În întrerupere trebuie neapărat să citești IIR, altfel nu se va genera ack pentru întreruperea în curs și nu o să mai primești întreruperi.
  
Line 42: Line 43:
 [[http://​cursuri.cs.pub.ro/​lurker/​message/​20070413.104853.300f0d29.en.html | Context ]] [[http://​cursuri.cs.pub.ro/​lurker/​message/​20070413.104853.300f0d29.en.html | Context ]]
  
-:?: În handler-ul ​pt intrerupere <code c>​irqreturn_t ​my_handler(int irq_no,void *dev_id,struct pt_regs *regs)</​code>​+:?: În handler-ul ​pentru ​intrerupere <code c>​irqreturn_t ​my_irq_handler(int irq_no, void *dev_id)</​code>​
 putem să folosim dev_id astfel încât să refere serial[0] și serial[1] ?  putem să folosim dev_id astfel încât să refere serial[0] și serial[1] ? 
 serial [0] de exemplu este : serial [0] de exemplu este :
-<code c>err = request_irq(MY_IRQ1,​my_handler,SA_INTERRUPT,"​uart16550",&​serial[0]);</​code>​+<code c>err = request_irq(MY_IRQ1, ​my_irq_handlerIRQF_SHARED, "​uart16550",​ &​serial[0]);</​code>​
  
  
 :!: Poți să înregistrezi același handler pentru ambele întreruperi (și MY_IRQ1 și MY_IRQ2); spre exemplu: :!: Poți să înregistrezi același handler pentru ambele întreruperi (și MY_IRQ1 și MY_IRQ2); spre exemplu:
 <code c> <code c>
-request_irq(MY_IRQ1,​my_handler,SA_INTERRUPT,"​uart16550",&​my_serial[0]);​ +request_irq(MY_IRQ1, ​my_irq_handlerIRQF_SHARED, "​uart16550",​ &​my_serial[0]);​ 
-request_irq(MY_IRQ2,​my_handler,SA_INTERRUPT,"​uart16550",&​my_serial[1]);​+request_irq(MY_IRQ2, ​my_irq_handlerIRQF_SHARED, "​uart16550",​ &​my_serial[1]);​
 </​code>​ </​code>​
  
Line 75: Line 76:
  
 <code c> <code c>
-struct structura_mea * sm = (struct structura_mea *) dev_id;+struct structura_mea *sm = (struct structura_mea *)dev_id;
 sm->​base;​ sm->​base;​
 </​code>​ </​code>​
Line 85: Line 86:
 :?: Din câte am înțeles, în write copiez din userspace într-un write buffer local. Write Bufferul este scris pe serial cu outb în handlerul de intrerupere. În read copiez în userspace dintr-un read buffer local. Read bufferul este umplut cu date primite pe serială(inb) în handlerul de întrerupere. Cum se leagă exact funcțiile de read și write de întrerupere?​ Mie îmi intră o singură dată în întrerupere la inițializarea modulului. ​ :?: Din câte am înțeles, în write copiez din userspace într-un write buffer local. Write Bufferul este scris pe serial cu outb în handlerul de intrerupere. În read copiez în userspace dintr-un read buffer local. Read bufferul este umplut cu date primite pe serială(inb) în handlerul de întrerupere. Cum se leagă exact funcțiile de read și write de întrerupere?​ Mie îmi intră o singură dată în întrerupere la inițializarea modulului. ​
  
-:!: La sfârșitul fiecărei funcții write va trebui ​fie să reactivați întreruperile <code c>​outb(0x00,​ IER); outb (0x03, IER);</​code> ​fie activați întreruperea ​de empty buffer doar când există ceva în buffer-ul ​device-ului de scris.+:!: RDAI trebuie să fie activă cât timp buffer-ul de citire nu este plin. Funcția de read ar trebui să activeze RDAI după ce a luat date din buffer-ul de citire iar handler-ul de întrerupere să dezactiveze RDAI dacă buffer-ul de citire devine plin. 
 +THREI trebuie să fie activă cât timp buffer-ul de scriere nu este gol. Funcția de write ar trebui să activeze THREI după ce a pus date în buffer-ul ​de scriere iar handler-ul de întrerupere să dezactiveze THREI dacă buffer-ul ​de scriere devine gol.
  
 ==== 4 - Buffer circular ==== ==== 4 - Buffer circular ====
Line 91: Line 93:
 [[ http://​cursuri.cs.pub.ro/​lurker/​message/​20100209.175807.e1d4fe9b.en.html | Context ]] [[ http://​cursuri.cs.pub.ro/​lurker/​message/​20100209.175807.e1d4fe9b.en.html | Context ]]
  
-:?: Există vreo implemente ​de buffer circular în Linux?+:?: Există vreo implementare ​de buffer circular în Linux? 
 :!: Da, detalii găsiți în [[http://​lwn.net/​Articles/​347619/​ | următorul articol LWN]] :!: Da, detalii găsiți în [[http://​lwn.net/​Articles/​347619/​ | următorul articol LWN]]
  
Line 101: Line 104:
  
 :?: Se poate apela ''​KeSetEvent''​ din handlerul întreruperii ?  :?: Se poate apela ''​KeSetEvent''​ din handlerul întreruperii ? 
 +
 :!: NU. Din [[http://​www.osronline.com/​DDKx/​kmarch/​k105_1prm.htm | documentația KeSetEvent]]:​ the caller can be running at ''​IRQL <= DISPATCH_LEVEL''​. Nu puteți folosi ''​KeSetEvent''​ dintr-un handler de întrerupere. Va trebui să planificați un DPC pentru acest lucru. Mai multe detalii despre IRQL puteți afla [[http://​ext2fsd.sourceforge.net/​documents/​irql.htm | aici ]]. :!: NU. Din [[http://​www.osronline.com/​DDKx/​kmarch/​k105_1prm.htm | documentația KeSetEvent]]:​ the caller can be running at ''​IRQL <= DISPATCH_LEVEL''​. Nu puteți folosi ''​KeSetEvent''​ dintr-un handler de întrerupere. Va trebui să planificați un DPC pentru acest lucru. Mai multe detalii despre IRQL puteți afla [[http://​ext2fsd.sourceforge.net/​documents/​irql.htm | aici ]].
  
-=== 2 - Cum dezactivez ACPI?+==== 2 - ACPI ==== 
 + 
 +:?: Cum dezactivez ACPI? 
 + 
 +:!: Go to Device Manager (Right Click on MyComputer -> Properties -> Hardware). Under Computer entry, right click on Standard PC -> Disable)
  
-Go to Device Manager (Right Click on MyComputer ​-> Properties -> Hardware). Under Computer entry, right click on Standard PC -> Disable)+==== 3 Dezactivare COM1 & COM2 ====
  
-=== 3 - Cum dezactivez COM1 & COM2?+:?: Cum dezactivez COM1 & COM2?
  
-Go to Device Manager (Right Click on MyComputer -> Properties -> Hardware). Under Ports (COM & LPT) entry, right click on COM1/​COM2 ​ -> Disable)+:!: Go to Device Manager (Right Click on MyComputer -> Properties -> Hardware). Under Ports (COM & LPT) entry, right click on COM1/​COM2 ​ -> Disable)
  
so2/teme/tema2/faq.1364653340.txt.gz · Last modified: 2013/03/30 16:22 by ghennadi.procopciuc
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0