blob: 6342edf7fe7d03ccaebd758bf29e215dd335f4fb [file] [log] [blame]
h2. Constraints Model
The constraints model contains different kind of constraints. There are the runnable-sequencing-constraints that can be used to define a required order for the runnables of the Software Model, the affinity constraints for defining the constraints for the mapping of runnables, processes and schedulers, and the timing constraints for restricting the time span between events or the duration of event chains. Regarding to that, it is also possible to define event chains in this model.
!../pictures/model_constraints.png!
h3. Requirements
The Requirements are used to specify quality requirements for the dynamic architecture.
Requirements are divided into the following types depending on the entity type for which the requirement is specified:
* Architecture Requirements for components
* Process Chain Requirements for process chains
* Process Requirements for tasks and ISRs
* Runnable Requirements for runnables
The Severity attribute is used to describe the quality impact if the requirement is not fulfilled.
The Limit defines the metric, the value, and whether the value for the metric is an upper or a lower bound.
Depending on the metric unit, the following Limits can be distinguished:
* Count Requirement Limit for metrics that count system actions
* CPU Percentage Requirement Limit for metrics that specify relative CPU characteristics
* Frequency Requirement Limit for metrics that measure the frequency of system actions
* Percentage Requirement Limit for metrics that specify relative system characteristics
* Time Requirement Limit for metrics that describe time intervals
!(scale)../pictures/model_constraints_requirements.png!
Time Metric groups all metrics that describe time intervals of an individual process instance or between two succeeding process instances and are defined here. Note that the colors of the various time slices depicted here, directly correspond to the states and colors from the BTF specification. The metrics for individual process instances include the following:
* __**CoreExecutionTime**__: This metric quantifies the amount of time of a process instance between its start and termination in which it is actively executed on a specific processing unit.<br/> !../pictures/model_constraints_metric_coreexecutiontime.png!
* __**GrossExecutionTime**__: This metric indicates the time interval between the start moment and the termination moment of a process instance.<br/> !../pictures/model_constraints_metric_grossexecutiontime.png!
* __**Lateness**__: This metric indicates whether a process instance misses its deadline. It quantifies the amount of time between the termination moment of the process instance and its deadline. Thus, the resulting lateness is negative and indicates that no deadline miss occurred if the termination moment of the process instance is before the deadline and vice versa.<br/> !../pictures/model_constraints_metric_lateness.png!
* __**MemoryAccessTime**__: This metric quantifies the amount of time that is required by a process for transferring data from or to the memory.
* __**NetExecutionTime**__: The net execution time indicates the actual execution time of a process instance, i.e., the time it is occupying a processing unit. Thus, it quantifies the time from the start moment of a process instance to its termination moment excluding the time the process instance is interfered.<br/> !../pictures/model_constraints_metric_netexecutiontime.png!
* __**OsOverhead**__: This metric indicates the amount of execution time that is consumed by functions that are part of the operating system.
* __**ParkingTime**__: This metric quantifies the amount of time that a process instance spends between its start and termination passively waiting for the access of a resource.<br/> !../pictures/model_constraints_metric_parkingtime.png!
* __**PollingTime**__: This metric quantifies the amount of time that a process instance spends between its start and termination actively waiting for the access of a resource.<br/> !../pictures/model_constraints_metric_pollingtime.png!
* __**ReadyTime**__: This metric quantifies the amount of time of a process instance between its start and termination in which it is not actively executed on any processing unit.<br/> !../pictures/model_constraints_metric_readytime.png!
* __**ResponseTime**__: The response time of a task or ISR instance is defined as the time between the moment of its activation and its termination. Thus, it measures the whole life cycle of a process instance.<br/> !../pictures/model_constraints_metric_responsetime.png!
* __**RunningTime**__: This metric quantifies the amount of time of a process instance between its start and termination in which it is actively executed on any processing unit.<br/> !../pictures/model_constraints_metric_runningtime.png!
* __**StartDelay**__: This metric quantifies the delay of the start time of a process instance which is defined as the time interval between the activation moment of this process instance and its start moment.<br/> !../pictures/model_constraints_metric_startdelay.png!
* __**WaitingTime**__: This metric quantifies the amount of time that a process instance spends between its start and termination passively waiting for an OS event.<br/> !../pictures/model_constraints_metric_waitingtime.png!
Inter process instance metrics include the following:
* __**ActivateToActivate**__: This metric indicates the distance between two successive activations of a task or isr. The __ActivateToActivate__ metric of process instance n quantifies the time between the activation moment of process instance n and that of instance n+1.<br/> !../pictures/model_constraints_metric_activatetoactivate.png!
* __**EndToEnd**__: This metric indicates the time interval between two successive ends of a process. The __EndToEnd__ metric of process instance n quantifies the time between the termination moment of process instance n and that of instance n+1.<br/> !../pictures/model_constraints_metric_endtoend.png!
* __**EndToStart**__: This metric indicates the time interval between two successive process instances. The __EndToStart__ metric of process instance n quantifies the time between the termination moment of process instance n and the start moment of instance n+1.<br/> !../pictures/model_constraints_metric_endtostart.png!
* __**StartToStart**__: This metric indicates the time interval between two successive starts of a process. The __StartToStart__ metric of process instance n quantifies the time between the start moment of process instance n and that of instance n+1.<br/> !../pictures/model_constraints_metric_starttostart.png!
Count Metrics are metrics that describe absolutely how often system characteristics occur and are defined as follows:
* __**Activations**__: This metric quantifies the number of times a process is activated.
* __**BoundedMigrations**__: This metric quantifies the number of times a process instance starts executing on a processing unit that is different to the processing unit on which the previous process instance terminated.
* __**CacheHit**__: This metric quantifies the amount of times that data requested by a process is found in the cache memory.
* __**CacheMiss**__: This metric quantifies the amount of times that data requested by a process is not stored in the cache memory and has to be fetched from somewhere else.
* __**FullMigrations**__: This metric quantifies the number of times a process instance migrates from one processing unit to another triggered by a schedule point.
* __**MtaLimitExceeding**__: This metric quantifies the number of times a process is not activated during runtime because this would violate the maximum number of concurrently activated processes (MTA).
* __**Preemptions**__: This metric quantifies the number of times a process is preempted by another task or ISR.
Frequency Metric groups all metrics that describe the rate in which system characteristics occur and are defined as follows:
* __**CacheHitFrequency**__: This metric quantifies how often per unit of time data requested by a process is found in the cache memory.
* __**CacheMissFrequency**__: This metric quantifies how often per unit of time data requested by a process is not found in the cache memory.
CPU Percentage Metric groups all metrics that describe a ratio between the amount of time a processing unit is in a certain state for a specific process and the maximum capacity of the considered processing unit and are defined as follows:
* __**CPUBuffering**__: This metric quantifies the ratio between the amount of time a processing unit is in the state buffering for a specific process and the maximum capacity of the considered processing unit.
* __**CPULoad**__: This metric quantifies the ratio of the load of a processing unit caused by a process and the maximum capacity of the considered processing unit.
* __**CPUParking**__: This metric quantifies the ratio between the amount of time a processing unit is in the state parking for a specific process and the maximum capacity of the considered processing unit.
* __**CPUPolling**__: This metric quantifies the ratio between the amount of time a processing unit is in the state polling for a specific process and the maximum capacity of the considered processing unit.
* __**CPUReady**__: This metric quantifies the ratio between the amount of time a processing unit is in the state ready for a specific process and the maximum capacity of the considered processing unit.
* __**CPURunning**__: This metric quantifies the ratio between the amount of time a processing unit is in the state running for a specific process and the maximum capacity of the considered processing unit.
* __**CPUWaiting**__: This metric quantifies the ratio between the amount of time a processing unit is in the state waiting for a specific process and the maximum capacity of the considered processing unit.
Percentage Metric groups all metrics that describe a relationship between two system characteristics and are defined as follows:
* __**CacheHitRatio**__: This metric quantifies how often data requested by a process is found in the cache memory in comparison to how often it is not found.
* __**CacheMissRatio**__: This metric quantifies how often data requested by a process is not found in the cache memory in comparison to how often it is found.
* __**NormalizedLateness**__: This metric quantifies the lateness of a process instance in comparison to the process's maximum response time which is defined by its deadline.
* __**NormalizedResponseTime**__: This metric quantifies the response time of a process instance in comparison to the process's maximum response time which is defined by its deadline.
* __**OsOverheadRelative**__: This metric quantifies the amount of execution time that is consumed by functions that are part of the operating system in comparison to net execution time of the process in whose context the functions are called.
An example for a requirement is the deadline for a task. The deadline is specified by an upper limit for the response time of the respective task.
h3. Runnable Sequencing Constraints
These constraints can be used to define execution orders of runnables or, in other words, the dependencies between runnables. These dependencies can result from data exchange or any functional dependency that is not necessarily visible by other model parameters.
The following requirements can be specified with this constraint:
* Execution sequence of runnables A ->B, meaning A has to be finished before B starts
* Scope on certain process/processes, when a runnable is executed multiple times in different process contexts
* Succession of runnables within a process (strict, loose)
* Position of sequence within a process (start, end, any position)
!../pictures/model_constraints_runnable_sequencing.png!
A __RunnableSequencingConstraint__ contains a list of __ProcessRunnableGroup__ elements and an enumeration __RunnableOrderType__ describing the basic rule for the sequencing. In general, a runnable sequencing constraint is independent of the processes that execute the runnables. Via the attribute "processScope" it is possible to define that a sequencing constraint is only valid for runnables within just one process or a set of processes.
The __ProcessRunnableGroups__ contain references to runnables that should be sequenced. The sequence is defined by the order of the runnable groups within the sequencing constraint. The order of the runnable references within a group is undefined.
To sequence two runnables it is consequently necessary to create a __RunnableSequencingConstraint__ with two __ProcessRunnableGroups__, each referencing one of the runnables.
To describe that a set of runnables have to be executed before or after another runnable or set of runnables, it is possible to put more than one runnable reference in a group. As already mentioned, the order of the referenced runnables within a __ProcessRunnableGroup__ is unimportant.
The following picture visualises a __RunnableSequencingConstraint__ and multiple possible runtime situations. The constraint has two runnable groups, each depicted by an ellipsis. In this example, there is just one runnable in each group. The runnables in the groups must be executed in the order of the group ("R1" before "R2"). There is no restriction in which process context the runnables are executed. It is important that the order is correct and that the runnable of one group terminates before the runnable of the next group starts. The exemplary runtime situations shown in the lower part of the figure visualise situations that satisfy this constraint (blue) and those who violate the constraint (red).
!../pictures/model_constraints_runnable_sequencing_basic.png!
The __RunnableSequencingConstraint__ in the next figure has two processes set as a scope in its second group. That means that the runnable "R3" is allowed to be executed on the processes "P1" or "P3" (blue). But it is only expected to be executed one time in between (red)!
!../pictures/model_constraints_runnable_sequencing_scope.png!
Each __RunnableSequencingConstraint__ has a __RunnableOrderType__. It provides the following sequencing modes:
* successor
* immediateSuccessorAnySequence
* immediateSuccessorEndSequence
* immediateSuccessorStartSequence
The meaning of the mode "successor" is that the runnable groups of a sequencing constraint do not have to follow each other directly, i.e., runnables that are not part of the constraint can be executed in between.
In contrast to this, the modes starting with "immediateSuccessor" express that the runnables referenced by the runnable groups must execute in direct order, so without any runnable in between. With "StartSequence", "AnySequence" and "EndSequence" it is further constrained that the runnables of the constraint have to be executed at the beginning, at the end or at any position in a process.
Assuming that all runnables are executed on the same process, the mode "immediateSuccessorStartSequence" means that all runnables of the constraint have to be executed in the correct order at the beginning of the process.
The mode "immediateSuccessorEndSequence" is like "immediateSuccessorStartSequence", but here the runnable sequence must be executed at the end of the process.
h3. Data Age Constraints
Data Age constraints are used to define when the information in a label becomes valid or invalid after its last update. Therefore a runnable and a label has to be set. The information update occurs when the runnable performs a write access on the label. It is possible to define the minimum time after the information of a label update becomes valid. This means that the information shall not be used for further calculations before this time is over. The maximum time on the other hand defines the time after the label update when the information becomes invalid. Beside of time it is possible to define a minimum and maximum cycle. The cycle is related to the activation of the process that executes the runnable.
!../pictures/model_constraints_data_age.png!
*(validation-rule) DataAgeTime: The _Time_ object in the role of _minimumTime_ must not contain a negative value!
*(validation-rule) DataAgeTime: The _Time_ object in the role of _maximumTime_ must not contain a negative value!
h3. Data Coherency Groups
A __DataCoherencyGroup__ is used to define data coherency requirements for a group of labels.
The Direction hereby is used to specify if the labels have to be read or written coherently. Moreover, the scope attribute defines the context of the coherent read or write requirement. Possible scopes are components, processes, and runnables.
!../pictures/model_constraints_data_coherency.png!
h3. Data Stability Groups
A __DataStabilityGroup__ is used to define that the values of labels have to be kept stable within a given execution context.
Currently, the following execution contexts are covered by the scope:
* Component
* Process
* Runnable
This means that it has to be guaranteed that the values of labels are identical either within the runnable, the process, or the component in which the denoted labels are accessed.
!../pictures/model_constraints_data_stability.png!
h3. Event Chains
The concept for event chains is based on the Timing Augmented Description Language.
!../pictures/model_constraints_eventchain.png!
The __(Abstract)EventChain__ consists of __EventChainItems__. These items are classified in two types:
# EventChainReferences -> EventChain: Used to refer to already defined EvenChains.
# EventChainContainers -> SubEventChain: Inner anonymous EventChains, which are only available in the context of the current EventChain.
An Event Chain object references always two events, a stimulus event and a response event. To define a simple event chain that just contains two events, one event chain object is enough. In this case it would just be a chain that with its stimulus as first event and the response as second event.
If more events are required it is necessary to add sub event chains. The stimulus is always the first event of an event chain, the response is always the last event. The events that are defined in the sub event chains are the events in between.
When adding __EventChainItems__ there are two properties that decide on the semantics of the SubEventChains:
table(minimal){padding:10px; border:1px solid black; background:#f8f8f8}.
|_. Name |_. Description |
| __EventChainItemType__ | This property defines how to interpret the subEventChain. There exist two possibilities: __sequence__ and __parallel__. Sequence means that all the subEventChains are evaluated in the defined order of the list. Parallel path can be alterantive paths or joins. |
| __minItemsCompleted__ | Defines how the parallel execution is interpetated. The designer specifies how many elements of the subEventChains must be completed to go to the next step. __1__ represents alternative paths of the EventChain. If the number equals the number of elements in the __EventChainItems__ list all paths must be triggered to continue the event-chain tracking and represents a complete join of all subEventChains |
*Simple structural example for sequence*
!{width: 750px}../pictures/model_constraints_eventchain_sequence.png!
*Simple structural example for parallel paths*
!{width: 800px}../pictures/model_constraints_eventchain_parallel.png!
*Structural example how to combine both*
!{width: 650px}../pictures/model_constraints_eventchain_example.png!
The picture below shows a simple example for an event chain of four events in a row.
The top level chain defines the first event (E1) and the last event (E4).
It contains a number of event chains. They describe the way from E1 to E4.
These sub event chains are added as __sequence__ to the parent.
For this some rules has to be considered:
The stimulus of the first child event chain has to be the same as the stimulus of the parent (red in picture).
The stimulus of other child event chains have to be equal to the response of the previous chain (blue in picture).
The response of the last child event chain has to be the same as the response of the parent (green in picture).
!{width: 500px}../pictures/model_constraints_eventchain_segments.png!
As a stimulus or response event it is either possible to use an Entity Event or an Event Set.
An Entity Event is a single event regarding to an entity like a task or a runnable. So it can be e.g. the start of a runnable.
If a set of events is used, then all events of this group must occur fulfill the event chain. The order in which the events occur is not important.
!../pictures/model_constraints_eventchain_eventgroups.png!
h3. Timing Constraints
h4. Synchronization Constraints
An __EventSynchronizationConstraint__ describes how tightly the occurrences of a group of events follow each other.
There must exist a sequence of time windows of width tolerance, such that every occurrence of every event in events belongs to at least one window, and every window is populated by at least one occurrence of every event.
The parameter __multipleOccurrencesAllowed__ defines, whether for the constraint all occurrences have to be considered or just the subsequent ones.
An __EventChainSynchronizationConstraint__ describes how tightly the occurrences of an event chain follow the occurrences of a different event chain.
The __SynchronizationType__ defines which parts of the event chains have to be in sync, stimulus or response, and the width of a time window sets the allowed tolerance.
The parameter __multipleOccurrencesAllowed__ defines, whether for the constraint all occurrences have to be considered or just the subsequent ones.
!../pictures/model_constraints_timing_sync.png!
*(validation-rule) _SynchronizationConstraint_: The _Time_ object in the role of _tolerance_ must not contain a negative value!
h4. Repetition Constraint
A __RepetitionConstraint__ describes the distribution of the occurrences of a single event, including jitter.
Every sequence of span occurrences of event must have a length of at least lower and at most upper time units.
!../pictures/model_constraints_timing_repetition.png!
*(validation-rule) _RepetitionConstraint_: The _Time_ object in the role of _lower_ must not contain a negative value!
*(validation-rule) _RepetitionConstraint_: The _Time_ object in the role of _upper_ must not contain a negative value!
*(validation-rule) _RepetitionConstraint_: The _Time_ object in the role of _period_ must not contain a negative value!
*(validation-rule) _RepetitionConstraint_: The _Time_ object in the role of _jitter_ must not contain a negative value!
h4. Delay Constraint
!../pictures/model_constraints_timing_delay.png!
*(validation-rule) _DelayConstraint_: The _Time_ object in the role of _lower_ must not contain a negative value!
*(validation-rule) _DelayConstraint_: The _Time_ object in the role of _upper_ must not contain a negative value!
A Delay Constraint imposes limits between the occurrences of an event called source and an event called target.
Every instance of source must be matched by an instance of target within a time window starting at lower and ending at upper time units relative to the source occurrence.
A __MappingType__ defines whether there is a strong ( __OneToOne__ ), neutral ( __Reaction__ ), or weak ( __UniqueReaction__ ) delay relation between the events:
* __**OneToOne**__: According to page 18f of "TIMMO-2-USE Deliverable D11 'Language Syntax, Semantics, Metamodel V2'":https://itea3.org/project/workpackage/document/download/850/09033-TIMMO-2-USE-WP-2-D11Languagesyntax,semantics,metamodelV2, a constraint with this mapping type is satisfied if and only if __source__ and __target__ have the same number of occurrences and for each index __i__, if there is an __i__-th occurrence of source at time __x__ there is also an __i__-th occurrence of __target__ at time __y__ such that __lower__ &le; __y__ - __x__ &le; __upper__.<br/> This means that the source event and the target event have the same number of occurrences and no stray target occurrences are accepted.
!../pictures/model_constraints_delayconstraint_onetoone.png!
* __**Reaction**__: According to page 17f of "TIMMO-2-USE Deliverable D11 'Language Syntax, Semantics, Metamodel V2'":https://itea3.org/project/workpackage/document/download/850/09033-TIMMO-2-USE-WP-2-D11Languagesyntax,semantics,metamodelV2, a constraint with this mapping type is satisfied if and only if for each occurrence __x__ of __source__, there is an occurrence __y__ of __target__ such that __lower__ &le; __y__ - __x__ &le; __upper__.<br/> This means that multiple source event occurrences may be mapped to the same target event and stray target event occurrences are ignored.
!../pictures/model_constraints_delayconstraint_reaction.png!
* __**UniqueReaction**__: This mapping type is a mixture of the previous types by specifying that for every occurrence of the source event exactly one target event must occur within the defined time span. Thus, target events may not be shared between source events and stray target events violate the requirement. In contrast to the __OneToOne__ mapping case, the source event is not mapped to the first source event but is dropped as a violation, if a target event is missed.
!../pictures/model_constraints_delayconstraint_uniquereaction.png!
h4. Event Chain Latency Constraint
An __EventChainLatencyConstraint__ defines how long before each response a corresponding stimulus must have occurred ( __Age__ ), or how long after a stimulus a corresponding response must occur ( __Reaction__ ).
It always refers to an EventChain.
!../pictures/model_constraints_timing_latency.png!
*(validation-rule) _EventChainLatencyConstraint_: The _Time_ object in the role of _minimum_ must not contain a negative value!
*(validation-rule) _EventChainLatencyConstraint_: The _Time_ object in the role of _maximum_ must not contain a negative value!
h3. Affinity Constraints
Affinity constraints are used to define the mapping of executable objects to each other.
The objects that can be mapped are:
* Runnables
* Processes (Task or ISR)
* Labels
!../pictures/model_constraints_affinity.png!
An affinity constraint can either be a pairing or a separation constraint. A pairing constraint contains one amount of objects and a target. The pairing constraints say "All these objects must run together on this target". A separation constraint contains two groups of objects and a target. It says "This group of objects is not allowed to be mapped with the other group of objects on the specific target". So the separation constraint can be used to forbid a combination of objects on a target. It can also be used to say "These objects are not allowed to be mapped on this target". In this case only one group of the separation constraint is used.
Each affinity constraint has one or more targets. The type of the target depends on the type that should be mapped.
h4. Data Affinity Constraints
A __DataConstraint__ is used to define the mapping of label objects to memory units.
!../pictures/model_constraints_affinity_data.png!
h4. Process Affinity Constraints
A __ProcessConstraint__ is used to define the mapping of process (Task or ISR) objects to processing cores or scheduling units.
!../pictures/model_constraints_affinity_process.png!
h4. Runnable Affinity Constraints
A __RunnableConstraint__ is used to define the mapping of runnable objects to processing cores or scheduling units.
!../pictures/model_constraints_affinity_runnable.png!
h3. Physical Section Constraints
A __PhysicalSectionConstraint__ is used to to define the mapping of Section objects to Memories. This mapping of Section object to Memory objects specifies that corresponding *PhysicalSectionMapping* associated to this *Section* element can be allocated only in the mapped Memories.
bc. Example: PhysicalSectionConstraint with the below properties has the following semantic:
name: Ram1_Ram2_PhysicalSectionConstraint
Memories : RAM1, RAM2
Section : .abc.reini
Semantic: PhysicalSectionMapping for .abc.reini section can only be allocated either in RAM1 or RAM2 or in both. But not in other Memories.