Tips and tricks

This chapter contains useful information to help you solve specific issues.

Archive a project

For a completed Open-CMSIS-Pack project using CMSIS-Toolbox and the CMSIS Solution project format, you should archive everything necessary to rebuild, debug, verify, and maintain the firmware independently of the original development environment.

What should be archived

Artifact Examples Recommendation
CMSIS solution configuration *.csolution.yml Mandatory
CMSIS project configuration *.cproject.yml Mandatory
Build configurations *.cbuild.yml, *.cbuild-idx.yml Archive the resolved configurations
Source code *.c, *.cpp, *.h, assembly Mandatory
Linker configuration Scatter files, linker scripts Mandatory
RTE configuration RTE/, RTE_Components.h, configured component files Mandatory
Generator configuration *.cgen.yml, generator inputs and outputs Archive when applicable
CMSIS-Pack dependencies DFPs, BSPs, software component packs Archive exact .pack versions
Pack lock information *.cbuild-pack.yml Mandatory for dependency traceability
Compiler and build tools Arm Compiler, GCC, LLVM, CMSIS-Toolbox Record exact versions; preserve installers where possible
Generated firmware *.elf, *.hex, *.bin Mandatory for released firmware
Debug information ELF with DWARF, map files Strongly recommended
Test and validation results Test reports, coverage, analysis results Mandatory for formal releases
Documentation README, requirements, release notes Strongly recommended
Version-control metadata Git commit, tag, submodule revisions Mandatory

Note

Files such as *.cbuild.yml and *.cbuild-idx.yml are generated by CMSIS-Toolbox. They are useful as records of the resolved build configuration, but they are not substitutes for the original solution and project definitions.

Preserve the complete dependency chain

A CMSIS project may depend on software components from multiple vendors. Merely preserving their names and version numbers is insufficient if the original pack repositories become unavailable.

For long-term reproducibility, preserve:

  • The exact CMSIS-Pack archives (.pack) used in the build, including transitive dependencies.
  • The compiler version and relevant toolchain binaries or installers.
  • The CMSIS-Toolbox version, including cbuild, csolution, and associated utilities.
  • Any external code generators, their configurations, and required runtime dependencies.
  • Custom scripts, environment settings, and CI/CD configuration.

For commercial compilers, licensing and redistribution restrictions may prevent archiving a fully portable toolchain. At minimum, preserve the version, build identification, installation source, and license requirements.

It is good practice to separate the editable project, its dependencies, and the release evidence:

📁 MyFirmware-1.0.0/
╠ 📁 project/ — Source code, solution files, layers, RTE configuration
╠ 📁 packs/ — Exact .pack dependencies
╠ 📁 toolchain/ — Tool versions, manifests, installers where permitted
╠ 📁 firmware/ — ELF, HEX, BIN and map files
╠ 📁 verification/ — Test reports, analysis results, build logs
╠ 📁 documentation/ — Release notes, build instructions, SBOM
╚ 📄 manifest.yml — Versions, hashes, Git revision, build environment

Include a SHA-256 checksum for each released binary and ideally for all archived dependencies.

Verify that the archive is reproducible

Before declaring the archive complete, rebuild the firmware in a clean environment.

CMSIS-Toolbox supports the --frozen-packs option, which checks the pack dependencies against *.cbuild-pack.yml and prevents unintended changes to the resolved pack set.

cbuild MyFirmware.csolution.yml \
  --frozen-packs \
  --rebuild

This command assumes that all required packs and toolchains are already installed. It does not itself guarantee bit-for-bit identical binaries. For that, compare the resulting firmware with the archived release and investigate differences caused by timestamps, build paths, compiler settings, or other nondeterministic inputs.

Note

It is recommended to commit the solution inputs, all RTE files, and *.cbuild-pack.yml to version control.

Create vcpkg configuration file

If your solution does not contain a vcpkg-configuration.json file, click on Arm Tools: 0 in the status bar and then on Add Arm Tools Configuration

The Arm Tools Environment Manager extension creates this file and opens the GUI view. Select the tools you want to use in your project (at least a compiler toolchain, cmake, and Ninja). Use the latest versions available if you do not have specific version requirements.

Switch to the JSON file view and press Ctrl/Cmd+s to save the file.

Set current solution in workspace

To activate a solution in the Solution outline view, use the Select Active Solution from workspace option in Views and More Actions:
Views and More Actions icon.

Documentation does not open

If you are using a Linux machine that uses the Snap package manager, your web browser will not be able to open documentation that is shipped in CMSIS-Packs as the CMSIS_PACK_ROOT directory is in ${HOME}/.cache/arm/packs which is not accessible to Snaps. Likewise, the Keil Studio help is located in ${HOME}/.vscode/extensions which is also not available.

To get this working, use a browser that is not installed as a Snap package:

  • Uninstall the Snap package. For example, run sudo snap remove firefox in a Terminal.

  • Download the installer from the browser's web site.

  • Install it on your machine.

Create a library file

With Keil Studio, it is possible to create a library file. All you need to do is to change the output type in the *.cproject.yml file to lib:

# Control output files (elf is generated by default)
  output:
    type:
      - lib

In the CMSIS view CMSIS view, click Build icon. The Terminal output will look like this:

Execute: cbuild /Users/user/project/Arm/ArmCM3/Library/Library.csolution.yml --build --context-set --packs
+----------------------------------------------
(1/1) Cleaning context: "Library.Debug+Library"
+----------------------------------------------
(1/1) Building context: "Library.Debug+Library"
Using AC6 V6.24.0 compiler, from: '/Users/user/.vcpkg/artifacts/2139c4c6/compilers.arm.armclang/6.24.0/bin/'
Building CMake target 'Library.Debug+Library'
[1/2] Building C object CMakeFiles/Group_Source_Files.dir/Users/user/project/Arm/ArmCM3/Library/main.o
[2/2] Linking C static library /Users/user/project/Arm/ArmCM3/Library/out/Library/Library/Debug/Library.lib
+------------------------------------------------------------
Build summary: 1 succeeded, 0 failed - Time Elapsed: 00:00:02
+============================================================
Completed: cbuild succeed with exit code 0

The corresponding library file will be present in the /out-directory.

Note

This only works with CMSIS-Toolbox starting v2.11.0.

Downgrading tool versions

When you downgrade a tool version in the vcpkg-configuration,json file, this will only be taken into account if you toggle the tools activation.

Do the following:

  • Click on the Arm Tools entry in the status bar.
  • In the Manage Arm Tools dialog, select Deactivate Environment. The status bar will show that tools are deactivated: Arm Tools deactivated
  • Again, click on the Arm Tools entry in the status bar.
  • In the Manage Arm Tools dialog, select Reactivate Environment.

The new settings will now the taken into account and you can start working with the downgraded tool version.

STM32CubeMX generator issues

If you are relying on the LL drivers, it may happen that STM32CubeMX does not generate/update a *.cgen.yml file. To get this fixed, go to:

  1. Project Manager
  2. Advanced Settings
  3. Select HAL (default) for at least one peripheral.

If you rely on LL for your peripherals, select/add an unused peripheral:

Make STM32CubeMX generate the cgen.yml file

Now, the GENERATE CODE button creates/writes the *.cgen.yml file.

Debugging

Use an external flash loader

To program additional memory, such as off-chip flash, specify the memory region and its programming algorithm in the memory: node of the applicable target type in the *.csolution.yml file:

solution:
  target-types:
    - type: MyHardware
      device: STMicroelectronics::STM32F746NGHx
      memory:
        - name: Ext-Flash
          access: rx
          start: 0x40000000
          size: 0x200000
          algorithm: Flash/Ext-Flash.flm
          ram-start: 0x20000000
          ram-size: 0x20000

CMSIS-Toolbox uses this information to generate the programming: node in the *.cbuild-run.yml file. The flash loader is therefore available to debug adapters that support CMSIS Run and Debug Management, and is not specific to pyOCD.

Memory and Peripheral Inspector are missing

If your Debug view does not contain "PERIPHERALS" and you cannot open the Memory Inspector, check if the extensions are installed correctly. If you had previously uninstalled the Arm Debugger extension, these two extensions might have been removed with it. Just reinstall them via the Extensions view.

Change variable display radix

In the Watch and Live Watch views, you can change the radix of variables by using the set output-radix base command in the Debug Console. For example,

> set output-radix 16

changes the radix to hexadecimal. Supported choices for base are decimal 8, 10, or 16.

Note

  • The > is part of the entered command instructing the console processing to use GDB CLI.
  • Refer to Numbers for more information.

FVP plug-ins are not found when starting a debug session

Symptom

After the Arm Tools Environment Manager activates the FVP tools, Load & Debug application fails because VS Code cannot resolve ${env:AVH_FVP_PLUGINS}, even though the AVH_FVP_PLUGINS environment variable is set.

Solution

Open the Command Palette (Ctrl/Cmd + Shift + p) and run Developer: Reload Window before starting the debug session. Reloading the window refreshes the environment variables used by VS Code.

Cannot connect UART when debugging

Symptom

Using older DAPLink or LPC-Link2 implementations, it is not possible to have a debug connection and monitor the output of the UART on the SERIAL MONITOR at the same time. Once the serial connection is opened, the debug connect stalls and throws these two errors:

Cannot execute this command while the target is running.
Use the "interrupt" command to stop the target and then try again.

And

Unable to read memory.

Solution

Using an NXP board with the new MCU-Link FW, this problem does not occur.

For older boards, there is no new DAPLink firmware available. Please avoid using the UART when debugging or use an external debug adapter.

Stack unwinding fails or hangs

AC6 (Arm Compiler for Embedded) or CLANG may not emit the required ELF/DWARF unwind information for functions with the noreturn attribute. As a result, GDB may show an incorrect call stack or the stack unwinder may take a long time or hang.

The compiler option -funwind-tables preserves the link register on the stack, which slightly increases stack usage but enables reliable stack unwinding. Add the option only for C files in the debug build-type in the *.csolution.yml file.

AC6

solution:

  build-types:
    - type: Debug
      debug: on
      misc:
        - for-compiler: AC6
          C:
            - -funwind-tables

CLANG

solution:

  build-types:
    - type: Debug
      debug: on
      misc:
        - for-compiler: CLANG
          C:
            - -funwind-tables