Er zijn twee problemen waar je rekening mee moet houden.
Ten eerste heb je als 'gewone' applicatie het probleem dat je proces op elk moment gepauseerd kan worden, omdat Linux aan pre-emptive multiprocessing doet en geen real-time OS is. Dat geldt tenminste met de normale scheduler; als je wat meer privileges hebt kun je een soft realtime scheduler kiezen met
sched_setscheduler. Realtime processen onderbreken direct niet-realtime processen als ze runnable zijn en kunnen zelf niet door andere processen onderbroken worden; ideaal voor het aansturen van een microcontroller dus. (Hoewel de kernel ondertussen nog wel signals afhandelt; maar met ~1ms resolutie moet dat geen problemen opleveren.)
Ten tweede is er het probleem dat
alle features die een beroep doen op de kernel om te wachten gesynchroniseerd worden met de kerneltimer. De granulariteit daarvan wisselt per platform en kernelversie, maar onder i386 was het altijd 100 Hz (10 ms) wat later is aangepast naar 1000 Hz (1 ms) en weer later naar 250 Hz (4ms). De precieze waarde kun je instellen met de CONFIG_HZ parameter van je kernel. De select()-truc hierboven is leuk, maar zal dus ook die kerneltimer als ondergrens hebben, dus om echt 1ms te slapen moet je ook je CONFIG_HZ op 1000 zetten.
Ik weet niet hoe portable je applicatie moet zijn, maar als het instellen van de kernelklok geen optie is, is het enige alternatief een busy loop. Helaas heeft Linux ook een chronisch gebrek aan accurate timers (om uit te lezen), dus ik denk dat je het beste een assembly loop kunt schrijven die de time-stamp counter uitleest (RDTSC). Dan moet je wel de processorsnelheid weten, maar die kun je wel weer uit /proc/cpuinfo vissen.
[
Voor 3% gewijzigd door
Soultaker op 14-11-2005 01:00
]