Commit 269d7dcc authored by Christian Dietrich's avatar Christian Dietrich

osek-v: static alarms

We will identify static alarms. A static alarm is configured running
within the OIL file, and is never touched by
CancelAlarm/SetRelAlarm/SetAbsAlarm. The OSEK-V architecture will not
emit code for manaing static alarms. They are managed by the hardware.

Change-Id: I7ebd5c06120cbdf6e36a60f2939b5a5f01eb5962
parent 5c5a7ea2
......@@ -14,7 +14,6 @@ class OSEKVArch(GenericArch):
with self.generator.open_file("linker.ld") as fd:
fd.write("IGNORED IN OSEK-V")
def generate_dataobjects(self):
"""Generate all dataobjects for the system"""
self.logic = self.system_graph.get_pass("LogicMinimizer")
......@@ -62,15 +61,41 @@ class OSEKVArch(GenericArch):
subtask.impl.task_id = task_id
def generate_rocket_config(self):
static_alarm_pass = self.system_graph.get_pass("static-alarms")
alarms = {}
# Generate rocket configuration for static alarms
if len(static_alarm_pass.static_alarms) > 0:
static_alarms = []
entry_abb = self.system_graph.AlarmHandlerSubtask.entry_abb
exit_abb = self.system_graph.AlarmHandlerSubtask.exit_abb
for alarm in self.system_graph.AlarmHandlerSubtask.alarms:
if not alarm in static_alarm_pass.static_alarms:
continue
config = static_alarm_pass.static_alarms[alarm]
# namedtuple -> OrderedDict -> dict
config = dict(config._asdict())
config["name"] = alarm.name
config["fsm_signal"] = self.syscall_rules.fsm_event_number(alarm.carried_syscall)
static_alarms.append(config)
alarm_entry_signal = self.syscall_rules.fsm_event_number(entry_abb)
alarm_exit_signal = self.syscall_rules.fsm_event_number(exit_abb)
alarms = {"basePeriod": static_alarm_pass.base_period,
"staticAlarms": static_alarms,
"entrySignal": alarm_entry_signal,
"exitSignal": alarm_exit_signal,
"count": len(static_alarms)}
with self.generator.open_file("rocket.config") as fd:
config = {
"coreHartCount": 1 << self.logic.action_len,
"coreOSEKSyscallWidth": self.logic.event_len,
"coreOSEKStateWidth": self.logic.state_len,
"coreOSEKInitialState": int(self.logic.fsm.initial_state, 2),
"coreHartCombinatorics":self.logic.minimized_truth_table_path
"coreHartCombinatorics":self.logic.minimized_truth_table_path,
"alarms": alarms,
}
fd.write(json.dumps(config))
fd.write(json.dumps(config,indent=2, sort_keys=True))
def generate_isr_table(self, isrs):
self.generator.source_file.include("interrupt.h")
......
......@@ -79,20 +79,24 @@ class WiredSystemCalls(BaseCoder):
def ShutdownOS(self, block):
FullSystemCalls.ShutdownOS(self, block)
def fsm_schedule(self, syscall, userspace, kernelspace):
def fsm_event_number(self, syscall):
fsm = self.system_graph.get_pass("LogicMinimizer").fsm
event = None
for ev in self.fsm.events:
if self.fsm.event_mapping[ev.name] == syscall:
for ev in fsm.events:
if fsm.event_mapping[ev.name] == syscall:
event = ev
break
if event is None:
print(syscall, None)
return
return int(event.name, 2)
bitstr = event.name
def fsm_schedule(self, syscall, userspace, kernelspace):
number = self.fsm_event_number(syscall)
if number is None:
return (syscall, None)
self.call_function(kernelspace, "Machine::syscall",
"void", [str(int(bitstr, 2))])
print(syscall, int(bitstr,2))
"void", [str(number)])
print(syscall, number)
def kickoff(self, syscall, userspace, kernelspace):
......
......@@ -166,6 +166,9 @@ if __name__ == "__main__":
pass_manager.register_analysis(FiniteStateMachineBuilder())
pass_manager.register_analysis(LogicMinimizer())
pass_manager.register_analysis(StaticAlarms())
# Statistics modules
pass_manager.register_analysis(GlobalControlFlowMetric("%s/%s_metric" % (options.prefix, conf.app.name)))
......@@ -220,6 +223,7 @@ if __name__ == "__main__":
pass_manager.get_pass("sse").use_app_fsm = True
pass_manager.enqueue_analysis("LogicMinimizer")
pass_manager.enqueue_analysis("fsm")
pass_manager.enqueue_analysis("static-alarms")
syscall_rules = WiredSystemCalls()
else:
assert False
......
from generator.analysis.Analysis import Analysis
from generator.analysis.AtomicBasicBlock import E, S
from generator.coder.elements import DataObject, Include
from collections import namedtuple
from fractions import gcd
import logging
class StaticAlarms(Analysis):
"""Checks all configured alarms in the system to be static. A static
is a alarm, that is configured only statically and runs all
the. (No CancelAlarm, SetRelAlarm)
"""
pass_alias = "static-alarms"
AlarmConfiguration = namedtuple("AlarmConfiguration", ["reltime", "cycletime"])
def requires(self):
return ["llvmpy"]
def do(self):
# By default all alarms are static
static_counters = {x: True for x in self.system_graph.counters}
static_alarms = {x: True for x in self.system_graph.alarms}
for abb in self.system_graph.abbs:
# All manipulated alarms and counters are non-static
if abb.isA([S.SetRelAlarm, S.CancelAlarm]):
static_alarms[abb.arguments[0]] = False
if abb.isA([S.AdvanceCounter]):
static_counters[abb.arguments[0]] = False
# An alarm can't be static, if the counter isn't static
for alarm in static_alarms:
if not static_counters[alarm.conf.counter]:
static_alarms[alarm] = False
# Only the static alarms
alarms_static = [k for k,v in static_alarms.items() if v]
base_period = None
for alarm in static_alarms:
if not alarm.conf.armed:
continue
if not base_period:
base_period = alarm.conf.reltime
base_period = gcd(base_period, alarm.conf.reltime)
base_period = gcd(base_period, alarm.conf.cycletime)
self.base_period = base_period
self.static_alarms = {}
for alarm in static_alarms:
if not alarm.conf.armed:
continue
self.static_alarms[alarm] = self.AlarmConfiguration(
reltime = alarm.conf.reltime//self.base_period,
cycletime = alarm.conf.cycletime//self.base_period,
)
......@@ -4,3 +4,5 @@ from .FiniteStateMachineBuilder import *
from .CFGRegions import CFGRegions
from .GenerateAssertions import *
from .LogicMinimizer import LogicMinimizer
from .StaticAlarms import StaticAlarms
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment