Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: jfila 23. 07. 2020, 06:27:40
-
Jak je to s přerušením v Linuxu? Můžete prosím i přiložit příklad zdrojáku? Očekával bych že vektory přerušení povedou do Kernelu a ten pak zavolá uživatelský program, je to tak? Musím se ale k "odběru" této události nějakým způsobem "přihlásit". Například RasPi a GPIO PIN.
-
https://www.raspberrypi.org/forums/viewtopic.php?t=180658
-
Obsluhovat preruseni v userspace je jen takova iluze / abstrakce, aby se nereklo. Bude to mit nejake latence, ktere musite vykryt napr. bufferovanim dat v one externi periferii. Hodi se to leda k cekani a aktivni probouzeni na ojedinelou udalost, ale aby nekdo s tim delal realnou obsluhu zarizeni, na to to uz nebude.
-
Ano to je mi jasné, že tím nebude možné měřit čas v nanosekundách. Ale na občasné probuzení a vyčtení bufferu nějaký rozptyl nevadí.
-
Pokud jde o vyčtení bufferu v přerušení a předání do aplikace, tak myslím, že v Linuxu se to obvykle řeší čtením souboru /dev/{fiktivní soubor implementovaný v kernel driveru}.
-
Pokud jde o vyčtení bufferu v přerušení a předání do aplikace, tak myslím, že v Linuxu se to obvykle řeší čtením souboru /dev/{fiktivní soubor implementovaný v kernel driveru}.
Ano to chápu, ale toto je jiný případ. Například mám po SPI připojen řadič a náhodně mě chodí data, je zbytečné neustále posílat dotaz, zda je něco v bufferu, když řadič má int PIN.
-
Linuxový zdroják je veřejný. Přerušení se tam používá v driverech na spoustě míst. Příklad použití jde vidět snadno třeba u nějakých krátkých driverů jako je třeba tento.
https://elixir.bootlin.com/linux/latest/source/drivers/input/touchscreen/mk712.c
-
Pokud jde o vyčtení bufferu v přerušení a předání do aplikace, tak myslím, že v Linuxu se to obvykle řeší čtením souboru /dev/{fiktivní soubor implementovaný v kernel driveru}.
Ano to chápu, ale toto je jiný případ. Například mám po SPI připojen řadič a náhodně mě chodí data, je zbytečné neustále posílat dotaz, zda je něco v bufferu, když řadič má int PIN.
Pokud na to driver není hotový, tak bude potřeba si driver napsat, alespoň nějaký minimální. A když už se člověk maže se základním driverem (a obranou kernelu proti out-of-tree driverům, prakticky asi bude potřeba si zkompilovat především celý kernel ze zdrojáků, a pak tam svůj driver naroubovat do stromu) tak bych rovnou veškerý bit-banging nechal v kernelovém driveru, vůči user space pak stačí jenom obsluhovat syscally... zrovna u SPI asi nestačí read() a write(), spíš nějaké to ioctl() - protože ta sběrnice není "jednoduchá roura".
Linux má koukám jakousi generickou podporu pro SPI (https://www.kernel.org/doc/html/v5.7/driver-api/spi.html), standardní API do user space i uvnitř kernel space. Dokonce ve zdrojákách (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi) vidím modul zvaný spi-bitbang (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-bitbang.c). Tzn. máte k dispozici generické vyšší vrstvy, rozhraní do user space je hotové, máte k dispozici knihovnu bitbanging rutin, jenom si musíte dopsat svůj relativně lehký modulek, který to všecko slepí dohromady a parametrizuje na Vaši mapu GPIO pinů v RPi. Ve vanilce je několik modulů, které bitbanging knihovničku využívají = můžete použít jako example. Viz Kconfig (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/Kconfig), hledejte výskyty "select SPI_BITBANG".
Spíš mě ale zaráží, našel jsem zmínky, že RPi obsahuje hardwarový SPI řadič, tam pak samozřejmě bitbanging není potřeba, ale: copak k tomu není dávno hotový driver? Neválí se něco hotového na Githubu? Nebo je to použité=zabrané na nějaké režijní účely? Nejsem znalcem RPi...
-
Děkuji mrknu na to. Raspberry Pi má SPI a modul lze normálně používat, také mám v plánu to využít, ale potřeboval jsem to přerušení.
-
Pokud jde o vyčtení bufferu v přerušení a předání do aplikace, tak myslím, že v Linuxu se to obvykle řeší čtením souboru /dev/{fiktivní soubor implementovaný v kernel driveru}.
Ano to chápu, ale toto je jiný případ. Například mám po SPI připojen řadič a náhodně mě chodí data, je zbytečné neustále posílat dotaz, zda je něco v bufferu, když řadič má int PIN.
Pokud na to driver není hotový, tak bude potřeba si driver napsat, alespoň nějaký minimální. A když už se člověk maže se základním driverem (a obranou kernelu proti out-of-tree driverům, prakticky asi bude potřeba si zkompilovat především celý kernel ze zdrojáků, a pak tam svůj driver naroubovat do stromu) tak bych rovnou veškerý bit-banging nechal v kernelovém driveru, vůči user space pak stačí jenom obsluhovat syscally... zrovna u SPI asi nestačí read() a write(), spíš nějaké to ioctl() - protože ta sběrnice není "jednoduchá roura".
Linux má koukám jakousi generickou podporu pro SPI (https://www.kernel.org/doc/html/v5.7/driver-api/spi.html), standardní API do user space i uvnitř kernel space. Dokonce ve zdrojákách (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi) vidím modul zvaný spi-bitbang (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/spi-bitbang.c). Tzn. máte k dispozici generické vyšší vrstvy, rozhraní do user space je hotové, máte k dispozici knihovnu bitbanging rutin, jenom si musíte dopsat svůj relativně lehký modulek, který to všecko slepí dohromady a parametrizuje na Vaši mapu GPIO pinů v RPi. Ve vanilce je několik modulů, které bitbanging knihovničku využívají = můžete použít jako example. Viz Kconfig (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/spi/Kconfig), hledejte výskyty "select SPI_BITBANG".
Spíš mě ale zaráží, našel jsem zmínky, že RPi obsahuje hardwarový SPI řadič, tam pak samozřejmě bitbanging není potřeba, ale: copak k tomu není dávno hotový driver? Neválí se něco hotového na Githubu? Nebo je to použité=zabrané na nějaké režijní účely? Nejsem znalcem RPi...
Ale tazatel nechce implementovat samotne SPI, ale dodatecny notifikacni mechanizmus vyuzivajici preruseni - jakozto optimalni reseni vuci amaterismum typu busy-loop a polling! Samozrejme ze RPI ma hw SPI a linux ma sve genericke SPI API.
-
Ale tazatel nechce implementovat samotne SPI, ale dodatecny notifikacni mechanizmus vyuzivajici preruseni - jakozto optimalni reseni vuci amaterismum typu busy-loop a polling! Samozrejme ze RPI ma hw SPI a linux ma sve genericke SPI API.
Já pořád nerozumím tomu, proč by měl v userlandu dělat polling.
Přijde mi, že se OP ptá z prostředka: má nějaký problém, vymyslel pro něj řešení, které neumí implementovat* a chtěl by s tou implementací pomoct. IMHO by bylo lepší, kdyby nastínil ten původní problém, třeba pro něj existuje nějaké jiné, standardní řešení.
Např. pokud by původní problém byl v tom, že nějaký hardware pomocí SPI pushuje hodnoty v nepravidelných intervalech a on na ně chce reagovat (soft)realtime, tak nepotřebuje žádné interrupty, bohatě mu stačí blokující znakové zařízení...
* to není kritika!
-
Celkem standardni reseni je naprogramovat kernel driver; neni k tomu treba modifikovat kernel tree, driver jde odladit i uplne mimo nej, samozrejme za predpokladu ze z toho bude modul. Neni to az tak slozite, jak se na prvni pohled zda, hlavne kdyz clovek vystaci s nejakym existujicim prikladem - pak neni ani nutne nejak hluboce studovat ruzne locking mechanismy, apod.
Fungovat to pak muze treba tak, ze komunikuju s driverem pres read/write/ioctl bez nejake nutnosti resit realtimovost (tzn. mereni casu probiha v KERNELu, ne userspace).
-
Např. pokud by původní problém byl v tom, že nějaký hardware pomocí SPI pushuje hodnoty v nepravidelných intervalech a on na ně chce reagovat (soft)realtime, tak nepotřebuje žádné interrupty, bohatě mu stačí blokující znakové zařízení...
SPI i I2C jsou master/slave zbernice, a jinak nez pollingem se s takovyma periferiema neda bavit. Pokud chce zarizeni neco rict, muze trpelive mlcet, az dostane slovo (polling), nebo se ozvat dodatecnym, out of band, signalem - prerusenim, na zaklade cehoz vyvola pozornost mastera aby ho zkontroloval.
Blokujici zarizeni se da vytvorit jedine napsanim ovladace konkretni periferie (konkretniho cipu).
Tazatel chce jenom implementovat "user space driver", protoze vyvoj a ladeni je mnohokrat jednodussi. Pokud je srozumen s reakcni dobou / latencema a nevadi to dane aplikaci, tak bych to taky tak preferoval.
-
Děkuji mrknu na to. Raspberry Pi má SPI a modul lze normálně používat, také mám v plánu to využít, ale potřeboval jsem to přerušení.
No tak třeba v RPi pythoní knihovně je na to funkce GPIO.wait_for_edge.
-
SPI i I2C jsou master/slave zbernice, a jinak nez pollingem se s takovyma periferiema neda bavit. Pokud chce zarizeni neco rict, muze trpelive mlcet, az dostane slovo (polling), nebo se ozvat dodatecnym, out of band, signalem - prerusenim, na zaklade cehoz vyvola pozornost mastera aby ho zkontroloval.
Jasne, ale tohle je/bude v jádře, ne v userspace.
Blokujici zarizeni se da vytvorit jedine napsanim ovladace konkretni periferie (konkretniho cipu).
Tazatel chce jenom implementovat "user space driver", protoze vyvoj a ladeni je mnohokrat jednodussi. Pokud je srozumen s reakcni dobou / latencema a nevadi to dane aplikaci, tak bych to taky tak preferoval.
Těžko může implementovat jenom "user space driver", když chce funkcionalitu, kterou žádný (?) existující kernel driver nemá.
-
Blokujici zarizeni se da vytvorit jedine napsanim ovladace konkretni periferie (konkretniho cipu).
Tazatel chce jenom implementovat "user space driver", protoze vyvoj a ladeni je mnohokrat jednodussi. Pokud je srozumen s reakcni dobou / latencema a nevadi to dane aplikaci, tak bych to taky tak preferoval.
Těžko může implementovat jenom "user space driver", když chce funkcionalitu, kterou žádný (?) existující kernel driver nemá.
Podle mě chce mít v user space program, který bude čekat na signál od zařízení (čekáním na interrupt), a když přijde, tak zařízení přečte (pomocí existujícího jaderného SPI).
-
SPI i I2C jsou master/slave zbernice, a jinak nez pollingem se s takovyma periferiema neda bavit. Pokud chce zarizeni neco rict, muze trpelive mlcet, az dostane slovo (polling), nebo se ozvat dodatecnym, out of band, signalem - prerusenim, na zaklade cehoz vyvola pozornost mastera aby ho zkontroloval.
Jasne, ale tohle je/bude v jádře, ne v userspace.
Blokujici zarizeni se da vytvorit jedine napsanim ovladace konkretni periferie (konkretniho cipu).
Tazatel chce jenom implementovat "user space driver", protoze vyvoj a ladeni je mnohokrat jednodussi. Pokud je srozumen s reakcni dobou / latencema a nevadi to dane aplikaci, tak bych to taky tak preferoval.
Těžko může implementovat jenom "user space driver", když chce funkcionalitu, kterou žádný (?) existující kernel driver nemá.
Pokud jsi root, tak v userspace si muzes napsat ovladac k cemu chces (klidne vyuzivajici mmap/dma) - samozrejme je tam silne omezeni, ze jedinym uzivatelem daneho zarizeni bude autorova aplikace, protoze to konecne pristupove API bude viditelne jenom pro userspace, vyjma par pripadu, ktere maji udelanej zpetnej tunel do jadra (napr. FUSE).
Treba to preruseni z gpio - viz strana 15:
https://elinux.org/images/c/c8/Userspace-drivers-csimmonds-elce-2018_Chris-Simmonds.pdf
A celkove obsluhu jednoducheho zarizeni lze pak udelat i v bashi.
Psat ovladac do jadra ma smysl jedine kdyby to zarizeni spadalo do existujicich trid zarizeni, ke kteremu existuje standardni linuxove API (napr. typu framebuffer, disk, komunikacni port, atd) a prave zarizeni, ktere je unikatni ze nic takoveho v jadre neni, se hodi spis na psani userspace driveru.
Typicky priklad pouzivajici userspace drivery - flashrom (kazdy model SPI flashky se implementuje trocha jinak) a taky je zpusob jejich pripojeni velice variabilni.
-
Psat ovladac do jadra ma smysl jedine kdyby to zarizeni spadalo do existujicich trid zarizeni, ke kteremu existuje standardni linuxove API.
Já jsem dotaz pochopil tak, že to je přesně ten případ. V kernelu už základ SPI je, chci si tam jenom dodělat ten mechanismus probuzení userlandu.
-
Psat ovladac do jadra ma smysl jedine kdyby to zarizeni spadalo do existujicich trid zarizeni, ke kteremu existuje standardni linuxove API.
Já jsem dotaz pochopil tak, že to je přesně ten případ. V kernelu už základ SPI je, chci si tam jenom dodělat ten mechanismus probuzení userlandu.
To co je v jadre neni zadnej "zaklad" SPI, ale plnohodnotny SPI driver. SPI je zbernice a nemuze resit kazdou periferii - stejne jako mas treba PCI, PCIe, atd. Ovladace PCI karet taky nejsou rozsirenim zakladu PCI driveru... jenom ho vyuzivaji jako jednu z komunikacnich cest.
Tazatel ale nenapsal co je to za periferii, takze se nechme prekvapit.
Btw pokud by na RPI nebo jinou platformu chtel psat ovladac ktery vyuziva spi/int z kernelu, tak spravna cesta by byla sparovanim onoho driveru na patricny SPI port a GPIO / interrupt skrze device tree, a to neni uplne vec pro zacatecnika.
-
jenom ho vyuzivaji jako jednu z komunikacnich cest.
No dyt.
-
Např. pokud by původní problém byl v tom, že nějaký hardware pomocí SPI pushuje hodnoty v nepravidelných intervalech a on na ně chce reagovat (soft)realtime, tak nepotřebuje žádné interrupty, bohatě mu stačí blokující znakové zařízení...
SPI i I2C jsou master/slave zbernice, a jinak nez pollingem se s takovyma periferiema neda bavit. Pokud chce zarizeni neco rict, muze trpelive mlcet, az dostane slovo (polling), nebo se ozvat dodatecnym, out of band, signalem - prerusenim, na zaklade cehoz vyvola pozornost mastera aby ho zkontroloval.
Blokujici zarizeni se da vytvorit jedine napsanim ovladace konkretni periferie (konkretniho cipu).
Tazatel chce jenom implementovat "user space driver", protoze vyvoj a ladeni je mnohokrat jednodussi. Pokud je srozumen s reakcni dobou / latencema a nevadi to dane aplikaci, tak bych to taky tak preferoval.
Joahaa! konečně chápu zadání, díky...
Treba to preruseni z gpio - viz strana 15:
https://elinux.org/images/c/c8/Userspace-drivers-csimmonds-elce-2018_Chris-Simmonds.pdf
A celkove obsluhu jednoducheho zarizeni lze pak udelat i v bashi.
Strana 15 nedořekla jedno sladké tajemství: poll() je třeba volat na pseudosoubor "value" v tomtéž adresáři.
A k tomu terminologická vysvětlivka: syscall poll() nedělá hloupé olizování, ale čeká na událost (aneb hlavně že jsme zmátli nepřítele.)
Trochu jsem se začetl, tady jsou k tomu nějaké další střípky:
https://www.kernel.org/doc/Documentation/gpio/sysfs.txt
(hledejte klíčové slovo "edge")
https://blog.frantovo.cz/c/355/GPIO%20v%C2%A0Raspberry%20Pi%20jako%20soubory
https://www.raspberrypi.org/forums/viewtopic.php?t=7509
...a jenom velmi na okraj (popravdě tam o IRQ není vlastně nic):
https://www.ics.com/blog/gpio-programming-using-sysfs-interface
Takže správný postup by měl být, použít standardní SPI API pro SPI komunikaci a GPIO API pro čekání na interrupt.
Chápu to tak, že kernel musí obsahovat obecné GPIO API a specifický ovladač nebo nějaký definiční soubor (v rámci device tree?) pro RPi, takže ví, jak IRQ nakonfigurovat a když přijde, tak ho umí taky třeba ACKnout, což bych z user space dělal asi dost těžko... prostě ten interrupt se na nejnižší úrovni musí obsloužit a ACKnout v kernelu (aby se nezacyklil) a pokud tato podpora v kernelu existuje, tak user space dostane už jenom výslednou relativně nezáludnou událost. BTW, asi chápu, proč jsou ty GPIO interrupty edge-triggered (nikoli level-triggered).
-
Takže správný postup by měl být, použít standardní SPI API pro SPI komunikaci a GPIO API pro čekání na interrupt.
Bingo!
Kdyby to chtel psat in-kernel jak by to rad Mirek, tak se z toho patlani spravneho DT s interruptem zblazni:
https://blog.stabel.family/raspberry-pi-4-device-tree/
Chápu to tak, že kernel musí obsahovat obecné GPIO API a specifický ovladač nebo nějaký definiční soubor (v rámci device tree?) pro RPi, takže ví, jak IRQ nakonfigurovat a když přijde, tak ho umí taky třeba ACKnout, což bych z user space dělal asi dost těžko...
Tak nejak.. delat polling interrupt flagu a acknout ho z userspace jde, pokud mate privilegia na pristup na dane adresy (mmio) nebo io porty, ale v ramci moderniho OS nemate sanci nastavit vektor preruseni, i kdyz vite kam ho zapsat, tohle musi resit kernel - protoze ten jedinej ma persistentni virtualni adresy (v x86 cs selektor).
Pred GPIO interruptem existoval navrh na IRQ API, kde v kernelu je kratky handler a jinak to funguje znova skrze poll():
https://lwn.net/Articles/127698/ (stejny zpusob pouziti, skrze poll)
-
Kdyby to chtel psat in-kernel jak by to rad Mirek
Já jenom dodám, že o tom prakticky nic nevím, takže jenom čistě laicky mi přišlo, že když mám v kernelu připravený základ, je snazší nad ním napsat nějaký tenký wrapper a vyexportovat si jednoduché jednoúčelové zařízení, se kterým už pak práce v userlandu bude triviální.
Spíš jsem se ptal, proč by se to tak udělat nemělo, rozhodně jsem se s tebou o to nechtěl hádat, na to jsem fakt v téhle oblasti úplný laik :)
-
Kdyby to chtel psat in-kernel jak by to rad Mirek
Já jenom dodám, že o tom prakticky nic nevím, takže jenom čistě laicky mi přišlo, že když mám v kernelu připravený základ, je snazší nad ním napsat nějaký tenký wrapper a vyexportovat si jednoduché jednoúčelové zařízení, se kterým už pak práce v userlandu bude triviální.
Spíš jsem se ptal, proč by se to tak udělat nemělo, rozhodně jsem se s tebou o to nechtěl hádat, na to jsem fakt v téhle oblasti úplný laik :)
Si to jednou zkus - problem neni napsat kod - ten udelas treba jednou (pokud jsi sikovnej a neudelas tam moc chyb), ale pak pro kazde zarizeni kde to bezi (rekneme RPi, Beaglebone, a ruzna cina) musis vytvorit ty upravy DT - coz je softwarova analogie k toho jak si ty dratky v hw pripojil.
Na tyhle jednoduchy veci nefunguje plug & play (to se nahrazuje tim DT) a kdyz se podivas na situaci kde PnP funguje (USB) a presto se voli psani userspace driveru (skrze libusb,libhid) - musi ti byt jasne ze psat neco v userspace je omnoho jednodussi. Muzes si volit jazyk, chyby ti nezpusobi pad OS, muzes resit veci interaktivne. Snad tohle postaci..
-
Si to jednou zkus - problem neni napsat kod - ten udelas treba jednou (pokud jsi sikovnej a neudelas tam moc chyb), ale pak pro kazde zarizeni kde to bezi (rekneme RPi, Beaglebone, a ruzna cina) musis vytvorit ty upravy DT - coz je softwarova analogie k toho jak si ty dratky v hw pripojil.
DT trochu znám, před nějakýma cca dvěma lety jsem s ním musel cosi řešit v Buildrootu s custom kernelem.
Na tyhle jednoduchy veci nefunguje plug & play (to se nahrazuje tim DT) a kdyz se podivas na situaci kde PnP funguje (USB) a presto se voli psani userspace driveru (skrze libusb,libhid) - musi ti byt jasne ze psat neco v userspace je omnoho jednodussi. Muzes si volit jazyk, chyby ti nezpusobi pad OS, muzes resit veci interaktivne. Snad tohle postaci..
Tohle mi nepřijde jako pádná argumentace ze dvou důvodů:
1. předpokládám, že tazatel to chce pro jedno zařízení a jednu desku, že to je nějaký custom projekt
2. důvody, proč se různé věci dělají spíš v userspace, můžou být úplně jiné a v daném případě neplatné
Takže tohle mě moc nepřesvědčilo. Kdybys řekl "věř mi, mám to vyzkoušené, tohle je lepší cesta", mělo by to pro mě (od tebe) větší váhu :)
-
Takže tohle mě moc nepřesvědčilo. Kdybys řekl "věř mi, mám to vyzkoušené, tohle je lepší cesta", mělo by to pro mě (od tebe) větší váhu :)
Ale ony neexistuji univerzalni duvody proc se neco musi prave tak a ne jinak - nastesti v Linuxu a OSS obecne mame moznost volby, jak veci delat ruznymi zpusoby
Jeden duvod, se kterym jsme se setkali u psani nasich ovladacu pro V4L2 - ze kernel-space je dost nestabilni co se API tyce, takze pokud chces udrzovat svuj driver v kernelu, musis tomu venovat omnoho vice casu. Ale zrovna u V4L2 se tomu neda vyhnout a driver musi byt v kernelu.
S kazdou verzi kernelu je sance, ze se ti tvuj driver rozbije, a musis sledovat kam ten vyvoj speje - treba i co se tyce zpusobu reseni preruseni - tech zpusobu jak preruseni obslouzit je snad pet ruznych (od jednoduchych callbacku, po kernel thready ktere usinaj do pristiho preruseni)
-
Chápu to tak, že kernel musí obsahovat obecné GPIO API a specifický ovladač nebo nějaký definiční soubor (v rámci device tree?) pro RPi, takže ví, jak IRQ nakonfigurovat a když přijde, tak ho umí taky třeba ACKnout, což bych z user space dělal asi dost těžko...
Tak nejak.. delat polling interrupt flagu a acknout ho z userspace jde, pokud mate privilegia na pristup na dane adresy (mmio) nebo io porty, ale v ramci moderniho OS nemate sanci nastavit vektor preruseni, i kdyz vite kam ho zapsat, tohle musi resit kernel - protoze ten jedinej ma persistentni virtualni adresy (v x86 cs selektor).
Pred GPIO interruptem existoval navrh na IRQ API, kde v kernelu je kratky handler a jinak to funguje znova skrze poll():
https://lwn.net/Articles/127698/ (stejny zpusob pouziti, skrze poll)
Díky za ten odkaz... moc hezké čtení, v podstatě to shrnuje všechny moje námitky :-)
User space chápu jako prostor, který je od hardwaru naschvál poněkud izolován, běží nad nějakou abstrakcí stroje s jednotným softwarovým rozhraním. User space je prostředí relativně lenivé, pokud se týče doby odezvy a její garance, ale na druhou stranu nijak děsivé pro programátora - a v zájmu stability systému toho user space zas tak moc nesmí.
ACKování IRQ je věc, kterou se patří dělat v "IRQ kontextu", což je z hlediska plánování procesů/tasků atd. poměrně vyjímečné místo s výsadními právy, zejména vysokou prioritou běhu, např. tam může být zakázáno další přerušení (nebo lze znovu rekurzivně přerušit jen IRQ linkou o vyšší prioritě). Pointa je v tom, že kromě ACKnutí interruptu standardním způsobem hostitelovu řadiči přerušení (tzn. charakteristicky pro danou platformu počítače) mívají jednotlivé periferie svá vlastní pravidla, jak je třeba v dané periferii HW-specificky zašťourat, aby (v kontextu naší debaty) dočasně zmlkla, tzn. aby po návratu obsluhy přerušení (ISR) nebyla obsluha volána okamžitě znovu toutéž periferií. Viz level-triggered IRQ na PCI, tam se snad ani nic "genericky" neACKuje. Druhá varianta je, že pokud IRQ řádně neACKnete HW-specifickým způsobem, periferie už nikdy další interrupt nepošle (toho bych se bál u edge-triggered IRQ) - ale tato varianta je obecně snad méně časově kritická, a zrovna tenhle druh ACKu by se dal odložit do nějaké té "obsluhy druhé úrovně" (ACK je proveden nějakým relativně standardním = řádně plánovaným taskem, v kernelu nebo i v user space).
Chci říct, že ISR kontext a user space jsou dost protichůdná prostředí. ISR kontext má přednost i před kernelovými tasky. Naopak mít v user space zakázané interrupty? Z toho mám trochu husí kůži... Plánovač procesů potřebuje povolené interrupty ke svému provozu. Nemám teď úplně jasno, jak "drahý" je odskok do normální kernelové obsluhy IRQ, vs. co by znamenalo, mít obsluhu navíc v adresním režimu user space (jestli by ten context switch byl nutně těžkotonážnější).
V tom historickém kontextu na LWN se správně píše, že se věc komplikuje u sdílených IRQ linek, a že ohledně zmíněného HW-specifického ACKování v samotné periferii byl i nějaký návrh, toto pro jednodušší případy popsat nějakým structem, který by se dal předat při inicializaci user-mode driveru z user space do kernelu, a generická obsluha (ISR) v první linii v kernelu by podle tohoto "receptu" provedla základní držhubný ACK, aby se interrupt mohl odblokovat (například pro další periferie sdílející tutéž linku). Pokud mohu soudit, neujalo se to...
Tzn. request_irq(IRQ,*obsluha) podle mého patří právem do kernelu, v user space bych se tohoto nedožadoval :-) Mimochodem v kernelu request_irq() nezapisuje přímo do tabulky vektorů, se kterou pracuje CPU LAPIC - kernel má jednotnou super-obsluhu, která se zavěsí na všechna IRQ obsluhovaná LAPICem, a teprve tahle superobsluha volá obslužné rutiny (callbacky) registrované jednotlivými drivery (kernelovými moduly). Je to pravda už hodně dávno, co jsem to ve zdrojákách našel - snad se na tom moc nezměnilo :-) Dovedu si představit, že tahle superobsluha umí čítat počty interruptů (pokud to nedělá hardware LAPICu) a mám pocit, že přímo tahle superobsluha umí po ukončení "užitečné" obsluhy taky zavolat plánovač, tzn. v tom případě není pravda, že je plánovač probouzen pouze konkrétním časovačem (a procesy, které se procesoru dobrovolně vzdají tím, že usnou/zablokují se).
Hergot to jsem zase ujel...
-
Děkuji za rozsáhlou diskuzi, chtěl jsem využít to co už v jádru je, ovladač SPI i obsluhu přerušení. Jak diskutující popsali, údržba a ladění jaderného ovladače mě připadá příliš kanónovrabcově. Ale pokud bych pokračoval, tak bych to možná udělal. Podobně to má udělaný například ovladač pro CAN SPI řadič. Ale zatím se snažím pouze o userspace.
-
Jaky cip/zarizeni to je, co se snazis obslouzit?
-
Začal jsem tlakoměrem a vlhkoměrem. Teď bych třeba RFID po SPI.