Miten saada aikaan 100us (10kHz) kutsu keskytysohjelmalle Linuxissa. Tuo keskeytysrutiini ei ole ongelma, vaan miten saada nostettua kellokeskeytyksen taajuus?
Miten 100us kello keskytys
Linuxissa
7460
0Äänestä
Muut lukivat myös
Odottaa vastausta
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 7
Vanhimmat
eikö usleep() kelpaa... voit vilkaista kernelin sorsasta miten homma on toteutettu ?
Missä fileessä on kellokeskytysrutiin? Sen löytäminen vain kahlaamalla kernelikoodia läpi kestäisi jokusen kuukauden.
Tarvitsen tuon HW ohjaukseen ja koska samaan aikaan pitää tehdä muutakin kuin pyöriä silmukassa niin usleep ei toimi. Kernelissä on 2.6-13 jälkeen 250Hz kellokeskeytys. Tarvitsen 10kHz kellorutiinia.
setitimer-ohjelmallahan nuo kellokeskeytykset asetetaan ja timeri sekä keskeytyksestä generoituva signaali valitaan. Teoriassa keskeytysvälin voi asettaa mikrosekunnin tarkkudella.
http://linux.die.net/man/2/setitimer
Lisäksi täytyy tehdä valitulle signaalille palveluohjelma ja asetella maskit ym. Kts. esim. ohjelmaa sigaction. Verkosta varmaan löytyy paljon esimerkkejä.
Ongelma vaan on, ettei standardi Linux ole varsinaisesti Real Time - käyttöjärjestelmä. Eli mikrosekuntien ajoitukset eivät ole tarkkoja. Linuxista on olemassa myös RealTime versioita, joihin on lisätty timereita ja niiden ajoitukset ovat tarkempia. En tiedä onko sinulla sellaista käytössä.
Yksi tapa toteuttaa tuo tarkka ajoitus on tehdä se tuomalla jostain ulkoisesta signaaligeneraattorista signaali esim. sarjaporttiin ja käyttämällä sarjaportin keskeytystä ajoitukseen.
O'reilly kustantamon "Linux system porgrammin" kirja viimevuodelta on eri mieltä. 2.6-13 versiossa kellokeskeytyksen taajuus on muutettu 250Hziin ja se on nopein timer-vauhti mihin ylletään. Toki voi pyytää nopeampaa timer-vauhtia mutta se ei toteudu tai sitten sieltä tulee signaaleja purskeina. Näin ainakin kirjan mukaan. Niinpä kelloa pitäisi nostaa. Jossain on parametri nimeltä HZ, kuinka ollakaan :-) joka määrää kellokeskeytyksen tahdin. Tuo on mitä ilmeisemmin käännösaikainen vakio.
Ulkoista keskeytystä on miettinyt mutta en ole vielä niin pitkällä, että tietäisin miten oma keskeytysrutiin kytketään HW-keskeytykseen Linuxissa. Laiteohjaimen tekemisen suhteen Linux on maailman helpoin käyttis.
Vielä kun keksisi millä oman laiteohjaimen saa pysyvästi mukaan niin, että se on juonessa mukana heti bootin jälkeen ja kuinka sen prioriteettin voisi asettaa halutuksi. Prioriteetin saa kyllä asetettua root-oikeuksilla myöhemmin pakottamalla mutta jos oman laiteohjaimen prioriteetin saisi heti bootissa ylös, myös reagoiminen timeriin olisi tarkempaa, eikä user-tason ohjelmat keskeyttäisi sitä milloinkaan.
Ei onnistu standardi LINUX:lla. Verkko on kuitenkin täynnä Real Time Linux:ja, joilla tuota ajaoitusta ja keskeytysten käsittelyä on optimoitu. Tässä esimerkki, joka mainostaa pystyvänsä alle 20 mikrosekunnin ajoitukseen.
Linkki:
http://www.linuxdevices.com/articles/AT8073314981.html
FSMLabs: RTLinuxPro -- the RTCore OS provides a POSIX hard real-time environment that runs Linux (or BSD UNIX) as an idle thread. Real-time applications run essentially at the limits of the hardware (worst case interrupt plus scheduling is sub-20 microsecond range on most platforms), while the full features of Linux (or BSD) are available as an integration platform. -- info
Tässä linux real time versioista informaatiota:
http://www.realtimelinuxfoundation.org/
Ei sitä pyörää itse tarvitse uudelleen keksiä. Niitä tehty maailman sivu.
Nuo RT Linuxit näyttäisi olevan kaikki aataminaikaisilla kerneleillä ja ylläpito on lopahtanut. Ne lisäksi vaikuttavat enempi vähempi virityksiltä.
Jos vain tietäisi
1. missä kernelin fileessä määritellän HZ-vakio
2. miten kernel käännetään
Tuohon 2) kohtaan uskon löytyvän hyvät ohjeet mutta kernelin vaikuttaa sillisalaatilta. Koodin dokumentaatio on kuin koulunsa aloittaneilla, sääli.
Olisko noin, että pelkästään HZ vakiota muuttamalla saisit nuo ajastukset toimimaan?
HZ on todennäköisesti määritelty jossain header-filessa.
1. mites olisi grep "HZ" *.h
2. Koeta löytää make-file.