Skip to content

Added FEO feature architecture #1109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions docs/features/frameworks/feo/architecture/_assets/dyn_arch.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/'
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
'/

box "Primary Process" #E0E0E0
participant "Primary Agent" as prim
participant "Scheduler" as scheduler
participant "UserActivity 1" as activity_1
end box

box "Secondary Process 1" #F0F0F0
participant "Secondary Agent 1" as sec_1
participant "UserActivity 2" as activity_2
participant "UserActivity 3" as activity_3
end box

box "Secondary Process 2" #F0F0F0
participant "Secondary Agent 2" as sec_2
participant "UserActivity 4" as activity_4
end box


== Process Startup ==

prim -> prim: create \nworker threads
sec_1 -> sec_1: create \nworker threads
sec_2 -> sec_2: create \nworker threads

sec_1 -> prim: connect
sec_2 -> prim: connect


prim -> scheduler: sync_remotes()
activate scheduler

scheduler -> sec_1: sync
scheduler -> sec_2: sync
sec_1 -> sec_1: sync
sec_2 -> sec_2: sync
sec_1 --> scheduler: ready
sec_2 --> scheduler: ready

scheduler --> prim: ok
deactivate scheduler


== Activity Startup ==

note over scheduler, activity_4
Call each activity's startup() method exactly once in an arbitrary order.
end note

prim -> scheduler: run()
activate scheduler

scheduler -> activity_1: startup()
activity_1 -> activity_1: startup
activity_1 --> scheduler: ready

scheduler -> sec_1: startup(a2)
sec_1 -> activity_2: startup()
activity_2 -> activity_2: startup
activity_2 --> sec_1: ready
sec_1 --> scheduler: ready(a2)

scheduler -> sec_1: startup(a3)
sec_1 -> activity_3: startup()
activity_3 -> activity_3: startup
activity_3 --> sec_1: ready
sec_1 --> scheduler: ready(a3)

scheduler -> sec_2: startup(a4)
sec_2 -> activity_4: startup()
activity_4 -> activity_4: startup
activity_4 --> sec_2: ready
sec_2 --> scheduler: ready(a4)

== Main Loop ==

loop

note over scheduler, activity_4
Call each activity's step() method in the order defined by the activity graph.
end note

note over scheduler, activity_4 #FFAAAA
TODO: The loop end-conditions are not yet defined in the feature request. => Endless loop.
end note

scheduler -> sec_1: step(a3)
sec_1 -> activity_3: step()
activity_3 --> sec_1: ready
sec_1 --> scheduler

scheduler ->?: step(.)
scheduler <--?: ready(.)

rnote over scheduler
...
end note

hnote over scheduler
sleep until end
of cycle time
end note

end loop

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is by intention incomplete, correct?
For the failure analysis it would be good to have one complete cycle visible in the diagrams

== Activity Shutdown ==

note over scheduler, activity_4
Call each activity's shutdown() method exactly once in an arbitrary order.
end note

scheduler -> activity_1: shutdown()
activity_1 -> activity_1: shutdown
activity_1 --> scheduler: ready

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

rnote over scheduler
...
end note

scheduler -> sec_2: shutdown(a4)
sec_2 -> activity_4: shutdown()
activity_4 -> activity_4: shutdown
activity_4 --> sec_2: shutdown
sec_2 --> scheduler: shutdown(a4)

scheduler --> prim: ok

deactivate scheduler

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diagram depicts nicely the interaction with the user application.
We should add the logical interfaces of external components e.g. mw::com, mw::log. At least this is my understanding of https://eclipse-score.github.io/score/main/process/process_areas/architecture_design/architecture_concept.html#static-view.

Additionally it would be good to indicate the system boundaries of the features as it was is done in https://eclipse-score.github.io/score/pr-1109/features/communication/ipc/architecture/feature_architecture.html#static-architecture

60 changes: 60 additions & 0 deletions docs/features/frameworks/feo/architecture/_assets/stat_arch.puml
Copy link
Contributor

@qor-lb qor-lb May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thinks this mixes component and feature architecture a little bit. The goal of the feature architecture is to allocate the feature requirements towards the involved components, however the implementation behind the components would be expected in the component architecture.

From my point of view, the FEO feature consists of these high-level components:

  • FEO
  • Communication
  • Logging

In the 1.0 I would extend the components with Time and potentially Trace, however these components will be part of FEO in the 0.5, therefore included in the component above.

The feature architecture should make it clear, which use-cases/requirements we allocate (additionally) to the IPC component that was already identified in the IPC Feature. In the end the IPC component needs to implement the requirements identified by the IPC feature, as well as the requirements identified in the FEO feature.

The architecture behind the FEO component is something that I would not expect in the Feature Architecture but the Component Architecture. I.e. Agents, Primary/Secondary Process, Scheduler, .... is something that is component implementation specific and driven by the requirements identified at feature level but should be detailed at the component level.

@armin-acn / @ramceb would you agree or do you see this differently? We discussed a similar situation in communication with @LittleHuba and ended up separating component architecture (later moved to the module repo) and feature architecture (staying in the main score repo).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@qor-lb, I agree that my current proposal of feature architecture looks a bit like a component architecture, but it follows the feature request. The feature request talks about Agents, Primary/Secondary Process, Executor/Scheduler etc. Thus, the feature architecture needs to pick it up somehow.

In the proposal, I tried to show how these entities are related to each other according to the description in the feature architecture. If I would make it even more generic, there wouldn't be much left, I assume, but maybe you have a good idea.

However, I would not agree that the FEO feature consists of FEO, Communication, and Logging. Communication and Logging are their own features according to my understanding, and the FEO implementation will just use components they provide. But maybe I am somehow misunderstanding the concepts here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would agree that we should have a feature architecture focusing on the behavior of the involved components on the (system) boundaries of the features and a component architecture depicting the interaction of the components.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/'
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************
'/
allowmixing

package FEO <<feature>> as feat_feo {

struct "feo::agent::Primary" as feo_primary
struct "feo::agent::PrimaryConfig" as feo_primary_config
struct "feo::agent::Secondary" as feo_secondary
struct "feo::agent::SecondaryConfig" as feo_secondary_config
struct "feo::scheduler::Scheduler" as feo_scheduler {
run()
sync_remotes()
}

interface "feo::activity::Activity" as activity {
startup()
step()
shutdown()
}

feo_primary -d-> activity: use
feo_primary -d-> feo_scheduler: use

feo_secondary -d-> activity: use

}

package "User Application" <<application>> as user_application {

component "Primary Process" as PP
component "Secondary Process" as SP

struct "UserActivity_1" as user_activity_1
struct "UserActivity_2" as user_activity_2

PP -d-> user_activity_1 : use
SP -d-> user_activity_2 : use

user_activity_1 .d.|> activity : impl
user_activity_2 .d.|> activity : impl
}

PP -d-> feo_primary : use
PP -d-> feo_primary_config : use
SP -d-> feo_secondary : use
SP -d-> feo_secondary_config : use

146 changes: 146 additions & 0 deletions docs/features/frameworks/feo/architecture/feature_architecture.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
..
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

Feature Architecture: FEO
=========================

Overview
--------
The current implementation of the feature "FEO" (Fixed Execution Order Framework) consists of a main
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should describe here, what the feature should do even if this does not reflect the current implementations. We could add an own chapter "Limitations/Known Issues" which just reflects, what is not implemented yet.

component and a set of auxiliary components that will be either replaced by or turned into
wrappers to components from other Score features. In the latter case, these wrappers will possibly
become sub-components of the main component.

In addition, the implementation comes with a few utility and example applications for demonstrating
its functionality that do not belong to the feature itself and might become obsolete or be
moved to another place in the project space.

Description
-----------

Feature Components
******************

* feo: The main component

Consists of the following sub-components:

- feo: Implements activities, threads, agents, and scheduling
- feo-cpp-build: C++ and Rust Code simplifying the integration of C++ components
- feo-cpp-macros: Rust proc-macros simplifying the integration of C++ components.

Rust requires proc-macros to reside in their own crate, therefore the latter two
sub-components cannot easily be combined into a single one.

* feo-com: Backends for inter-activity data communication

Will be replaced by or become a wrapper of the interface `mw::com` provided by the feature
"Communication".

* feo-log: Logging macros (Rust and C++) and logger implementation

Consists of the following sub-components:

- feo-log: Logging macros (Rust and C++)
- feo-logger: Logger implementation (Rust and C++)

Will be replaced by or become a wrapper of an interface provided by the feature "Logging".

* feo-time: Interface to system clocks

Will be replaced by or become a wrapper of an interface provided by the feature "Time".

* feo-tracing: Subscriber for Rust tracing API

Will be replaced by or become a wrapper of an interface provided by the feature "Logging".


Utility and Example Applications
********************************

* feo-tracer: A simple tracing daemon receiving trace messages from all feo agents

Consists of the following sub-components:

- feo-tracer: Tracing daemon
- perfetto-model: Support for the Perfetto trace file format

Will be replaced by an alternative solution provided by the feature "Tracing".

* logd: A simple logging daemon receiving log output from all feo agents

Will be replaced by an alternative solution provided by the feature "Logging".

* mini-adas: Example of a minimal dummy ADAS activity set

* cycle-benchmark: A simple configurable benchmarking application to measure the FEO cycle time


Rationale Behind Architecture Decomposition
*******************************************

The feature has been split into a main component, auxiliary components as well as utility and
example applications. The main component implements the functionality that is expected to
be required by most systems making use of FEO. Auxiliary components are parts of the code
that are likely to be replaced by components from other features in the future. They have been
split according to their functionality and/or well-known APIs. Utility applications are optional
pieces of software that can be run to test or demonstrate the feature functionality but are not
expected to be used directly in a productive system. They may become obsolete in future.

The main component has been split into three sub-components mainly according to usability
considerations and Rust compiler constraints. (Rust proc-macros must reside in their own crate.)


Static Architecture
-------------------

.. feat_arc_sta:: Static Architecture
:id: feat_arc_sta__feo__main
:security: YES
:safety: ASIL_B
:status: valid
:fulfils: feat_req__feo__application, feat_req__feo__activity, feat_req__feo__task_chain, feat_req__feo__agent
:includes: logic_arc_int__feo__logic_int

.. uml:: _assets/stat_arch.puml
:scale: 50
:align: center


Dynamic Architecture
--------------------

.. feat_arc_dyn:: Dynamic Architecture
:id: feat_arc_dyn__feo__main
:security: YES
:safety: ASIL_B
:fulfils: feat_req__feo__application, feat_req__feo__activity, feat_req__feo__task_chain, feat_req__feo__agent
:status: valid

.. uml:: _assets/dyn_arch.puml
:scale: 50
:align: center


Logical Interfaces
------------------

.. logic_arc_int:: Logical Interface
:id: logic_arc_int__feo__logic_int
:security: YES
:safety: ASIL_B
:status: valid
:fulfils: feat_req__feo__application, feat_req__feo__activity, feat_req__feo__task_chain, feat_req__feo__agent

See static architecture.
1 change: 1 addition & 0 deletions docs/features/frameworks/feo/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ and :need:`Feature Request Template <gd_temp__change__feature_request>`.
:hidden:

requirements/index.rst
architecture/feature_architecture

Feature flag
============
Expand Down