Open-CMSIS-Pack / Open-CMSIS-Pack-Spec

Common Microcontroller Software Interface Standard - Pack(age) based distribution system
https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/
Apache License 2.0
54 stars 22 forks source link

Handling of Multiple Component Instances #76

Closed ReinhardKeil closed 9 months ago

ReinhardKeil commented 2 years ago

The current approach to multi-component instances is documented here: https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/pdsc_components_pg.html#Component_Instances

In the projmgr input files, it is currently not possible to specify component instances, however it would be fairly simple to add a instance count, for example with #, example - component: ARM::CMSIS:CORE#2 or alternatively with a key value "instances: 2".

However I have a fundamental question: is the current approach for instances sufficient. Should we reconsider the current method?

fred-r commented 2 years ago

We would like to build on the current concept:

maxInstances | Maximum allowed instances of a component in a project. Default is 1 for one instance. The range is [1..10]. | xs:integer | optional -- | -- | -- | --

That allows to indicate that a component can be instantiated. In the pdsc, we cannot really tell more, instantiating is more a configuration step.

Today, instantiation is materialized by the duplication of configuration files (appending a suffix).

Tomorrow, we would like to extend this approach (evolution, not revolution):

ReinhardKeil commented 2 years ago

@fred-r thanks for all your feedback. Now it is consolidated. Take a look to the proposed evolution of instances here.

fred-r commented 2 years ago

Hi Reinhard,

I think I would like the instances to be even more "concrete".

Regarding the identifier, I would like it to reflect that an instance can be the instantiation of a sub-class of a component seen as a mother class. To me, it is really a child element.

It may be used to already indicate the “sub-class” of the instance when the component is a “super-class” Proposal: MotherComponentID%%%[function_id]%%[api_level]%logical_id

This may open the door to further use of the instances (not only descriptive):

ReinhardKeil commented 2 years ago

@fred-r thanks for the feedback, but I struggle to understand it. Maybe an example would help.

Here is my attempt to create an example. Take the UART implementation on STM32U5 where we have:

  USART1
  USART2
  USART3
  UART4
  UART5
  LPUART1

In my example, the USART2 should be use for "Debug", the LPUART1 for "Modem" connection.

The available components are defined in the *.PDSC file. It could look like:

Driver  (Cclass)
  UART (Cgroup)    - unified UART driver API  - just header file definition for software interfacing
     USART         (defined with instance range 1..3 in *.PDSC)
     UART          (defined with instance range 4..5 in *.PDSC)
     LPUART        (defined with instance range 1..1 in *.PDSC)

All this is defined in *.PDSC files.

The cproject.yml level could look like:

components:
  - component: Driver:UART:USART
    instances:
    - Debug: 2            # USART2 is exposed i.e. via DriverUART_Debug
  - component: Driver:UART:LPUART
    instances:
    - Modem: 1            # LPUART1 is exposed i.e. via DriverUART_Modem

Both components would effectively create a Driver:UART API that can be accessed by middleware i.e. via a DriverUART handle or access struct. What exactly is exposed would depend on the "config" files that are part of the *.PDSC description.

The IDE view of such a project could be something like this:

Driver
  LPUART1 (UART Modem)
  USART2 (UART Debug)

Based on this example there is one gap in the *.PDSC: The attribute MaxInstances is not sufficient as it would be required to describe a range. A possible alternative is to provide an attribute Instances with a string that describes the available instances. Could look like this:

<component Cclass="Driver" Cgroup="UART" Csub="USART" Instances="1,2,3">
   <file category="source" name="DriverUART-USART.c" attr="config" />
</component>
<component Cclass="Driver" Cgroup="UART" Csub="LPUART" Instances="1">
   <file category="source" name="DriverUART-LPUART.c" attr="config" />
</component>

In the actual project, these config files would get expanded to:

DriverUART-USART2.c
DriverUART-LPUART1.c

Again, the content of these files is under user control and ultimately the could define the handle or access struct for each of the instances.

fred-r commented 2 years ago

@ReinhardKeil : basically there are 2 things I'd like to achieve

  1. Represent the flexibility of the Hardware being driven by the driver To me there are 2 level of flexibility:

    • the API level : there can be several level of abstractions for the drivers
    • the functionality : a same hardware peripheral can provide several functionalities
  2. Avoid in my pdsc to have a description which is "static" because the hardware capabilities can differ between two devices, even in the same family

We are still discussing these aspects, I'll come back to you with details as soon as possible.

fred-r commented 2 years ago

I thought again about this topic. Probably I'm going too far with the API level and functionality. These concepts do not need to be reflected at composition stage (at least in a first approach).

So, in order to progress faster, I think we can stick to something close to what you proposed, but with the "lockfile" format discussed with @slhultgren.

Nevertheless, there is one point where I'd disagree with your proposal for the pdsc description: I think we should not try to stick to the exact number of instances. For the component to be "as generic as possible", what matters is to know if it is instantiable or not. I am fine with the range as long as we can say 0 (can be omitted: not instantiable) and "1..x" (instantiable).

Then, to me, it is at composition stage that we should care for the exact numbering. So the user flow would be:

  1. At composition stage, decide to instantiate a component ==> only the instance entry is created
  2. At configuration stage, fill this instance with maybe a failure (too many instances for example.)

If the instantiable component is not associated to a generator:

If the instantiable component is associated to a generator:

Then, the project manager (csolution) can parse the gpdsc to update the project file description if needed.

ReinhardKeil commented 12 months ago

@fred-r is this still relevant? If not could you please close this issue.

ReinhardKeil commented 9 months ago

We need instances to support the upcoming MDK middleware. We will therefore implemented https://github.com/Open-CMSIS-Pack/devtools/issues/1123

It is unclear if we need further enhancements, and I'm closing this as there is no further activity on it. Please create a new issue with an explanation why we should add features.