Skip to content
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

API, Components, and Interfaces - better definition required #114

Closed
ReinhardKeil opened this issue Apr 6, 2022 · 10 comments
Closed

API, Components, and Interfaces - better definition required #114

ReinhardKeil opened this issue Apr 6, 2022 · 10 comments
Labels
Discussion Done Discussion for this issue has converged

Comments

@ReinhardKeil
Copy link
Collaborator

ReinhardKeil commented Apr 6, 2022

During the discussion yesterday, I got the impression that we need a better definition of the differences between API, Components, and Interfaces as somewhat they related to each other. An Interface is actually more a SW interface (yes ultimately these connect to hardware peripherals at some point). Here is my first attempt of a definition:

API

An API is an interface template provided as header file. In a Pack an API is identified with the format [Cvendor::] Cclass : Cgroup that refers to header files. In a Pack the API itself does not have an implementation, but one or more Components can implement this functionality.

Component

A Component is a set of files that implement a functionality. The component name serves also as interface descriptor. The component has these naming conventions.

A Component may be based on an API. In this case the API element provides the header files that defines the compnent interface.

For a Component that is not based on an API, the component the sharing of the API definition is not defined by the Open-CMSIS-Pack system, but implementation defined. It is recommended that the API header file is part of the component.

Interface

An Interface identifies an implementation of a functionality that is defined by an API (header files).

An Interface is referenced by:

  • conditions element in a software pack using Cxxx attributes.
  • interface: requires: where it is assumed that the interface is used by source/header files in a layer.

An Interface is defined by:

  • A Component in Pack.
  • An API in Pack plus a selection of a component that implements this API. It should be therefore possible to refer just to an API with interface: requires:
  • interface: provided: where it is assumed that the interface is implemented by source/header files in a layer.

NOTE: it is obvious that the topic needs more work, but I would propose that we define the naming conventions for interfaces as a next step. It could be a:

  • [component name](component has these naming conventions to refer to components and APIs that are defined in Packs
  • simple name identifier to refer interfaces inside a csolution based project (works only on project scope).
@fred-r
Copy link
Contributor

fred-r commented Apr 6, 2022

Today our components do not use the concept of API, and we do not plan to move towards it because it would require to split all our components between .h and .c and it will be too many components in our opinion.
I think this API concept is good for standardized layers where a same API can have several implementations, but it is overkill for our proprietary interfaces.

So, based on this assumption, I think I need a way at component level to indicate the provided interface.
A component may have the possibility to provide several interfaces based on its configuration.
Ultimately, an instantiable component can have each instance providing a different interface or set of interfaces.

Regarding the way to define an interface, my first thinking was to maybe split it in 2 parts:

  • one mandatory part defining the functionality (should be standardized but proprietary values allowed)
  • one optional part defining the kind of API (api type, can be silicon vendor proprietary)

If I take an example based on ST drivers.
We have 2 kinds of API: HAL and LL.
An UxART hardware instance can offer synchronous and asynchronous functionalities, so the component driving it can offer both functionalities.

So, at the end we can offer "Synchronous_HAL" or "Synchronous_LL" and even "Syncrhonous_LL+Asynchronous_LL".

These are only some "early" thinking to contribute to the spec, it needs to be refined.

@mdortel-stm: I know we are still having internal discussions about it at ST so please feel free to disagree if needed :-)

@ReinhardKeil
Copy link
Collaborator Author

@fred-r I have slightly revised the text. For a component there are two options:

  • based on a API -> header file provided by the API definition
  • not based on API -> header file might be part of the component, but it is up to the implementer to decide that.

My intention was to make the relationship clearer.

For interface: requires: there are three ways to resolve it

  • specify an API: a component that implements this API must be selected to match the required interface.
  • specify a component
  • specify a name string -> a layer that defines the string with interface: provided: is required.

@fred-r
Copy link
Contributor

fred-r commented Nov 16, 2022

It is still very confusing to me... even when reading: https://github.com/Open-CMSIS-Pack/devtools/blob/main/tools/projmgr/docs/Manual/YML-Input-Format.md#interface

To me, what is called interface here is "only" a service.
And this service today is offered by a layer or a projet.
But, this service is only defined by a string ==> no property associated to it.

So, to me, the only way to "require" such a service is to "consume" the very same string.

Hence, I think it is confusing when we say that a require can be satisfied by 3 elements (very different string formats):

  • an API component
  • a component
  • an interface

I also have a problem with the "scope" of the interfaces.
They are user defined...so to me it is very likely that we will have collisions with the string names.

To me, it is very likely that we will have some situation like:

NXP board layer

interface:
provides:
- USART VCOM
- WiFi socket

ST board layer

interface:
provides:
- USART VCOM
- WiFi socket

But the APIs won't be the same though the strings are the same.

To me we are not defining interfaces here but services.

To me, an interface is an element that different entities will use to interact.
When it comes to software, it is a "contract" translated into an API.
So, here, I do not see the added value of the "interface" compared to the API.

Also, what is very confusing to me is this:
provides:
- Heap: 65536 # heap size

==> to me, this is not an interface. It does not allow two elements to interact, it is a system configuration parameter.
We can consider it as a service: "heap service" allowing you to allocate dynamic memory.

The key/value pair is also unclear to me.

  • CMSIS Driver Ethernet: 0 # driver number ==> is it an identifier or a number of items ?
  • Heap: 65536 # heap size ==> clearly here it is a size

And this sounds not realistic to me:
consumes:
- Heap: +30000 # requires additional 30000 bytes memory heap
==> for a project I may understand it because we "know" the application.
But for a layer, we have no idea how it is going to be used by the application (unless it is an applicative layer).

Typically, say that you declare FOTA support as a layer.
You will indicate that you need +30k of HEAP for TLS support.

But, maybe the application will maintain only 1 TLS link at a time, so no reason to add extra heap...
I don't see how we can use this in a scalable manner (I mean without being to application dependent).

@ReinhardKeil
Copy link
Collaborator Author

@fred-r I agree that are still many things to solve, but we have to start somewhere. To an certain extend it only makes sense when we agree on compatible APIs. We have proposed IoT_Socket, PSA, and CMSIS-Driver APIs. Once they are consistently implemented, we would need to define the interface strings that describe them (and replace the user-defined with additional information).

@fred-r
Copy link
Contributor

fred-r commented Nov 18, 2022

To be discussed with @iomint : if we stick to CMSIS-Driver APIs, I am not sure we can really leverage it as we will promote our ST APIs.
For PSA, ok this one makes sense I agree (de facto standard I would say).

@ReinhardKeil
Copy link
Collaborator Author

ReinhardKeil commented Nov 18, 2022

If CMSIS-Driver APIs are not fit for purpose, we should discuss changing it. However without alignment on APIs code reuse from different SIPs will not work.

But you could enable the system within ST and just use names like "ST UART" in the interface descriptions.

@DavidJurajdaNXP
Copy link

Hi all,

I am used to model application as dependency tree like this:

graph

From this model we can recognize only two entity types:

  • nodes (solution, project, layer, interface, configuration, component, generator, APIs - explicit or implicit)
  • edges (dependencies)

In my opinion, it is possible to define single data type (node) which would allow description of any node type currently recognized.
Node type would not be defined explicitly, but by topology and presence of specific data. Any node can require any other node or data element without restrictions.
Because we are using existing technology (cmsis pack), which already define components and APIs and we are using two file formats (xml, yml), it is kind of natural that new entities appeared. Layers and interfaces are introducing new constrains and form extensions of currently available cmsis pack data types (components, APIs).

Alternative approach would require modification of existing cmsis pack component and API data types and also migration of this data types into yml format (components can be only referenced, but cannot be defined in ymls currently).

In theory it is possible to define just single data type, but it is not doable with backward compatibility and resource limitations in mind.

I like the idea of single dependency space, where any kind of entity can require any kind of other existing data.
(Currently only some dependency types are allowed in specific entity type. It is significant for current entity differentiation.)

On the other hand explicit types might help with communication of its role in the ecosystem. Type specific entities can be implemented as syntactic sugar on top of universal node entity which would be used by core engine.

There is overlap between API, interface, and layer.

  • implicit API (component) - ID without API version with source files
  • explicit API - ID with API version and header file
  • component implementing explicit API - ID matching some explicit API ID and API version
  • interface - just ID without files, can represent anything
  • layer - ID identifying combined object formed from components and configurations (similar to project and solution)

Note about explicit API in NXP:
We are not using explicit API entities in MCUXpresso metadata, but we are considering it, since it would simplify construction of hardware independent projects and provide written template for driver authors.

Note about system libraries:
System library API should be also represented as form of dependency (condition) in my opinion.

@fred-r
Copy link
Contributor

fred-r commented Nov 23, 2022

Hi @DavidJurajdaNXP, @ReinhardKeil , @jkrech and all.

I agree with the concept presented by David: we do have "nodes" and "links" to materialize functional elements and their relations.
Now, let me try to summarize what I understood from Reinhard's explanations yesterday, and try to put it in perspective with David's view.
As usual, I will introduce wording to clarify my thoughts...the risk is over-specification, so I rely on you to keep it "pragmatic".

Objective and Context

I think the "interface" concept makes sense with the introduction of the new "nodes": layers.
These layers are preconfigured functional blocks:

  • they offer a service
  • they pre-compose a set of components
  • they pre-configure these components

Now, I think Reinhard's objective is to expose a "service" provided by these blocks, so that these blocks can be interconnected easily : this is the "link" in David's view.
The "service" serves the purpose to find which "links" can be created.

So to me:

  • the context is "compound nodes" a.k.a. "layers"
  • the objective is to offer a way to find compatible "compound nodes" and "link" them

Subdividing the interface concept

I think the concept introduced by Reinhard may be sub-divided to be easier to understand.
I would see it like this.

Basically, the "compound node" a.k.a. "layer" (or maybe a cproject also ?) can provide or consume services.
This is where I would disagree to call it an interface.
Why ?
Because to me we may describe a layer like this:

Top level: layer name (the compound node)

  • Consumes: [0..N]
    -- Service
    --- Function: the service has a function (asynchronous serial link, IP link, ...)
    --- SW API : the software API associated to this service (can be a component or an API)
    --- Hardware API : can be an arduino pin, ....
    --- Default Key Settings: how the service is preconfigured (only the key elements like a baud rate...)

  • Provides: [0..N]
    -- Service

Example

If I think about a board "layer" it may be defined like this:

ST Evaluation Board XXX

  • Consumes: [0]
  • Provides
    -- Service : serial link data
    --- Function: asynchronous serial link
    --- SW API : ST HAL UART driver
    --- Hardware API : arduino pin 8 for RX, arduino pin 9 for TX
    --- Default Key Settings:
    ---- baud rate: 115200
    ---- stop bit: 1
    ---- word length: 8 bits

And another layer like this:

IoT Middleware YYY
- Consumes: [2]
-- Service : serial link data (for trace purpose)
---- ....etc....
-- Service : IP link (for cloud connectivity purpose)
--- ...etc...

Is it what you had in mind @ReinhardKeil ?

@ReinhardKeil
Copy link
Collaborator Author

I believe this is outdated. I leave it open until we demo'ed the layers.

@ReinhardKeil ReinhardKeil added the Discussion Done Discussion for this issue has converged label Jan 17, 2023
@ReinhardKeil
Copy link
Collaborator Author

Closing as there is no further activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Discussion Done Discussion for this issue has converged
Projects
None yet
Development

No branches or pull requests

3 participants