Mbed CLI development environment sharing thread

Hi Mbed users,

I have been using Mbed OS with Mbed CLI for some time now (we require a lot of customization, where Mbed Studio is too inflexible) and I noticed that there are no “best practices” when it comes to the development environments and external tools which go along with Mbed OS. It is understandable, since the project is heavily in development and constantly improving, and the user base is so diverse that it is not possible to dictate a “best practice”.

Still, I think the community would benefit from users sharing their development setups, which could be guides for other newcomers and even users like me who are maybe missing out on some cool development tools. Also we could discuss the issues we are having with the integration and maybe find solutions.

A nice-to-have is that the tools are open-source, but not a necessity (I know that some people are developing on proprietary IDEs such as CLion @MultipleMonomials). You could still share ways to access these proprietary tools e.g. for student organizations.

I already found a guide by @hudakz on how to develop on Qt Creator (didn’t even know if it was an alternative!). Please tell me if there are other such guides/repositories.

So let me start:

Operating system: Windows, since it is adopted by my company. I am a big fan of Linux when it comes to development systems due to its reproducable package management system and abundance of open-source tooling. Furthermore, compilation of Mbed on Linux is way faster. Since dual-booting is a hassle, I tried developing on a VM (Ubuntu on VirtualBox), however I had problems with debugging (uploading is crazy slow with pyOCD). I would be happy to hear if anybody is successfully developing and debugging on a Linux VM.

Editor: Visual Studio Code. I find the UI and the extension system amazing, compared to more classical open-source IDEs such as Eclipse. I use custom tasks, settings and launch configurations, since the ones generated from Mbed OS are buggy. There is a 3rd party script by @janjongboom which generates these, but I already developed mine since I didn’t know of it back then (this is exactly what I mentioned by the lack of best practices). Furthermore it supports remote development, which could be useful when building on a VM.

Debugger: I use the cortex-debug plugin of VS Code together with pyOCD. In addition to the VS Code’s own debugger, it shows register information and memory content. As the probe I use ST-Link, which is very slow when uploading large binaries. I tried the much-praised J-Link probe, however the J-Link GDB server does not support RTX threads, which is a bummer. Apparently pyOCD has J-Link support, but I had issues with uploading binaries.

Code analysis / verification tools: Currently I do not use any but I am planning to integrate some into my development flow. I am open to suggestions here too.

This is what comes to my mind so far, but it is a broad topic with many particular details to discuss, so I expect more aspects to be added to the discussion in the future. Looking forward to your contributions!

1 Like

I’m using also VSCode + Cortex-Debug, but with BMP. There I’m also missing thread support for debugging. I experienced also pyocd was very slow with STLink, with BMP I have flash rates of 20…38 kB/s. Has pyocd thread support?
And I’m still using mbed-cli tasks, but watching the cmake development and I’m waiting for more modular blocks. Compiling takes a lot of time, and on windows gcc is many times slower than on linux. Even in WSL compiling is much faster.

2 Likes

Thanks @boraozgen for starting this thread! What a great opportunity to learn from fellow developers!

If needed, I’m happy to share anything mentioned below.

Targets: for the moment, only the STM32F769 with STLink v3

OS: I’ve been on macOS for a few years now. Besides the OS and the hardware, the *nix kernel allows developer to install most of the software available on Linux. I use homebrew (brew.sh) to manage all that. I also maintain formulae for osx-cross avr-gcc and arm-gcc.

To make the env more reproductible locally and for CI, I’m working on a docker image which will integrate everything needed to get up and running.

Editor: previously a big vim/neovim user and lover. Worked great for my arduino based project with YouCompleteMe but I still haven’t been able to make it work with mbed… So I switched to VSCode, which I really love. I used to use the mbed-vscode-generator mentionned above with mbed-cli but now that I use mbed-cmake, I get my completion with cmake-tools which is much faster and works really well!

I script everything for the command line, I love make, bash/zsh and if things get a bit more complicated, I turn to ruby scripts. We have a script setup to generate our PinNames map from a csv files downloaded from a shared google spreadsheet.

Debugger: openOCD and gdb mainly, I need to improve my workflow and tools on that, I might try the cortex-debug.

Code analysis/verification tools: the basic is clang-format which really soothe my ocd for formatting and style guides. I have some basic Github actions set up to build the projects, run the tests, etc. Today I was working on some self-hosted runners to also flash our products and run tests IRL. I’ll setup some code coverage actions in the coming weeks.

1 Like

The good news is that the Mbed Studio IDE is steadily improving and I hope it will keep like that! But until it gets support for shared user libraries and debugging of all my targets my favorite development environmnet remains as below:

Operating system: Linux (Ubuntu 18.04 LTS at the present)

  • Compilation is much faster than on Windows and I cannot afford a Mac machine.
  • It has a powerful shell scripting and a lot of useful utility programs and tools for free!

Build system: Mbed CLI + GCC ARM toolchain.

  • Mbed CLI is Mbed’s native building tool.
  • Supports all Mbed enabled targets. I used to use the QbsProjectManager (a QtCreator plugin) but with that I was not able to keep up with the ever changing Mbed versions and new targets.

IDE: The QtCreator IDE and the STM32Cube IDE.

  • Qt Creator is an amazing IDE freely available on Linux. The editor can be switched to vim-style editing if one prefers so.
  • Allows to easily add new compilers, debuggers, make tools (supports Cmake too), kits and wizards to easily create new projects.
  • I use it to build also desktop applications (including Graphical User Interface design) and Arduino (AVR, ESP8266 and EPS32) programs.
  • But I have to admit that the IDE sometimes crashes, although, I have never lost a single file.
  • To utilize low level HAL functionalities on STM targets I use also STM’s great STM32Cube IDE when needed. Then I port the project to the QtCreator (or the online compiler) to add Mbed APIs.

Code analysis / verification tools: The QTCreator IDE can use the following Code Analyzer plugins

  • ClangStaticAnalyzer
  • Valgrind

Custom targets: Thanks to Johannes Stratmann (@JoJoS) for sharing his Custom Targets (targets and how to organize directories for custom targets) the Qt Creator allows to easily use custom targets too.

Debugger: pyOCD and OpenOCD

  • I use pyOCD (version 0.8.0) to debug targets equipped with DAPLink.
  • OpenOCD works great for debugging STM targets.

Flashing (program download) tools: I use the following utilities to flash my target boards

Programming/debugging probes:

  • USB to UART converter.
  • NUCLEO ST-LINK/V2-1 (detachable from NUCLEO boards).
  • ST-Link V2 USB dongle (aka ST-Link V2 Programming Unit).

Serial Terminal:

One can find more details about building and debugging offline on Linux with QtCreator IDE here.

4 Likes

Operating System

I use Windows, but people on my team use almost this same setup on Mac and Linux

  • Build time is manageable since I’m almost always doing incremental builds
  • All the build tools I use run fine on it

Build System

mbed-cmake + GCC Arm Toolchain

  • Provides more powerful target handling and build option support than Mbed CLI
  • Native IDE support

Testing Tools

Currently RPL has a custom simulator written for our code. However, we might upgrade to RTXOff as our simulator soon so that we can use threaded code.

IDE

CLion

  • Has a super great GUI debugger that can connect to any gdbserver
  • Provides content assist for code
  • Good CMake integration
  • Free to me as a student

Debugger

  • ST-LINK gdbserver (for STM32 boards)
  • J-Link gdbserver (for NXP boards)
  • (also PyOCD if I specifically need threaded debugging, which is rare)

Flash Tools

  • Stm32CubeProgrammer (for STM32 boards)
  • J-Link Commander (for NXP boards)
  • (RPL fork of) NXP-Flash [included with mbed-cmake]

Debug Probes

  • ST-LINK v2
  • J-Link

Serial Terminal

TeraTerm!

1 Like

Hi all –

Quick update on this topic. :slight_smile:

Debug

I’ve finally had the time to set up Cortex-Debug and I really like it. It works great with VSCode-CMake-Tools and makes it really easy to build, flash and debug an application.

IDE

Still using VSCode but I’ve moved from CMake-Tools/Intellisense to clangd. I find the latter faster and with great feature to help refactoring. It uses the compilation database and doesn’t seem to need hours to index files (not sure if it needs indexing at all).

Code Analysis

With clangd you get cland-tidy for free. We use it with modernize-* and suggestions/issues appear directly in VSCode with “fix available” most of the time.

I’ve tried using Clang’s Static Analyser but I can’t find any issues with our code, which sounds strange. @hudakz could you share how you’re using it?

Unit tests

We’ve moved to TDD using Google Tests and gMock and we are not going back. We have a 100% code coverage on new code (excluding shallow C++ wrappers around C APIs) and slowly moving the old code to meet our new standard.

CI

We also started using SonarCloud for PR/Code Coverage/Code Analysis and we really love it. It helps us spot a lot of issues we would have missed otherwise and also helps the team avoid long discussions about some possibly risky code practices. If SonarCloud generates a warning, it’s usually right and the code needs fixing.

Conclusion

Working with a team, what all those things bring is:

  • better overall code quality
  • shorten PR review time
  • more focus on what’s important
  • less bike shedding about coding style / potential bugs / etc.
  • big improvement of the team’s skills and knowledge, in particular thanks to Sonar Cloud which always gives detailed explanations regarding their issues/warning and clang-tidy with modernize
2 Likes

@ladislas how did you set up the clangd extension? I am using --compile-commands-dir and --query-driver arguments but still getting weird errors from the mstd_type_traits file. Could you please share your clangd extension settings?

Edit: I noticed that my compile_commands.json generated by CMake has broken command path. Somehow the whole command is surrounded by parantheses “( )”. This breaks clangd as it tries to parse the command. Does anybody have this issue?

Here you go:

{
	"cmake.buildDirectory": "${workspaceFolder}/_build_cmake_tools",
	"cmake.configureArgs": [
		"-DTARGET_BOARD=LEKA_V1_2_DEV",
		"-DCMAKE_CONFIG_DIR=${workspaceFolder}/_build_cmake_tools/cmake_config"
	],
"cmake.configureOnOpen": true,
	"clangd.checkUpdates": true,
	"clangd.arguments": [
		"--query-driver=/usr/local/bin/arm-none-eabi*",
		"--log=verbose",
		"--completion-style=detailed",
		"--clang-tidy",
		"--clang-tidy-checks=-*,modernize*"
	]
}

My compile_commands.json is symlinked at the root of the project.

1 Like

A quick update on CI. :slight_smile:

As previously said, we are using Github Actions to run our CI: unit tests, SonarCloud, clang-tidy, clang-format, etc.

One thing that quickly became an issue was code size: with 2/3 developers, after a few PRs it’s really hard to track the impact of the changes on code size.

I spent quite some time to setup a specific workflow for .bin/.map files analysis. The way it works is quite simple:

  • build the code on the base branch (develop in our case)
  • store the .bin & .map files as artifacts
  • build the code on the head branch from the PR
  • store the .bin & .map files as artifacts
  • generate the table representation of the .map files in .txt
  • run diff on the .bin and .txt files
  • output the difference as a comment in the PR

It works great because besides our main application, we have a lot of spikes that we keep for documentation. At some point we thought about removing them, but they help us keep track of the impact of changes.

We recently also added % of flash used for the bootloader and os, to make sure we don’t overflow the sectors.

The workflows are run in a matrix with log enabled/disabled.

You can see an example of output:

The code for the workflow is here:

1 Like