Sanntidsoperativsystemer (RTOS) og deres programmer (applikasjoner)

Av Lim Jia Zhi, Senior Embedded Software Engineer

Bidrag fra DigiKeys nordamerikanske redaktører

Hva er RTOS

Et sanntidsoperativsystem (Real-Time Operating System - RTOS) er et lett operativsystem som brukes til å lette multitasking og aktivitetsintegrasjon i ressurs- og tidsbegrenset design, noe som vanligvis er tilfelle i innebygde systemer. Dessuten indikerer begrepet «sanntid» forutsigbarhet/determinisme i utførelsestid i stedet for rå hastighet, derfor kan en RTOS vanligvis bevises å tilfredsstille harde sanntidskrav på grunn av sin determinisme.

Nøkkelbegreper i RTOS er:

Oppgave

Oppgaver (kan også kalles prosesser/tråder) er uavhengige funksjoner som kjører i uendelige sløyfer, vanligvis hver ansvarlig for en funksjon. Oppgavene kjører uavhengig i sin egen tid (tidsisolasjon) og minnestakk (romlig isolasjon). Romlig isolasjon mellom oppgaver kan garanteres ved hjelp av en maskinvareminnebeskyttels-MPU (memory protection unit), som begrenser tilgjengelig minneområde og utløser feilavvik ved tilgangsbrudd. Normalt er interne periferiutstyr minnekartlagt, så en MPU kan brukes til å begrense tilgangen til periferiutstyr også.

Oppgaver kan være i forskjellige tilstander:

  • Blokkert – oppgaven venter på en hendelse (f.eks. forsinkelsestidsavbrudd, tilgjengelighet av data/ressurser)
  • Klar – oppgaven er klar til å kjøres på CPU, men kjører ikke fordi CPU er i bruk av en annen oppgave
  • Kjører – oppgaven er tildelt å kjøre på CPU

Planlegger

Planleggere i RTOS styrer hvilken oppgave som skal kjøres på CPU, og forskjellige planleggingsalgoritmer er tilgjengelige. Normalt er de:

  • Preemptiv (disponert på forhånd) – oppgaveutførelsen kan avbrytes hvis en annen oppgave med høyere prioritet er klar
  • Kooperativ – oppgavebytte vil bare skje hvis gjeldende kjørende oppgave gir seg selv

Preemptiv planlegging tillater høyere prioriterte oppgaver å avbryte en lavere oppgave for å oppfylle sanntidsbegrensninger, men det kommer i kostnaden for mer overhead ved kontekstbytte.

Inter-task-kommunikasjon (ITC)

Flere oppgaver må vanligvis dele informasjon eller hendelser med hverandre. Den enkleste måten å dele på er å lese/skrive delte globale variabler direkte i RAM, men dette er uønsket på grunn av risikoen for datakorrupsjon forårsaket av en rasetilstand. En bedre måte er å lese/skrive filskårede statiske variabler som er tilgjengelige med setter- og getter-funksjoner, og raseforhold kan forhindres ved å deaktivere avbrudd eller bruke et gjensidig ekskluderingsobjekt (mutex) inne i setter-/getter-funksjonen. Rengjøringsmåten er å bruke trådsikre RTOS-objekter som meldingskø til å sende informasjon mellom oppgaver.

I tillegg til å dele informasjon, kan RTOS-objekter også synkronisere utførelse av oppgaver fordi oppgaver kan blokkeres for å vente på tilgjengelige RTOS-objekter. De fleste RTOS-er har objekter som:

  • Meldingskø
    • FIFO-kø (First-in-first-out) for å sende data
    • Data kan sendes med kopi eller referanse (peker)
    • Brukes til å sende data mellom oppgaver eller mellom avbrudd og oppgave
  • Semafor
    • Kan behandles som en referanseteller for å registrere tilgjengeligheten til en bestemt ressurs
    • Kan være en binær eller tellende semafor
    • Brukes til å overvåke bruk av ressurser eller synkronisere utførelse av oppgaver
  • Mutex
    • Likner binær semafor, brukes vanligvis til å vokte bruken av en enkelt ressurs (MUTual EXclusion)
    • FreeRTOS mutex har en prioritert arvemekanisme for å unngå prioritert inversjon (tilstand når høyprioritert oppgave ender med å vente på lavere prioritert oppgave) problem.
  • Postboks
    • Enkel lagringsplassering for å dele en enkelt variabel
    • Kan betraktes som en enkeltelementkø
  • Hendelsesgruppen
    • Gruppe av forhold (tilgjengelighet av semafor, kø, hendelsesflagg, etc.)
    • Oppgaven kan blokkeres og kan vente til et spesifikt kombinasjonsvilkår er oppfylt
    • Tilgjengelig i Zephyr som Polling API, i FreeRTOS som QueueSets

Systemfrekvens (system tick)

RTOS trenger en tidsbase for å måle tid, vanligvis i form av en systemfrekvens (system tick) økt i et periodisk maskinvaretidsavbrudd. Med systemfrekvens (system tick) kan et program opprettholde mer enn tidsbaserte tjenester (oppgavekjøringsintervall, ventetidsavbrudd, tidskutt) ved hjelp av bare en enkelt maskinvaretimer. En høyere oppdateringsfrekvens (tick rate) vil imidlertid bare øke RTOS-tidsgrunnoppløsning, det vil ikke få programvaren til å kjøre raskere.

Hvorfor bruke RTOS

Organisering

Programmer kan alltid skrives på en ren metallmåte, men ettersom kodekompleksiteten øker, vil det å ha en eller annen form for struktur bidra til å administrere forskjellige deler av programmet og holde dem adskilt. Dessuten, med en strukturert måte å utvikle og kjent designspråk, kan et nytt teammedlem forstå koden og begynne å bidra raskere. RFCOM Technologies har utviklet programmer ved hjelp av forskjellige mikrokontroller som Texas Instruments sin Hercules, Renesas sin RL78 og RX, og STMicroelectronics sin STM32 på en annen RTOS. Lignende designmønstre tillater oss å utvikle programmer på forskjellige mikrokontroller og til og med forskjellige RTOS.

Modularitet

Splitt og hersk. Ved å skille funksjoner i forskjellige oppgaver, kan nye funksjoner enkelt legges til uten å bryte andre funksjoner; forutsatt at den nye funksjonen ikke overbelaster delte ressurser som CPU-en (prosessoren) og periferiutstyr. Utvikling uten RTOS vil normalt være i en stor uendelig sløyfe hvor alle funksjoner er en del av sløyfen. En endring av en funksjon i sløyfen vil ha en innvirkning på andre funksjoner, noe som gjør programvaren vanskelig å modifisere og vedlikeholde.

Kommunikasjonsstakker og drivere

Mange ekstra drivere eller stakker som TCP/IP, USB, BLE stakker og grafikkbiblioteker er utviklet/portet for/til eksisterende RTOS-er. En programutvikler kan fokusere på et program-lag av programvaren og redusere tiden det tar å få den på markedet betydelig.

Tips

Statisk allokering

Bruk av statisk tildeling av minne for RTOS-OBJEKTER betyr å reservere minnestakk i RAM for hvert RTOS-OBJEKT i kompileringstiden. Et eksempel på en statisk allokeringsfunksjon i freeRTOS er xTaskCreateStatic(). Dette sikrer at et RTOS-OBJEKT kan opprettes med hell, noe som sparer besværet med å håndtere en mulig mislykket tildeling og gjør programmet mer deterministisk.

Når det gjelder å bestemme stabelstørrelse som trengs for en oppgave, kan oppgaven kjøres med en større (mer enn nok) stakkstørrelse, og deretter kan stabelbruken kontrolleres i kjøretid for å bestemme høyvannsmerket. Det er også tilgjengelig statisk stakkanalyseverktøy.

Operativsystem abstraksjonslag (OSAL) og meningsfylt abstraksjon

Akkurat som Hardware Abstraction Layer (HAL), gjør bruk av RTOS-abstraktjonslaget det mulig for programvare å migrere enkelt til andre RTOS-er. Funksjonene til RTOS-er er ganske like, så å opprette OSAL bør ikke være for komplisert. For eksempel:

Bruke freeRTOS API direkte:

if( xSemaphoreTake( spiMutex, ( TickType_t ) 10 ) == pdTRUE ) { //dosomething }

Pakke RTOS API inn i OSAL:

if( osalSemTake( spiMutex, 10 ) == true) { //dosomething }

bruke abstraksjonslaget på inter-task-kommunikasjon for å gjøre koden mer lesbar og minimere omfanget av et RTOS-objekt:

if( isSpiReadyWithinMs( 10 ) ) { //doSomething }

I tillegg tillater abstraksjonen også en programmerer å endre RTO-objektet som brukes under (f.eks. fra mutex til tellesemafor) hvis det er mer enn én SPI-modul tilgjengelig. OSAL og andre abstraksjonslag hjelper til i programvaretesting så vel som ved å forenkle mock-funksjonsinnsetting under enhetstesting.

Oppdateringsintervall-valg

Ideelt sett er skal oppdateringsfrekvens (tick rate) være bedre, på grunn av mindre overheadressurser. For å velge en passende tikkfrekvens, kan utvikleren liste ned tidsbegrensninger for moduler i et program (gjentakelsesintervall, tidsavbruddsvarighet, etc.). Hvis det er noen avvikende moduler som trenger et lite intervall, kan det vurderes å ha et dedikert tidsavbrudd for avvikende moduler i stedet for å øke RTOS-oppdateringsfrekvens (tick rate). Hvis høyfrekvensfunksjonen er svært kort (f.eks. skriv for å registrere for å slå på/av en LED), kan det gjøres inne i en avbruddsservicerutine (ISR), ellers kan utsatt avbruddshåndtering brukes. Utsatt avbruddshåndtering er en teknikk for å utsette avbruddsberegning til en RTOS-oppgave, ISR vil bare generere en hendelse gjennom RTOS-objektet, deretter vil RTOS-oppgaven bli avblokkert av hendelsen og utføre beregningen.

Oppdateringsdemping (tick suppression) for lavt strømforbruk

Oppdatering-inaktivitet (tickless idle) inaktiv deaktiverer kryssavbrudd når systemet går inaktivt i lengre tid. En viktig måte for innebygd fastvare å redusere strømforbruket på er å sette systemet i lav strømmodus så lenge som mulig. Oppdateringsinaktivitet (tickless idle) implementeres ved å deaktivere det periodiske tikkavbruddet og deretter sette opp en nedtellingstimer for å avbryte når en blokkert oppgave skal utføres. Hvis det ikke er noen oppgave som venter på et oppdateringsavbrudd, kan kryssavbruddet deaktiveres på ubestemt tid til et nytt avbrudd skjer (f.eks. ved å trykke på knappen). For eksempel, når det gjelder et lavenergi-Bluetooth Low Energy (BLE)-fyr (beacon), kan mikrokontrolleren (MCU-en) settes i dyp dvale mellom annonseintervallet. Som vist i figur 1, settes nettvarden (beacon) i dyp dvalemodus for det meste, og forbruker strøm i titalls µA.

Graf over gjeldende forbruk av et BLE-nettvarden (beacon) (klikk for å forstørre)Figur 1: Strømforbruk for et BLE-nettvarden (beacon) (Bildekilde: RFCOM)

Konklusjon

En RTOS gir funksjoner som planlegger, oppgaver og inter-task kommunikasjons RTOS-objekter, så vel som kommunikasjonsstakker og drivere. Dette gjør det mulig for utviklere å fokusere på programlaget i den innebygde programvaren, og utforme multitasking-programvare med letthet og hastighet. Men den må, som alle andre verktøy, brukes riktig for å få frem mer verdi. For å skape trygg, sikker og effektiv innebygd programvare, bør utviklere vite når DE skal bruke RTOS-FUNKSJONER og også hvordan de konfigurerer RTOS.

DigiKey logo

Disclaimer: The opinions, beliefs, and viewpoints expressed by the various authors and/or forum participants on this website do not necessarily reflect the opinions, beliefs, and viewpoints of DigiKey or official policies of DigiKey.

Om skribenten

Image of Lim Jia Zhi

Lim Jia Zhi, Senior Embedded Software Engineer

Lim Jia Zhi is an embedded software engineer, holds a degree in Electrical and Electronics Engineering. He has developed software for devices in IoT solution covering edge gateway and battery-powered edge devices, and also involved in developing safety-critical embedded software. Actively learning ways to design efficient and reliable embedded system, like using design pattern and tools, and having software development lifecycle. (jia.zhi.lim@rfcom-tech.com (+65) 6635 4217)

Om denne utgiveren

DigiKeys nordamerikanske redaktører