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

Default Linker Script handling #1134

Closed
JonatanAntoni opened this issue Sep 26, 2023 · 8 comments
Closed

Default Linker Script handling #1134

JonatanAntoni opened this issue Sep 26, 2023 · 8 comments
Labels
discussion done indicates an issue's discussion is completed enhancement New feature or request

Comments

@JonatanAntoni
Copy link
Collaborator

JonatanAntoni commented Sep 26, 2023

The Problem To Be Solved

Maintenance of device family packs (DFPs) is cumbersome and doesn't scale once new compilers are to be supported. In former times, the startup components contained compiler specific assembly code (startup_<device>.s). In order to overcome this compiler dependency, we introduced C startup code (startup_<device>.c). The compiler specific's got moved into the CMSIS-Core compiler abstraction. This left us with only the linker configuration which is still compiler specific.

Hence, to add support for another compiler/toolchain requires additional linker scripts to be added to all DFPs. This still doesn't scale and leaves users alone once they want to use a device with a non-up-to-date DFP.

Proposed Solutions

We have multiple ideas under discussion.

Default Linker Scripts shipped with CMSIS-Toolbox

As a first solution, we enhanced CMSIS-Build to ship a set of default linker scripts for known compilers as part of CMSIS-Toolbox. Once a .cproject ends up with having no linker script (neither one contributed via the startup component nor a custom one added by the user) the default linker script from the toolbox installation gets used implicitly.

The drawbacks of this solution (as currently implemented) are:

  1. Relying on the default linker script makes the compilation result dependent on the toolbox installation. Individual users with different versions of the toolbox might get different default linker scripts and hence varying binary images.
  2. Default linker scripts are not under version control.
  3. Linker scripts cannot be modified, easily. The user needs to manually copy the default linker script from the toolbox installation into the project and register it as a custom one. While this is possible the required steps can be considered cumbersome.
  4. Adding further Compiler support in the future requires both,
    • A new CMSIS Base Pack with CMSIS-Core Compiler support.
    • A new CMSIS-Toolbox release with the new default linker script.

Some drawbacks could be compensated by enhancing the implementation:

  1. Consider the default linker scripts taken from etc folder like any other config file; e.g., associate a file version.
  2. Copy the default linker script into the projects RTE folder if required and use the copy.

Default Linker Scripts shipped with CMSIS base pack

Another solution could be to "bring back" some "default startup component" as part of the CMSIS base pack (alongside CMSIS-Core). Shipping these files in a CMSIS-Pack with attribute "config" makes the files becoming part of the user project, being modifiable, and version controlled. We could think about a "template component" which can be used for every device giving the users required starting points whenever the according DFPs lack required support:

<component Cclass="Device" Cgroup="Linker" Cvariant="Template"> contains the default linker scripts for known and supported compilers. It's up to the user to select this component if no other linker script is available for the selected device.

This solution seems to have the following drawbacks:

  1. The component needs to be selected explicitly; i.e., this solution doesn't kick in automatically.
  2. If it happens that multiple components (i.e., the DFP's startup and the linker template) contribute a linker script, the project becomes "invalid".

Related Features

In order to separate Linker Scripts from device memory settings, CMSIS-Toolbox supports preprocessing of Linker Scripts (C-Preprocessor). The memory settings, i.e., region start addresses and sizes, are stored in an additional regions_<device>.h config file. The very same config file can be used by the linker scripts for different compilers. This helps to assure consistent memory settings across toolchains.

Linker scripts shipped in packs/components so far are not prepared for being preprocessed by CMSIS-Toolbox. Hence, we need to enhance the pack schema to flag pre-processing for linker scripts.

Example

Given an easy Blinky example which has been created with only Arm Compiler support. Using C Startup this example shall compiler "out of the box" with a new compiler, e.g., GCC or LLVM/Clang.

The project was created using the pseudo devices specified in CMSIS-DFP which does not ship linker scripts. Just selecting a new compiler on the cbuild command line would now do the following depending on the solution discussed above:

Default Linker Scripts shipped with CMSIS-Toolbox

The project does not contain any linker script. Hence cbuild finds the default linker script for the selected compiler in its etc folder and uses it implicitly.

If the default linker script needs to be adopted to project needs, one need to find it manually in the toolbox etc folder, copy it into the project folder, and register it with the .cproject file.

Given a tool enhancement: The default linker script is copied into RTE folder but still used implicitly. Required changes to the linker script can now be done in the RTE folder. There is no need to register the linker script with the .cproject file.

Default Linker Scripts shipped with CMSIS base pack

The project needs to be adopted to select the additional Device:Linker&Template component. The default linker script gets copied into the projects RTE folder and is used from there.

If the default linker script needs to be adopted to project needs, it can be modified in the RTE folder like any other component's config files.

Pros/Cons Comparison

This table lists advantages and disadvantages in direct comparison between the two solutions.

Issue Toolbox Component
Linker Script selection Automatic (+) Manual (-)
Multiple Linker Script clash. No (+) Yes (-)
Config File appearance To be implemented (-) Yes (+)
Enhancement with CMSIS-Core Separately (-) Yes (+)
Require pack schema enhancement No (+) Yes (/)
@JonatanAntoni JonatanAntoni added the enhancement New feature or request label Sep 26, 2023
@fred-r
Copy link

fred-r commented Sep 26, 2023

If we keep on providing linker scripts with attr=config in our DFPs, how does it coexist ?
We just need NOT to select the new component ?

And if we do so, the copied linker scipt still keeps precedence over the CMSIS-Toolbox one ?

@ReinhardKeil
Copy link
Collaborator

The term CMSIS base pack was introduced in the CMSIS Embedded World meeting. CMSIS v6 will introduce this (shown in the picture below). The repo https://github.com/ARM-software/CMSIS_6 contains the WiP development of this CMSIS base pack.

image

@JonatanAntoni
Copy link
Collaborator Author

JonatanAntoni commented Sep 26, 2023

If we keep on providing linker scripts with attr=config in our DFPs, how does it coexist ? We just need NOT to select the new component ?

The problem/solution discussed here only applies when a user selects a compiler/toolchain that is not (yet) explicitly supported by the chosen DFP. Once the DFP provides the required linker script this one is to be used.

And if we do so, the copied linker script still keeps precedence over the CMSIS-Toolbox one ?

This is what I mean with "Multiple Linker Script clash". Automatic Linker script usage is only possible when there is exactly one linker script. The toolbox solution (as implemented) only falls back to the default linker script if there is no linker script at all.

In contrast to that, the component solution would end up with multiple linker scripts if the startup component has a linker script attached as well. In this case, the user would either need to deselect the Device:Linker component or user the linker node in the yaml to select which of the available linker scripts shall take precedence.

@ReinhardKeil
Copy link
Collaborator

ReinhardKeil commented Oct 24, 2023

@JonatanAntoni Proposed solution

Change of the Linker Script Management when no linker script is provided as part of the software components.

  • Instead of using the linker script from the CMSIS-Toolbox ./etc directory, the linker script is copied by the csolution tool to the RTE directory of the project, i.e. ./RTE/gcc_linker_script.ld, The csolution` tool does not copy this file if it is already present.

This should solve most of the drawbacks outlined above and avoids that DFPs provided linker scripts outdate when a new compiler/linker is released. The CMSIS-Toolbox contains a cmake file and the linker script for the various toolchains and is most likely the better place to supply it.

@JonatanAntoni
Copy link
Collaborator Author

JonatanAntoni commented Oct 24, 2023

  • Instead of using the linker script from the CMSIS-Toolbox ./etc directory, the linker script is copied by the csolution tool to the RTE directory of the project, i.e. ./RTE/gcc_linker_script.ld, The csolution` tool does not copy this file if it is already present.

Yes, this is one option to make it more visible to the users.

Today, we discussed that we still might want to decouple the linker scripts from CMSIS-Toolsbox an rather ship them in a dedicated component (e.g., in the base pack, or perhaps in the compiler pack). This way we would gain the config file versioning for free, and the solution is somewhat backward compatible (e.g., for uVision). But, using linker scripts which require preprocessing in components might need us to enhance the PDSC format to flag those "new style linker scripts".

@ReinhardKeil
Copy link
Collaborator

ReinhardKeil commented Oct 25, 2023

What are the benefits of decouple linker scripts from the CMSIS-Toolbox. In my view the CMSIS-Toolbox comes today with the *.cmake and the linker script templates of the various compilers. Would you decouple both or just the linker scripts?

As a user of uVision (or other older tools), the new linker script handling can be beneficial, but preprocessing part is somewhat missing. Yes there are workarounds with the AC6 linker, but I believe this requires manual work.

@JonatanAntoni
Copy link
Collaborator Author

Would you decouple both or just the linker scripts?

Today, we only discuss about linker scripts. The cmake is toolbox specific, so probably I'd not decouple it.

@ReinhardKeil
Copy link
Collaborator

Covered now in #1175

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion done indicates an issue's discussion is completed enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants