That sounds really good.
I like the Mbed build system because it is really easy to add sourcefiles or libraries. But there are problems when you add headerfiles with names that exist already. Or when you try to reduce the number of included files with .mbedignore entries. There are too many unknown dependencies and this is a tedious work. I hope these issues will be fixed by an improved build system.
Thanks @MultipleMonomials for the positive overview of these complexe topics
Itâs good to hear that investing time in mbed-cmake wonât go to waste and that weâll be able to move to the new tools easily.
Quick follow-up question (cc @Kojto : with the new cmake tools, will we still have mbed_app.json
?
Iâm not a big fan of the magic config parsing and json is really hard to edit by humans (the absence of comments is a pain in the neck).
I cannot image that mbed_app.json will be dropped, it is something different than the build system. It is the way that librarys announce their settings and to set constant values without changing the library source code.
The config options can be shown with âmbed compile --config -vâ. With this unified system, it should be possible to add editor extensions for a intellisense for mbed_app.json, that would be cool.
While waiting for the Mbed OS feature-cmake
branch to be merged into master
, weâve decided to use mbed-cmake
in our project.
Before blindly moving to a new build system, I decided to try it on a smaller project with the same structure to make sure it would suit our needs.
The process is documented in a public repository.
Iâve tried to make the instructions as clear as possible. Itâs a work in progress so things may change dramatically in the future.
Iâm happy if it can help someone and Iâm open to ideas, feedback and suggestions. PR and issues are welcome as well!
Iâm happy to announce that after getting rid of some fiddling little details, we have successfully transitioned our whole project to mbed-cmake and it works like a charm!
Our project has the same structure as the template shared before, with:
-
lib
directory to store our libs and our vendor libs (such as mbed-os) underlib/_vendor
. We followed to Mbedâs cmake-feature directory structure with aninclude
andsource
directory for each library -
src
directory for the main program (the firmware of our product) -
spike
directory to test features, solutions and investigate bugs
Everything is cmake base, it compiles great and we have near perfect autocompletion with cmake-tools in VSCode.
We also have different targets for different dev boards (internal & external) weâre using and switching is super easy.
Weâve also decided to not have mbed-os under source control yet. We want to be able to keep up with the development and the whole project adds too much clutter to our own. Iâll try to find a way to only keep what we need (in particular regarding targets).
What we donât have yet:
- unit tests
- functional tests (greentea or icetea)
- separate application and bootloader (weâll work on that next)
Iâm not yet using cmake, but it sounds interesting.
My project structure looks like this:
This uses a common mbed-os to avoid wasting to much HD space. The disadvantage is, that an update may not work for some older app, but it can be switched quickly to another mbed-os branch by using git.
I use this also together with VSCode and I start from a workspace within the app folder. The tasks are the same for all apps, so for starting a new project I can copy the app to a new directory in the apps folder. The tasks use âmbed compileâ for the build process. A task looks like this:
{
"label": "compile debug",
"group": {
"kind": "build",
"isDefault": true
},
"command": "mbed",
"args": [
"compile",
"--build",
"../../BUILD/${workspaceFolderBasename}/Debug",
"--source",
".",
"--source",
"../../mbed-os",
"--source",
"../../libs",
"--source",
"../../drivers",
"--source",
"../../custom_targets",
"--source",
"../../components",
"--profile",
"debug"
]
Problem is here only intellisense, I have to run a (modified) VScode export to create the c_cpp_properties.json for different targets.
Another caveat with VSCode is that it cannot handle nested git repos, so this structure was necessary. But it is not compatible with the mbed library handling and publishing projects is more difficult.
Now I am interested in what is different to my system.
Is switching between different releases easy as with the mbed build system? The mbed build does always a scan before compiling. But this takes a long time now already. I guess a cmake run has to be started before a make? or does cmake all in one?
In our case, we clone mbed-os with git clone --depth=1 --branch=mbed-os-6.2.1 https://github.com/ARMmbed/mbed-os
.
The --depth=1
is important as it clones only the last commit so the directory is not that heavy, only 686,3 MB The draw back is that you need to re-clone each time so you need a working internet connection.
You structure is not far from the mbed-cmake-template so it should not be that hard.
If you switch, youâll still need to run the config script to generate the *_config.h
and CMake files. Then you can just run CMake with Makefile or Ninja (we use Ninja).
As long as you donât change any .json
files or switch mbed-os version, youâre good.
If you do, youâll need to config script again. But to be honest itâs pretty fast, youâll just recompile everything from scratch.
thanks for your comments, its getting a little bit clearer now.
So, generating the config and CMake files is the step that the Mbed build system does with the python based scanning?
Is there a difference between the Mbed CMake branch and your work?
The current mbed-cli tools (as far as I understand) are not using CMake, they are parsing the configs and then calling the build commands from the python script (mbed compile
).
mbed-cmake uses the mbed-cli to generate the cmake config and then itâs cmake all the way. meaning that you can store your config with git an share them with you team, without the need for those people to use mbed-cli (as long as you donât change any .json, switch target or mbed-os version).
For an industrial project, those things are usually written in stone, so you wonât change them very often. For personal testing purposes, you might change those regularly. It will scan again, build from scratch but thatâs not as bad as it sounds.
I personally love how CMake helps you organize your project.
For quick and dirty, mbed-cli might still be a good choice.
mbed-cmake has been mainly developed by @MultipleMonomials & ProExpertProg. Iâve contributed a little.
mbed-cmake-template is a fork from the current master (6dfe783) but starting from scratch, with a personal reorganization, renaming, some scripts improvements and the removal of mbed-os sources from the git history.
Give it a try! and let me know if the documentation is good enough.
thanks again for your detailed explanation, Iâll give it a try.
Hi all! Iâm happy to announce that mbed-cmake has just been updated to version 1.4.0. This version includes a major new feature: the ability to use STM32Cube upload and debug tools with mbed-cmake.
Initially, I started experimenting with this because I was annoyed with pyOCDâs sluggish step-to-next-line command when debugging on my STM32 board, and I wanted to check what other alternatives were available. When I finally got STM32Cube set up, I was blown away: debugging commands run almost instantly! And not only that, but uploading code is at least 5-10 times faster than pyOCDâs upload command! That may not seem like much since it still completes in a few seconds, but if youâre uploading a 128k program tens of times a day, it adds up. And while this is similar to the speed you can get with OpenOCD, OpenOCD requires a lot of configuration to get running for a target while STM32Cube works out of the box.
There is one downside however: to get this to work, you need to install the entire STM32Cube IDE, which takes over 2GB of space. While this software is available freely, ST simply doesnât distribute their GDB server in any way outside the IDE. And while you can copy the executable out of the IDE, itâs against their EULA to distribute it on its own, so I canât make you a mini zip file with just the GDB server.
All in all though, this update should be a major productivity boost if you work with STM32 boards. And you can see the docs on configuring the new upload method by scrolling to the bottom of the wiki page (which I also made some updates to).
NOTE: This update fixes the case of certain mbed-cmake file names. On Windows and Mac, if you are copying the new release into your repo (as opposed to using a submodule), you will need to run git config --global core.ignorecase false
before committing the changed files to ensure these case changes get picked up.
NOTE 2: Make sure to also update your UploadMethodConfig.cmake in your project to enable the new upload method. The new configs to add can be found in the example project.
as an alternative for debugging I can recommend Black Magic Probe: Home · blackmagic-debug/blackmagic Wiki · GitHub
There you can connect gdb to the probe via a virtual com port. BMP detects the target itself and does not need further configuration. In my launch.json for VSCode, I need to specify only the port for the probe.
And currently I have merged BMP and Mbed. BMP uses libopencm3 and has no ethernet support, I have made the BMP to work over ethernet. So in gdb, a âtarget ext ip:portâ will directly connect to the probe. Its still experimental, but flashing works with 37 kB/s pretty fast and a single step takes about 30 ms. My hardware is a cheap STM32F407VG board + LAN8720 phy, but with Mbed it can run also on other boards with Ethernet.
The USB version on a F103 does flashing with 22 kB/s on the same target.
Flashing seems to be working flawlesly (Win10), but I canât get debug to work.
I always get
C:/MBED_CMAKE/Target/build/mbed-cmake.gdbinit:3: Error in sourced command file:
[build] localhost:61234: No connection could be made because the target machine actively refused it.
And the offending line in gdbinit:3 is
target remote localhost:61234
And that doesnât change no matter which port I use. When the default port didnât work, I used 61234 which is used by STM32CubeIDE by default.
Did you run ninja start-gdbserver
in another terminal first?
I didnt know i needed to do that, since the first line of response from âninja debug-Projectâ is âstarting GDB to debug ProjectâŠâ
But it is still not working. I want to explore this deeper.
as a first few lines after is start debug with a gdb server started i get
[build] This GDB was configured as "--host=i686-w64-mingw32 --target=arm-none-eabi".
[build] Type "show configuration" for configuration details.
[build] For bug reporting instructions, please see:
[build] <http://www.gnu.org/software/gdb/bugs/>.
[build] Find the GDB manual and other documentation resources online at:
[build] <http://www.gnu.org/software/gdb/documentation/>.
[build]
[build] For help, type "help".
[build] Type "apropos word" to search for commands related to "word"...
[build] Reading symbols from D:/Google Drive/VENDING/Project/build/HrVendExec.elf...
[build] Reset_Handler ()
[build] at ../mbed-cmake/mbed-src/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L433xC/device/TOOLCHAIN_GCC_ARM/startup_stm32l433xx.S:63
[build] 63 ldr sp, =_estack /* Atollic update: set stack pointer */
[build] (gdb) Exception condition detected on fd 0
[build] error detected on stdin
[build] A debugging session is active.
[build]
[build] Inferior 1 [Remote target] will be killed.
[build]
[build] Quit anyway? (y or n) Exception condition detected on fd 0
[build] error detected on stdin
[build] A debugging session is active.
[build]
[build] Inferior 1 [Remote target] will be killed.
[build]
[build] Exception condition detected on fd 0
[build] error detected on stdin
[build] A debugging session is active.
[build]
[build] Inferior 1 [Remote target] will be killed.
...
And the last message repeats.
Currently, opening the STM32CubeIde and manually pointing the debbuger to .elf file in build directory works just fine, so I am using that.
Hmm, someone else reported this too, but I canât reproduce on STM32F429ZI. Pretty sure itâs related to config options on the GDB server.
We need to try and figure out what command line arguments the IDE is running ST-LINK_gdbserver.exe with. I think that the easiest way to do this is to first start GDB from the IDE. Then run Process Explorer, find ST-LINK_gdbserver.exe in the list, right click it and selecting Properties, then go to Image > Command line. Can you send me the command line it shows?
Update: turns out I was totally barking up the wrong tree on this! One of the developers at RPL worked with me to diagnose the issue. Turns out that the issue is that Ninja doesnât run GDB from an interactive terminal, so it freaks out and gives Exception condition detected on fd 0
. I feel like âHey! Please run me from an interactive terminal!â would be a better message, butâŠ
Thankfully there is an easy fix for this by adding the CMake option USES_TERMINAL
to add_custom_target().
I went ahead and released version 1.4.1 with this fix, plus another fix for ST-LINK_gdbserver failing to execute on Linux and Mac systems with a shared library error.
mbed-cmake 1.5.0 has been released!
Changes:
- Refactor upload method system to make it cleaner and enable you to add upload methods without modifying mbed-cmake
- Fix CMake dependency errors in unit test configuration (how did it ever work before??)
- Includes mbed-os 6.5.0 (patched to support unignore rules and to fix a broken mbedignore file (
events/tests/.mbedignore
) that caused build errors) - Rewrote default âignore all extrasâ mbedignore file for mbed-os 6.5+ file structure.
Note:
Several upload method variables in this version were renamed for better consistency. These changes have been updated on the wiki page. The renames are:
- JLINK_JTAG_SPEED â JLINK_CLOCK_SPEED
- PYOCD_JTAG_SPEED â PYOCD_CLOCK_SPEED
Also, a new STM32CUBE_PROBE_SN
variable was added to STM32CUBE to provide better control over which ST-Link is used.
Note 2:
With the pace of official cmake development, this is likely to be the last major release of mbed-cmake. Currently, official CMake is not yet usable for everyone as itâs missing support for many targets as well as upload method support. However, Iâm working hard to submit the best features of mbed-cmake as pull requests, and I hope we can get it feature complete within the next few months!
Also, one other announcement: Iâm introducing two alternate builds of mbed-cmake: âretroâ and âpaleoâ.
I know that there are lots of you out there who are still using older Mbed OS versions - maybe your target was removed in Mbed 6, or maybe you havenât updated your code for breaking changes, or maybe youâre just scared to try out this RTOS business (thatâs how RPL was until somewhat recently!). Since these versions will never get official CMake support, mbed-cmake is your only way to build them with CMake. However, until now doing that has required copying around a bunch of source files, and even manually patching the Mbed source code in some cases. With these new alternate builds, this becomes a lot easier:
- mbed-cmake Retro contains the mbed-cmake system together with Mbed OS 5.15.6, for people who need Mbed OS 5.x
- mbed-cmake Paleo contains the mbed-cmake system together with Mbed 2 r163 for people still using Mbed 2 (I know youâre out there!)
To use these alternate builds, just check out the retro
and paleo
branches of the mbed-cmake
and mbed-cmake-example-project
repositories instead of the master branch. I have tested that they compile and run on a few of my boards but I also donât have the time to test them exhaustively, so let me know if theyâre behaving weirdly.
Note: Unit testing is not supported on the retro or paleo configurations.
Note 2: You would not believe how hard it is to find the actual source code for mbed 2! The âmost recentâ release that mbed-cli downloads is broken and missing most of the source code, and all of the github tags are wrong so I canât find the old releases on the GitHub repo. I was finally able to find the source code only via a mirror repository.
Just pushed a neat update! Have you ever been annoyed by always having to update the MBED_PATH
variable when you plug a new board into your machine? It turns out that all this time, Mbed OS has had an automatic code uploader built in to the mbed-tools
python package! It is capable of automatically traversing the list of USB devices to find any and all Mbed dev boards connected to your machine.
Iâve adapted this into a rewrite of the MBED
upload method. So, it will automatically search your machine for mbed boards that match your project target and then upload code straight to them â no configuration needed. It will ignore other boards that are a different model, and if you do have multiple of the same board connected, itâs smart enough to handle this case as well (mbed-cli will just blindly flash all of them):
Before I can release it to master, I need a couple people to beta-test this functionality for me. If youâre interested in trying it out, just check out the mbed-pathless
branch of the mbed-cmake repository, and report back here whether it works for you. Thanks for your help!