130 likes | 243 Views
PMU Agenda. Concurrent Model Real Time Model. Environment (1). public createEvents: () ==> () createEvents () == ( if len inlines > 0 then ( dcl curtime : nat := NewWorld`timerRef.GetTime(), done : bool := false; while not done do
E N D
PMU Agenda • Concurrent Model • Real Time Model
Environment (1) public createEvents: () ==> () createEvents () == ( if len inlines > 0 then ( dcl curtime : nat := NewWorld`timerRef.GetTime(), done : bool := false; while not done do def mk_(eventtype, theEvent, timestamp) = hd inlines in if timestamp <= curtime then ( cases eventtype: 1 -> ( def mk_(cpr, eventid, datatype, devicedata) = theEvent in for all device in set elems devices do if (device.getCprNr() = cpr and device.getDeviceType() = datatype) then ( device.poll(eventid, datatype, devicedata, timestamp) ), 2 -> ( def mk_(cpr, eventid) = theEvent in for all pmu in set elems pmus do if (pmu.getPMUId() = cpr) then ( pmu.proximity() ), others -> Printer`Out("Env: Something bad happened... crap...") end; inlines := tl inlines; done := len inlines = 0; ) else done := true ) else busy := false);
Environment (2) Event (Data) [mk_(1, mk_(2508821401, 1, 1, [mk_(1,0), mk_(1,1), mk_(1,2), mk_(2,3), mk_(3,4)]), 10), mk_(2, mk_(2, 2508821401), 20)] EventData = EventType * Event * TimeStamp Event = Data | ProximityEvent Data = CprNr * EventId * DataType * seq of DeviceData DeviceData = nat * TimeStamp ProximityEvent = EventId * CprNr EventType (Data poll event) TimeStamp Event (Proximity) EventType (Proximity event) TimeStamp
MedicalDevice • Contains the data the PMU is collecting. The environment instigates the polling on the correct medicaldevice based on the CPR nr and device type. public poll: EventId * DataType * seq of DeviceData * TimeStamp ==> () poll(evid, dtype, devicedata, ts) == ( pmuref.collectDeviceData(evid, dtype, devicedata, ts) );
PMU public collectDeviceData : EventId * DataType * seq of DeviceData * TimeStamp ==> () collectDeviceData(evid, datatype, devicedata, ts) == ( if datatype = 3 then (mdDataPrio3 := mdDataPrio3 ^ [mk_(evid, datatype, devicedata, ts)];) else if datatype = 2 then (mdDataPrio2 := mdDataPrio2 ^ [mk_(evid, datatype, devicedata, ts)];) else if datatype = 1 then (mdDataPrio1 := mdDataPrio1 ^ [mk_(evid, datatype, devicedata, ts)];) ); processData: () ==> () processData() == ( ( for all analyzerId in set dom analyzer do if(analyzerId = HEARTRATE) then def mk_(evid, datatype, devicedata, pt) = getData(mdDataPrio3) in ( while (len mdDataPrio3 > 0) do (analyzer(analyzerId).addData(evid, datatype, devicedata, pt)) ) else if(analyzerId = TAKEMEDICIN) then def mk_(evid, datatype, devicedata, pt) = getData(mdDataPrio2) in ( while (len mdDataPrio3 = 0 and len mdDataPrio2 > 0) do (analyzer(analyzerId).addData(evid, datatype, devicedata, pt)) ) else if(analyzerId = WEIGHT) then def mk_(evid, datatype, devicedata, pt) = getData(mdDataPrio1) in ( while (len mdDataPrio3 = 0 and len mdDataPrio2 = 0 and len mdDataPrio1 > 0) do (analyzer(analyzerId).addData(evid, datatype, devicedata, pt)) ) ) );
Analyzer public doStuff: () ==> () doStuff() == ( (dcl curData : Data := hd dataBuffer; def mk_(evid, datatype, devicedata, pt) = curData in ( if hasBattery then batMonitor.drain(20); for all value in set elems devicedata ( def mk_(val, timestamp) = value in ( oldValue := curValue; curValue : = val; if(curValue - oldValue > 5) transmitter.send(evid, HEART_RATE_SPIKE, devicedata, NewWorld`timerRef.GetTime()); ); ): dataBuffer := tl dataBuffer; if len dataBuffer = 0 then busy:= false; ) ) );
Transmitter • Sorts messages by priority and transmits the highest priority first. sortByPriority: TransmitData * seq of TransmitData ==> seq of TransmitData sortByPriority(val, sorted) == ( cases true: (len sorted = 0) -> return [val], (val.#2 <= (hd sorted).#2) -> return [val] ^ sorted, others -> return [hd sorted] ^ sortByPriority(val, tl sorted) end ); private sendMessage: () ==> () sendMessage() == ( if busy then ( dcl msg : TransmitData := hd prioritizedBuffer; prioritizedBuffer := tl prioritizedBuffer; Environment'handleEvent(msg, NewWorld`timerRef.GetTime()); battery.drain(drainVolume(msg.#2)); busy:=len buffer > 0 ) );
BatteryMonitor • Symbolizes the battery and the drain on this from different operations. If there’s no battery left, processes are halted in the drain call. public drain: nat ==> () drain(drainVolume) == batteryLife := batteryLife - drainVolume; sync mutex(drain); mutex(drain, getBatteryLife, recharge); per drain => batteryLife > 0
Real Time MedicalDevice • The analysis algorithm has a cycles added due to the computation. async public poll: EventId * DataType * seq of DeviceData * TimeStamp ==> () poll(evid, dtype, devicedata, ts) == ( pmuref.collectDeviceData(evid, dtype, devicedata, ts) );
Real Time PMU • Thread becomes periodic a number of cycles is added to processData. collectDeviceData has a duration added due to communication initialization. thread periodic(500, 0, 0, 0) (processData) processData: () ==> () processData() == cycles(100) ( … ); public collectDeviceData : EventId * DataType * seq of DeviceData * TimeStamp ==> () collectDeviceData(evid, datatype, devicedata, ts) == duration(20) ( … );
Real Time Analyzer thread periodic(500, 100, 0, 0) (doStuff) public doStuff: () ==> () doStuff() == Cycles(5000) ( … );
Real Time Transmitter async public transmit: TransmitData ==> () transmit(data) == ( buffer := sortByPriority(data, buffer); busy:= true; ); thread periodic(500, 10, 0, 0) (sendMessage) private sendMessage: () ==> () sendMessage() == duration(50) ( … );