Das Objekt Mittelwertbilder stellt - wie schon oben gesagt - ein
passives Objekt dar. Wir werden es daher grundsätzlich in
Form eines Task's implementieren. Dabei wird die Operation
Gib_Mittelwert
als Task-Entry realisiert werden.
Es liegt aufgrund der semantischen Beschreibung nahe, falls gerade keine Anforderung zum Übergeben eines Mittelwertes ansteht, einen neuen Temperaturwert vom Temperatur-Sensor einzulesen. Eine mögliche Implementierung lautet daher:
Die aufgeschobene Implementation des Task-Body's könnte folgendermaßen aussehen:
separate(Mittelwertbilder)
task body Mittelwert_Task is
type Mittelwert_Typ is
record
Anzahl: natural;
Summe: integer;
end record;
null_Mittelwert: constant Mittelwert_Typ := (
Anzahl =
Summe =
alter_Mittelwert: Mittelwert_Typ := (
Anzahl =
Summe =
neuer_Mittelwert: Mittelwert_Typ := null_Mittelwert;
-dieSpezifikationderISR
protected Temperatur_Sensor_Interrupt_Service_Routine is
entry Hole_Daten_ab;
for Hole_Daten_ab use at Temperatur_Sensor.Interrupt_Adr;
end Temperatur_Sensor_Interrupt_Service_Routine;
generic
size: in natural := 20;
type item is private;
package Generic_Buffer is
procedure Enqueue(I: in item);
procedure Dequeue(I: out item);
end Generic_Buffer;
package body Generic_Buffer is separate;
package Temperatur_Buffer is new Generic_Buffer(
size =
item =
protected body Temperatur_Sensor_Interrupt_Service_Routine is separate;
begin
loop
select
accept
Gib_Mittelwert(
Mittelwert: out Temperatur_Sensor.Temperatur) do
if neuer_Mittelwert = null_Mittelwert then
-seitderletztenAnfragekeinneuerWerteingetroffen
Mittelwert := Temperatur_Sensor.Temperatur(
alter_Mittelwert.Summe
else
-berechneMittelwert
Mittelwert := Temperatur_Sensor.Temperatur(
neuer_Mittelwert.Summe
alter_Mittelwert := neuer_Mittelwert;
neuer_Mittelwert := null_Mittelwert;
end if;
end Gib_Mittelwert;
else
-holeneuenMesswertab
declare
Temp: Temperatur_Sensor.Temperatur;
begin
Temperatur_Buffer.Dequeue(Temp);
-summiereauf
declare
s1: integer := neuer_Mittelwert.Anzahl + 1;
s2: integer := neuer_Mittelwert.Summe + integer(Temp);
begin
neuer_Mittelwert.Anzahl := s1;
neuer_Mittelwert.Summe := s2;
exception
when others =
null; -lasseMittelwertsowieerwar
end;
end;
end select;
end loop;
end Mittelwert_Task;
Es bleibt also nur noch die Implementation der Interrupt-Service-Routine, d.h. jenes Entry's eines geschützten Objektes, der aufgerufen wird, wenn der entsprechende Interrupt ausgelöst wird.
separate(Mittelwertbilder)
protected body Temperatur_Sensor_Interrupt_Service_Routine is
entry Hole_Daten_ab when true is
begin
Temperatur_Buffer.Enqueue(Temperatur_Sensor.Temp);
Temperatur_Sensor.Temp_Sens_Port.ready := true;
end Hole_Daten_ab;
end Temperatur_Sensor_Interrupt_Service_Routine;
Johann Blieberger