RTP Real-Time Programmatuur hoofdstuk 15: laag-niveau programmeren Yolande Berbers Programmatuur voor real-time controle slide 1 RTP overzicht mechanismen voor hardware input/output iets uitgebreider dan in het boek taal-ondersteuning algemeen Ada C schrijven van device drivers (vb in Ada) (device driver: deel van besturingssysteem dat een bepaald randapparaat aanstuurt) Yolande Berbers Programmatuur voor real-time controle slide 2 RTP mechanismen voor hardware input/output 2 klassen computer architecturen tov randapparaten een bus voor geheugen, andere bus voor randapparaten één bus voor alles data MEM data CPU dev dev dev adressen dev adressen data CPU MEM dev dev dev dev adressen Yolande Berbers Programmatuur voor real-time controle slide 3 RTP mechanismen voor hardware input/output ook 2 methoden voor toegang tot randapparaten twee sets van instructies, één voor elke bus toegang tot devices via speciale hardware instructies vaak spreekt men over poorten vb: Intel 8086 memory mapped I/O de randapparaten bestrijken een deel van de adresruimten schrijven en lezen van randapparaat gaat zoals schrijven en lezen van geheugen (zelfde instructies) vb: M68000 familie, de meeste moderne architecturen Yolande Berbers Programmatuur voor real-time controle slide 4 RTP mechanismen voor hardware input/output communicatie met randapparaten direct vanuit de toepassing in hogere programmeertalen die mogelijkheden aanbieden voor I/O programmatie in hogere programmeertaal waar men dicht bij machine kan schrijven, of waar men assembler kan in schrijven (bv C) besturingssysteem moet dit toelaten (vaak beschermd) via interface van besturingssysteem (system calls) meestal via bibliotheekroutines vaak behandelt de interface alle I/O als karakterstroom een device driver is een deel van het besturingssysteem dat interactie verzorgt met een bepaald randapparaat Yolande Berbers Programmatuur voor real-time controle slide 5 RTP mechanismen voor hardware input/output interactie met randapparaat device driver -> randapparaat opdrachten gegevens (bij schrijven) randapparaat -> device driver gegevens (bij lezen) informatie over wanneer opdracht beëindigd is (eindeinformatie) informatie over hoe de opdracht beëindigd is (statusinformatie) Yolande Berbers Programmatuur voor real-time controle slide 6 RTP mechanismen voor hardware input/output interactie met randapparaten: schematisch processen besturingssysteem device driver status instructies data interrupts device Yolande Berbers Programmatuur voor real-time controle slide 7 RTP mechanismen voor hardware input/output interactie met randapparaten: gegevens via gegevens-register van randapparaat of controler rechtstreeks in het geheugen via DMA (Direct Memory Access) CPU geeft beginadres en grootte van buffer door aan randapparaat randapparaat kan rechtstreeks lezen en schrijven in geheugen randapparaat moet rechtstreeks aan het geheugen kunnen gebeurt door cycle stealing maakt het probleem van voorspellen van duur van programma (zie Hdst 13) veel moeilijker status-informatie (randapparaat -> device driver) via status-register van randapparaat of controler Yolande Berbers Programmatuur voor real-time controle slide 8 RTP mechanismen voor hardware input/output schematisch met DMA processen besturingssysteem device driver status MEM interrupts controller DMA dev Yolande Berbers instructies dev dev Programmatuur voor real-time controle slide 9 RTP mechanismen voor hardware input/output interactie met randapparaten: opdrachten via opdracht-register van randapparaat of controler via kanaalprogramma (channel program) het randapparaat is intelligent en heeft een processor die kanaalprogramma’s kan uitvoeren de CPU schrijft zo een programma in het geheugen randapparaat krijgt beginadres van randapparaat en leest het programma rechtstreeks uit het geheugen randapparaat moet rechtstreeks aan het geheugen kunnen dit gebruikt ook altijd DMA komt veel voor bij main frames, zelden in real-time systemen Yolande Berbers Programmatuur voor real-time controle slide 10 RTP mechanismen voor hardware input/output schematisch met kanaalprogramma processen besturingssysteem device driver prog. status MEM interrupts kanaal DMA controller Yolande Berbers start-info controller Programmatuur voor real-time controle slide 11 RTP mechanismen voor hardware input/output einde-informatie (randapparaat -> device driver) polling of status-gestuurd herhaaldelijk inspectie van status-register meestal in een vorm van busy-waiting interrupt-gestuurd randapparaat stuurt interrupt als klaar met uitvoeren van opdracht tijdens wachten op interrupt kan computer andere taak uitvoeren mechanisme: zie volgende slide Yolande Berbers Programmatuur voor real-time controle slide 12 RTP mechanismen voor hardware input/output interrupt-mechanisme: bij optreden van interrupt: contextswitch running taak wordt onderbroken en toestand wordt bewaard om later herstart te worden (gebeurt door de hardware) minimaal: programmateller en statuswoord maximaal: ook alle registers tussenin: ook een aantal registers routine geassocieerd met randapparaat dat interrupt genereerde wordt opgeroepen (gebeurt door de hardware) interrupt routine voert uit (dit is software) indien niet voldoende registers bewaard: bewaart nog registers deze routine voert uit herstelt wat eventueel in begin van routine werd bewaard voert een ‘return from interrupt’ uit de bewaarde context wordt hersteld en de onderbroken taak kan verder uitvoeren (gebeurt door de hardware) Yolande Berbers Programmatuur voor real-time controle slide 13 RTP mechanismen voor hardware input/output identificatie van randapparaat dat interrupt veroorzaakte interrupt vector vector met adressen van interrupt routines elke element van de vector is geassocieerd met een randapparaat status-info via hardware wordt een algemene interrupt-routine opgeroepen deze ziet in status-info welk randapp. de interrupt veroorzaakte de gepaste routine wordt opgeroepen polling analoog aan status-info maar algemene routine moet alle randapparaten afgaan om te zien wie een interrupt veroorzaakte identificatie (reden) van interrupt Yolande Berbers testen op status van randapparaat Programmatuur voor real-time controle slide 14 RTP mechanismen voor hardware input/output interrupt-controle interrupts kunnen aan en af gezet worden soms via bit in interrupt-toestandstabel of device-statuswoord soms via mask waarbij elke bit een randapparaat voorstelt en 0 of 1 kan bevatten verschillende niveaus van interrupts en prioriteiten elke klasse van randapparaten krijgt niveau toegewezen processor heeft ook een niveau (veranderlijk) op elke moment mogen alleen de randapparaten met een hoger niveau als de processor een interrupt veroorzaken, de andere interrupts worden tegengehouden zo kan men prioriteiten geven aan randapparaten Yolande Berbers Programmatuur voor real-time controle slide 15 RTP mechanismen voor hardware input/output twee modellen voor device drivers één-niveau device driver meest eenvoudige device driver, vaak in RT-systemen behandelt aanvraag per aanvraag aanvaardt nooit opdracht voordat vorige behandeld is proces keert pas terug nadat zijn aanvraag behandeld werd processen besturingssysteem device driver status Yolande Berbers instructies device data Programmatuur voor real-time controle interrupts slide 16 RTP mechanismen voor hardware input/output twee modellen voor device drivers twee-niveau device driver (zie ook volgende slide) bovenste niveau: aanvaardt de aanvragen dit niveau wordt aangeroepen door proc. met aanvragen randapparaat vrij: aanvraag wordt direct doorgegeven randapparaat bezet: aanvraag wordt in wachtlijst geplaatst onderste niveau: behandelt afwerking van aanvragen schiet in actie na het behandelen van een aanvraag wordt aangeroepen door interrupt: werkt interrupt-gestuurd moet eventueel proces verwittigen dat aanvraag behandeld is wachtlijst niet ledig: haalt aanvraag uit lijst, behandelt die wachtlijst ledig: doet niets Yolande Berbers Programmatuur voor real-time controle slide 17 RTP mechanismen voor hardware input/output twee-niveau device driver processen besturingssysteem slaap voegtoe bovenste niveau driver wachtlijst scheduler onderste niveau driver wordt wakker status Yolande Berbers herorden instructies device data neem uit interrupts Programmatuur voor real-time controle slide 18 RTP eisen voor taalondersteuning traditioneel gebruik van assembler taal zoals C biedt ook veel laag-niveau mogelijkheden talen zoals Modula-1, Ada bieden hoger-niveau ondersteuning Yolande Berbers Programmatuur voor real-time controle slide 19 RTP eisen voor taalondersteuning ondersteuning modulariteit en encapsulatie om de machine afhankelijke software te scheiden van machine-onafhankelijke software toegang tot registers vanuit hogere programmeertaal specificeren van specifieke fysische adressen voor variabelen (normaal kiest de compiler een plaats in adresruimte van proces) bit-manipulaties leesbaar kunnen doorvoeren abstract model voor het werken met een randapparaat randapparaat wordt gemodelleerd als aparte processor voorstelling van interrupts: zie volgende slide Yolande Berbers Programmatuur voor real-time controle slide 20 RTP eisen voor taalondersteuning voorstelling van interrupts in hogere programmeertalen procedureoproep werd eigenlijk uitgelegd bij interrupt-mechanisme gebruikt in C en C++ gebaseerde systemen sporadisch proces interrupt is aanvraag om een sporadisch proces op te starten asynchroon event interrupt is een asynchroon event gestuurd naar een handler synchronisatie zoals van gedeeld gegevens interrupt komt overeen met een signal bij monitor, met V bij semafoor, met een oproep van protected object gebruikt in Modula-1, Ada boodschap: interrupt is als een lege boodschap Yolande Berbers Programmatuur voor real-time controle slide 21 RTP schrijven van een driver in Ada Ada voorziet attributen als ondersteuning voor toegang tot registers size: specificeert het aantal bits voor een variabele alignment: specificeert dat variabele moet geplaatst worden op bepaalde grenzen (bv woord) bit-ordering: specificeert big-endian of little-endian address: specificeert op welk adres de variabele moet voorstelling van interrupt protected object om registers (dit zijn gedeelde var.) te beschermen een parameter-loze procedure van het protected object wordt geassocieerd met de interrupt: deze procedure is de interruptroutine Yolande Berbers Programmatuur voor real-time controle slide 22 RTP schrijven van een driver in Ada toepassing: driver die een A/D convertor leest deze driver wordt gerealiseerd in een package Adc_Device_Driver gebruiker kan enkel de procedure Read oproepen intern gebruikt de driver een protected object Interrupt_Interface aan de interrupt van het randapparaat wordt de procedure Handler van het protected object geassocieerd het protected object heeft verder twee entries entry Read: – wordt opgeroepen vanuit de procedure Read – een guard houdt volgende oproepen tegen – het randapparaat krijgt de opdracht – de aanvraag wordt geplaatst achter de entry Done entry Done: – procedure Handler opent de guard van deze entry – entry test op goede afloop – entry opent de guard van Read Yolande Berbers Programmatuur voor real-time controle slide 23 RTP schrijven van een driver in Ada randapparaat heeft twee registers data register van 16 bit dat de gegevens bevat controle register waarvan de bits de volgende betekenis hebben Bit 0 6 7 8-13 15 Yolande Berbers Naam Betekenis A/D Start Set to 1 to start a conversion. Interrupt Enable/Disable Set to 1 to enable interrupts. Done Set to 1 when conversion is complete. Channel The converter has 64 analog inputs; the one required is indicated by bits 8-13 Error Set to 1 by converter if device malfunctions. Programmatuur voor real-time controle slide 24 package Adc_Device_Driver is Max_Measure : constant := (2**16)-1; type Channel is range 0..63; subtype Measurement is Integer range 0..Max_Measure; procedure Read(Ch: Channel; M : out Measurement); Conversion_Error : exception; private for Channel'Size use 6; -- indicates that six bits only must be used end Adc_Device_Driver; with Ada.Interrupts.Names; use Ada.Interrupts.Names; with System; use System; with System.Storage_Elements; use System.Storage_Elements; package body Adc_Device_Driver is Bits_In_word : constant := 16; word : constant := 2; type Flag in (Down, Set); type Control_Register is record Ad_Start: Flag; Done: Flag; Error: Flag; end record; -- bits in word -- bytes in word Ienable: Ch: Flag; Channel; for Control_Register use -- specifies the layout of the control register record Ad_Start at 0*Word range 0..0; -- at word 0 bit 0 Ienable at 0*Word range 6..6; Done at 0*Word range 7..7; Ch at 0*Word range 8..13; Error at 0*Word range 15..15; end record; for Control_Register'Size use Bits_In_Word; -- the register is 16 bits long for Control_Register'Alignment use Word; -- on a word boundary for Control_Register'Bit_order use Low_Order_First; type Data_Register is range 0 .. Max_Measure; for Data_Register'Size use Bits_In_Word; -- the register is 16 bits long Contr_Reg_Addr: constant Address := To_Address (8#150002#) Data_Reg_Addr: constant Address := To_Address (8#150000#) Adc_Priority: constant Interrupt_Priority := 63; Control_Reg: aliased Control_Register; -- aliased indicates that pointers are used to access it for Control_Reg'Address use Contr_Reg_Addr; -- specifies the address of the control register Data_Reg : aliased Data_Register; for Data_Reg'Address use Data_Reg_Addr; -- specifies the address of the data register protected type Interrupt_Interface(Int_Id : Interrupt_Id; Cr : access Control_Register; Dr : access Data_Register) is entry Read(Chan : Channel; M : out Measurement); private entry Done(Chan : Channel; M : out Measurement); procedure Handler; pragma Attach_Handler (Handler, Int_Id) pragma Interrupt_Priority(Adc_Priority) -- see Section 13.10 for discussion on priorities Interrupt_Occurred : Boolean := False; Next_Request : Boolean := True; end Interrupt_Interface; Adc_Interface : Interrupt_Interface(Names.Adc, Control_Reg'Access, Data_Reg'Access); -- this assumes that 'Adc' is registered as an Interrupt_Id -- in Ada.Interrupts.Names -- 'Access gives the address of the object protected body Interrupt_Interface is entry Read(Chan : Channel; M out Measurement) when Next_Request is Shadow_Register: Control_Register; begin Shadow_Register := (Ad_Start => Set, Ienable => Set, Done => Down, Ch => Chan, Error => Down); -- opdat alle velden in één keer in het register geschreven: -- velden worden eerst in een copie geschreven Cr.all := Shadow_Register; -- het geven van de opdracht Interrupt_Occurred := False; Next_Request := False; requeue Done; end Read; procedure Handler is begin Interrupt_Occurred := True; end Handler; entry Done(Chan Channel; M : out Measurement) when Interrupt_Occurred is begin Next_Request := True; if Cr.Done = Set and Cr.Error = Down then M := Measurement(Dr.all); else raise Conversion_Error; end if; end Done; end Interrupt_Interface; procedure Read(Ch : Channel; M out Measurement) is begin for I in 1..3 loop begin Adc_Interface.Read(Ch,M); return; exception when Conversion_Error => null; end; end loop; raise Conversion_Error; end Read; RTP een voorbeeld-driver in C analoge operaties op registers als in het vb met Ada #define START 01 /* numbers beginning with 0 are in hexadecimal */ #define ENABLE 040 #define ERROR 08000 unsigned short int *register, shadow, channel; register = 0AA12; /* register address */ channel = …; shadow = 0; shadow = (channel << 8) | START | ENABLE; *register = shadow; dit is de enige compiler-onafhankelijke manier Yolande Berbers Programmatuur voor real-time controle slide 32