VxWorks er eit kommersielt sanntidsoperativsystem (RTOS) som vert mykje nytta i industrielle datasystem. Det er millom anna kjent for å verta nytta i romfarkostane åt NASA.

Ålment hev me tri ulike slag operativsystem: Monolittisk, layered eller klient-tenar. Sistnemnde kann avgrensast til ein mikrokjerne som tek seg av scheduling og synkronisering. Annan funksjonalitet er implementert i parallelle prosessar og trådar. Applikasjonane er klientar som kommuniserar gjenom systemkall til sovorne ”server tasks”. VxWorks er eit sovore OS.

Wind-kjernen Kjernen i VxWorks heiter Wind. Han tek seg av scheduling og synkronisering. Scheduleren er avbrotsdriven og preemptive med 256 ulike prioritetsnivå. Prioritet 0 er den høgste og 255 den lægste. Med systemkallet kernelTimeSlice() kann ein kontrollera um scheduleren skal nytta round-robin scheduling eller ikkje på tasks med same prioritetsnivå. Denne typen scheduling er til vanleg slegen av.

Modularitet og skalabilitet Etter det som stend i VxWorks-databladet, kann utviklaren velja millom meir enn 100 ulike ”options” og setja i hop sjølvstyrte konfigurasjonar. Individuelle modular kann skalerast inn og ut or systemet, og dette gjev utviklaren høve til å skreddarsy run-time-software for alskens applikasjonar. Til dømes kann individuelle funksjonar takast ut or ANSI C run-time-biblioteket, eller serskilde kjernesynkroniseringsobjekt kann takast ut um applikasjonen ikkje treng dei. I utviklingsfasen åt ein applikasjon kann det gjerne vera høvelegt å nytta netverkstenestor av ymist slag, medan det i den endelege utgåva vil verka ressurssparande å plukka burt denne funksjonaliteten. Då høver det godt at TCP, UDP, sockets og standard Berkeley netverkstenestor alle er døme på modular som kann skalerast inn eller ut or systemet.

Utviklingsmetodikk VxWorks-utviklarar byggjar på ”host != target”-prinsippet. Utviklingsmiljøet, kalla Tornado, held til på ein Windows NT eller Solaris arbeidsstasjon. Ein kann nytta host-maskinen til å redigera, kompilera, lekkja og lagra real-time-kode, og dinæst køyra og ”debugge” real-time-koden på target-maskinen. Den endelege VxWorks-applikasjonen kann køyra åleine på target-maskinen, anten i ROM eller på disk, utan nokon studnad frå netverket eller host-maskinen.

Host-maskinen og VxWorks-maskinen kann jamvel arbeida saman i ein hybrid-applikasjon der host-maskinen nyttar VxWorks-systemet som ein real-time-server i eit netverksmiljø. Til dømes kann eit VxWorks-system som styrer fabrikkutstyr taka imot instruksjonar frå ein host-maskin som køyrer NT.

Studnad for C++: Attåt generell studnad for C++, inkludert iostream-biblioteket og standard template library, fær du med den valfrie komponenten Wind Foundation Classes desse objektbiblioteki: VxWorks Wrapper Class Library Tools h++ library frå Rogue Wawe.

Debugging: Med i “Wind DeBug”-protokollen fylgjer ein sokalla “Target Agent”. Um ikkje anna vert spesifisert, køyrer han som ein eigen task kalla tWdbTask. Tornado-serveren sender debugging-fyrespurnader til agenten som fær høve til å kontrollera eller manipulera andre tasks i systemet.

Multitasking/scheduling: Multitasking gjev sanntidapplikasjonar høve til å fungera som eit sett sjølvstendige tasks. Kvar task hev sin eigen kontekst, det vil segja CPU-miljø og systemressursar som applikasjonen ser kvar gong han køyrer. Ved ein ”context switch”, dvs skifte frå ein prosess/tråd til ein annan, vert konteksten lagra i ein ”Task Control Block” (TCB). Kvar kontekst inneheld:

Ein programteljar (program counter) CPU-register og um turvande floating-point register Ein stabel (stack) med dynamiske variablar og returadressor til funksjonskall IO-tilordningar for standard input, output, error Eit forseinkingsur (delay timer) Eit tidlukeur (timeslice timer) Kjernekontrollstrukturar Signalhandlers Kontrollvariablar for debugging og yvervaking

Wind-scheduleren nyttar til vanleg prioritetsbasert preemptive scheduling. Med preemptive scheduling fær kvar task sin prioritet og kjernen sikrar at CPU’en er allokert til høgaste prioritetstask i ready-lista. Denne schedulingi er preemptive på den måten at um ein task med høgare prioritet vert ”ready”, lagrar kjernen straks konteksten til noverande task og svitsjar kontekst til tasken med høgare prioritet.

Med round-robin scheduling vert CPU-tidi likt fordelt millom alle ready-tasks med same prioritet. CPU-tilgangen gjeng på rundgang der kvar tasks køyrer i eit fastsett intervall eller ”time slice”.

Rutinen som kontrollerar round-robin-scheduleren er:

kernelTimeSlice(int ticks)

Wind-kjernen hev prioritetsnivå frå 0 og ned til 255. Tasks vert tilordna prioritet i det dei vert skapte, men ein kann byta prioritet undervegs med systemkallet taskPrioritySet().

Når ein task vert skapt, gjeng han inn i tilstandet ”Suspended”. Etter at han er skapt, lyt han aktiverast for å koma yver i ”Ready”-tilstandet. Eventuelt kann ein nytta ”Spawning”-primitiven som gjev høve til både skaping og aktivering med einskildfunksjonen taskSpawn().

Døme frå C++: id = taskSpawn(name, priority, options, stacksize, function, arg1,.. , arg10);

Rutinen taskSpawn lagar her ein ny task context.

Synkronisering: VxWorks tilbyd både eigne wind-semaforar og POSIX-semaforar. Semaforar gjev dei ulike applikasjonane høve til å koordinera einannan. Den mest upplagde måten ulike tasks kann kommunisera på er gjenom ”shared memory”. Sidan alle tasks i VxWorks eksisterar i det same lineære adressevaldet, er det lett å byta datastrukturar. Globale variablar, lineære buffer, ringbuffer, lekkjelistor og peikarar kann refererast beinveges frå program som køyrer i ulik kontekst.

Kor som er lyt det finnast ein mekanisme som hindrar at programmi øydelegg for einannan. Ein av metodane som finst for å gjeva eit program eksklusiv ressurstilgang er bruk av semaforar.

Attåt POSIX-semaforane hev me tri slag semaforar i VxWorks, skreddarsydde for kvar sine uppgåvor:

Binær: Den snøggaste og mest generelle semaforen. Utforma serskilt til synkronisering og jamvel mutual exclusion.

Mutual exclusion: Ein serskild binær semafor, utforma serskilt til “mutual exclusion”, prioritetsarv (priority inversion), “deletion safety” og rekursjon.

Counting: Som den binære semaforen, men held orden på kor mange gonger han vert frigjeven. Vaktar på ressursar det finst meir enn eitt næme av.

Minnehandtering I VxWorks køyrer all kode i det same lineære adressevaldet. Minneadressering treng soleides ikkje vera med i ”task context”. Skulde kvar task ha sitt eige minnevald, trong ein mapping frå virtuelt til fysisk minne, og det er berre tilgjengeleg gjenom den valfrie komponenten VxVMI.

Mange operativsystem tilbyd paging og swapping. I sanntids-OS kann me ikkje nytta sovorne teknikkar då det skaper uventa forseinkingar i programkøyringi. Sidan Wind-kjernen er serskilt utforma for sanntidsapplikasjonar, nyttar han aldri paging eller swapping. Kor som er held POSIX 1003.1b-standarden for sanntidsystem studnad for operativsystem med virtuelt minne. I sovorne system kann applikasjonar som nyttar POSIX page-locking hindra at utvalde blokker i minnet vert paga eller swappa. For skuld portabiliteten hev VxWorks inkludert page-locking-rutinane i POSIX. Det gjer ingen skilnad til eller frå um ein nyttar desse rutinane då alt minnet i praksis er ”locked”.

Priority inversion control Priority inversion fær me bruk for når ein task med høg prioritet vert tvinga til å venta på ein task med lægre prioritet. Det vanlegaste dømet på dette er at ein høgprioritetsprosess lyt venta på ein lågprioritetsprosess som held eit synkroniseringsobjekt (ein semafor). For å hindra at ein prosess med medium prioritet skal preempta den blokkerande lågprioritetsprosessen, vert lågprioritetsprosessen tilordna same prioritet som høgprioritetsprosessen.

For å kunna nytta priority inversion på ein “mutual exclusion”-semafor, lyt me nytta flagget SEM_INVERSION_SAFE som enablar ein prioritetsarvealgoritme. Denne algoritmen sikrar at prosessen som er inne i den kritiske regionen køyrer på same prioritetsnivå som prosessen han hev blokkert i denne regionen. So snart den prioritetsinverterte prosessen hev sleppt semaforen, fær han attende den upphavlege prioriteten sin. SEM_INVERSION_SAFE må nyttast i kombinasjon med flaget SEM_Q_PRIORITY.

Døme frå C++: semId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);

Avbrotshandtering Avbrot (interrupts) gjev systemet høve til å ansa på eksterne hendingar. I VxWorks er kvar interrupt knytt til si Interrupt Service Routine (ISR) gjenom ein vektortabell. Programutviklaren kann sjølv skriva eigne ISRs og knyta deim til sine respektive interrupts med systemkallet intConnect().

Det som normalt hender når ein interrupt gjeng inn til systemet, er at ikkje-kritisk kode vert preempta og ISR’en køyrd. Tidi det tek frå interrupt-signalet når systemet til ISR’en køyrer kallar me interrupt latency. Sidan mange interrupts kann koma i snøgg rekkjefylgja og ISRs med høg prioritet kann blokkera ISRs med låg prioritet, er det viktugt å halda ISR-prosesseringi på eit minimum.

ISR-koden køyrer ikkje i vanleg task context, han hev ingen Task Control Block (TCB) og alle ISRs nyttar same stabelen (stack). Desse skilnadene fører med seg visse avgrensingar for kva slags rutinar som kann køyra frå ein ISR.

ISRs bør ikkje nytta funksjonar som kann føra at prosessen som kalla upp interruptet vert ”blokkert”. Døme på funksjonar som ikkje kann nyttast er malloc, free og semTake. Ein ISR må ikkje nytta IO-operasjonar gjenom VxWorks-systemet. Eit kall til ein device driver kann blokkera systemet um han som kalla upp interruptet lyt venta på devicen.

ISRs bør ikkje nytta floating point instructions då desse operasjonane er tidkrevjande og dei dedikerte registri ikkje er lagra i entryet åt eit ISR (Fyre eit interrupt vert kalla upp, pushar me ymse register på stacken slik at ISR’en ikkje skal skriva yver data som uppkallaren sidan skal nytta seg av. Dette kallar me entryet åt eit ISR. Motsett lyt me pop’a informasjonen attende fyre me returnerar kontrollen til uppkallaren).

Intertask-kommunikasjon VxWorks hev intertask-communication-mekanismar som gjev sjølvstendige tasks høve til å koordinera einannan. Utviklaren kann forma ut programmi med shared memory, meldingskøar, semaforar, events og pipes (For intertask-messaging innanfor CPU’en. Pipes er virtuelle IO-einingar styrte av driveren pipeDrv. pipeDevCreate() skaper ein pipe-device og den assosierte meldingskøen. Tasks vert blokkerte når dei les frå ein tom pipe eller skriv til ein full pipe. Til liks med vanlege meldingskøar kann ISR’ar skriva til ein pipe, men ikkje lesa frå ein pipe), sockets og remote procedure calls (til intertask-kommunikasjon yver netverk) og signals (til exception handling). For å kontrollera kritiske systemressursar er mange slag semaforar tilgjengelege – som alt nemnt under ”Synkronisering”.

Meldingskøar er den viktugaste mekanismen VxWorks hev for kommunikasjon millom tasks på same prosessor. Meldingskøane gjev høve til å utveksla meldingar av variabel lengd. Kvar einaste task kann senda meldingar eller taka imot meldingar. Dei same meldingskøane kann delast av mange tasks. Tvovegskommunikasjon millom tvo tasks krev til vanleg tvo meldingskøar, ein for kvar veg kommunikasjonen gjeng.

Wind-meldingskøar kann skapast og slettast med desse rutinane: msgQCreate(int maxMsgs, int maxMsgLength, int options): Allokerar og initialiserar ein meldingskø. msgQDelete(MSG_Q_ID msgQId): Terminerar og frigjev ein meldingskø. msgQSend(MSG_Q_ID msgQId, char *Buffer, UINT nBytes, int timeout, int priority): Sender ei melding til ein meldingskø. Um ingen tasks ventar på meldingar frå køen, vert ho lagd til. Er tasks som ventar, gjeng meldingi beinveges åt den fyrste tasken som ventar.