2006-10-03
Realtid - grunder
I ett typiskt Linuxbaserat Audio/MIDI-system kan man hitta flera olika komponenter som måste samverka:
IRQ
IRQ står för Interrupt ReQuest. Detta innebär en avbrottskanal där enheter som behöver sända data påkallar uppmärksamhet. Processorn avbryter då för att ta emot data från den enhet som sänt IRQ.
I begynnelsen fanns AT-datorerna. Dessa hade 8 IRQ (0-7), som sedan utökades till 16 (0-15). När det fanns åtta IRQ var prioritetsordningen mellan dem så att lägst nummer hade högst prioritet och högst nummer hade lägst prioritet.
När IRQ utökades till 16 stycken, lade man in alla från 8-15 i platsen för IRQ 2, så nu ser prioritetsordningen ut som följer:
0, 1, (8, 9, 10, 11, 12, 13, 14, 15), 3, 4, 5, 6, 7
Detta innebär att IRQ 9, 10 och 11 är högre prioriterade än exempelvis 3 och 4. Detta går dock att ändra på.
PROCESS-PRIORITET
Man kan mycket förenklat säga att ju högre prioritet en process har, ju större chans är det att den kan köra ostört. Med en realtids-kärna har man möjlighet att låta IRQ-hanterare köras med lägre prioritet än användarapplikationer.
Det är, till exempel, möjligt att köra jackd med högre prioritet än alla IRQer för att säkerställa ostörd audio-hantering. Detta kan även inkludera IRQer för hårddisk och nätverkskort.
I en standard realtids-kärna har alla IRQ-hanterare en prioritet mellan 40-60. Genom att sätta jackd's prioritet till 70, gör vi så att JACK går före alla enheters begäran om åtkomst till processorn och databussen. Vi gör detta med jackd's -P switch:
# jackd -R -P 70 -d alsa ...
Det är ju allt väl, om det inte vore så att den IRQ som ljudkortet ligger på, och JACK använder sig av, bör ligga högre i prioritetsskalan än jackd.
Introduktion alltså för ett nytt program, som brukar ligga i ett paket som heter något liknande schedutils, chrt. Med chrt kan man ändra realtids-attributen för en viss process.
I realtidskärnan har varje IRQ ett process-ID (pid) för att det ska vara möjligt att manuellt ställa prioriteten på dem. För att lista ut vilka process-IDn som innehas av olika IRQer använder vi oss av programmet ps. ps är en typisk UNIX-förkortning som står för process och kommandot kan visa alla processer som för närvarande finns på systemet. För att bara visa de processer som har beskrivningen IRQ använder vi kommandot grep och filtrerar ps-kommandot genom det:
Eftersom de ljudkort som finns installerade har ICE1712-chip samt CS46xx-chip så kan man av listningen ovan sluta sig till att raderna markerade med < style="font-weight: bold;">IRQ 3 och 9.
Detta är inte alldeles enkelt för en nybörjare att klara av, så om du är en sån, ha gärna med dig en garvad nörd som du kan rådfråga med jämna mellanrum.
Processerna kan alltså ändras genom kommandot chrt med följande växlar, -p för prioritet 0-99 och -f för FIFO (First In First Out) policy, vilket är vad som bör användas i ljudsammanhang.
För enkelhetens skull kan man använda kommandot pidof som tar process-IDt från en process som matchar en viss textsträng.
# chrt -f -p 99 `pidof "IRQ 3"`
eller enligt ps-listningen en bit ovan:
# chrt -f -p 99 2837
Det är bra, för att inte säga en förutsättning, för ett lyckat resultat att ha ljudkortet på en egen IRQ. Om ljudkortet delar IRQ med till exempel nätverkskortet (exempelvis eth0) får detta lika hög prioritet som ljudkortet och hotar att dra en massa elände med sig.
Men det förutsätter som sagt att man lyckats kompilera sin egen kärna med realtids-patchning. Det går vi igenom i nästa avsnitt.
- JACK
- ALSA
- En MIDI-sequencer
- Några mjukvarusynthar
- En hårddiskinspelare
- All annan hårdvara (som hårddisk, nätverkskort, etc..) som behöver IRQ (avbrottsförfrågan) för att fungera.
- Resten av mjukvaran (som window-managers och annat användbart)
- Prioriterad audio-hantering samt
- Grym MIDI-tajming
IRQ
IRQ står för Interrupt ReQuest. Detta innebär en avbrottskanal där enheter som behöver sända data påkallar uppmärksamhet. Processorn avbryter då för att ta emot data från den enhet som sänt IRQ.
I begynnelsen fanns AT-datorerna. Dessa hade 8 IRQ (0-7), som sedan utökades till 16 (0-15). När det fanns åtta IRQ var prioritetsordningen mellan dem så att lägst nummer hade högst prioritet och högst nummer hade lägst prioritet.
När IRQ utökades till 16 stycken, lade man in alla från 8-15 i platsen för IRQ 2, så nu ser prioritetsordningen ut som följer:
0, 1, (8, 9, 10, 11, 12, 13, 14, 15), 3, 4, 5, 6, 7
Detta innebär att IRQ 9, 10 och 11 är högre prioriterade än exempelvis 3 och 4. Detta går dock att ändra på.
PROCESS-PRIORITET
Man kan mycket förenklat säga att ju högre prioritet en process har, ju större chans är det att den kan köra ostört. Med en realtids-kärna har man möjlighet att låta IRQ-hanterare köras med lägre prioritet än användarapplikationer.
Det är, till exempel, möjligt att köra jackd med högre prioritet än alla IRQer för att säkerställa ostörd audio-hantering. Detta kan även inkludera IRQer för hårddisk och nätverkskort.
I en standard realtids-kärna har alla IRQ-hanterare en prioritet mellan 40-60. Genom att sätta jackd's prioritet till 70, gör vi så att JACK går före alla enheters begäran om åtkomst till processorn och databussen. Vi gör detta med jackd's -P switch:
# jackd -R -P 70 -d alsa ...
Det är ju allt väl, om det inte vore så att den IRQ som ljudkortet ligger på, och JACK använder sig av, bör ligga högre i prioritetsskalan än jackd.
Introduktion alltså för ett nytt program, som brukar ligga i ett paket som heter något liknande schedutils, chrt. Med chrt kan man ändra realtids-attributen för en viss process.
I realtidskärnan har varje IRQ ett process-ID (pid) för att det ska vara möjligt att manuellt ställa prioriteten på dem. För att lista ut vilka process-IDn som innehas av olika IRQer använder vi oss av programmet ps. ps är en typisk UNIX-förkortning som står för process och kommandot kan visa alla processer som för närvarande finns på systemet. För att bara visa de processer som har beskrivningen IRQ använder vi kommandot grep och filtrerar ps-kommandot genom det:
$ ps ax | grep IRQOm vi ska modifiera prioriteten på IRQ för ljudkortet, tittar vi först vilken IRQ som det använder sig av genom att lista den virtuella filen /proc/interrupts med kommandot cat:
18 ? S< 0:00 [IRQ 9]
808 ? S< 0:00 [IRQ 12]
891 ? S< 0:00 [IRQ 1]
1724 ? S< 0:00 [IRQ 14]
1803 ? S< 0:00 [IRQ 10]
2837 ? S< 0:00 [IRQ 3]
2946 ? S< 0:00 [IRQ 8]
2960 ? S< 0:00 [IRQ 7]
3004 ? S< 0:00 [IRQ 6]
3080 ? S< 0:00 [IRQ 11]
5403 pts/0 R+ 0:00 grep IRQ
$ cat /proc/interrupts
CPU0
0: 357694670 XT-PIC timer 0/94670
1: 192527 XT-PIC i8042 0/92527
2: 0 XT-PIC cascade 0/0
3: 3683355 XT-PIC CS46XX 0/83355 <
8: 12983156 XT-PIC rtc 0/83156
9: 203367747 XT-PIC ICE1712 0/67747 <
10: 18757427 XT-PIC eth0 0/57427
11: 652848 XT-PIC nvidia 0/52848
12: 3109504 XT-PIC i8042 0/9504
14: 1693997 XT-PIC ide0 0/93997
15: 3617940 XT-PIC ide1 0/17940
NMI: 0
ERR: 600
Eftersom de ljudkort som finns installerade har ICE1712-chip samt CS46xx-chip så kan man av listningen ovan sluta sig till att raderna markerade med < style="font-weight: bold;">IRQ 3 och 9.
Detta är inte alldeles enkelt för en nybörjare att klara av, så om du är en sån, ha gärna med dig en garvad nörd som du kan rådfråga med jämna mellanrum.
Processerna kan alltså ändras genom kommandot chrt med följande växlar, -p för prioritet 0-99 och -f för FIFO (First In First Out) policy, vilket är vad som bör användas i ljudsammanhang.
För enkelhetens skull kan man använda kommandot pidof som tar process-IDt från en process som matchar en viss textsträng.
# chrt -f -p 99 `pidof "IRQ 3"`
eller enligt ps-listningen en bit ovan:
# chrt -f -p 99 2837
Det är bra, för att inte säga en förutsättning, för ett lyckat resultat att ha ljudkortet på en egen IRQ. Om ljudkortet delar IRQ med till exempel nätverkskortet (exempelvis eth0) får detta lika hög prioritet som ljudkortet och hotar att dra en massa elände med sig.
Men det förutsätter som sagt att man lyckats kompilera sin egen kärna med realtids-patchning. Det går vi igenom i nästa avsnitt.