How to migrate Mbed projects created in Mbed-Studio to Mbed-CE/CMake?

Hi,

For apparent reasons, I am planning to migrate our mbed based projects to Mbed-CE. All of them were created with Mbed-Studio. As far as source code themselves are concerned, I believe the API differences are minor if any at all. So the barrier to me is mostly the build system.

I spent sometime reading through CMake documentation, was able to pass through the initial errors in configuration generation, but unfortunately was not able to build any of our projects with either mbed-tools (CLI 2) and Mbed-OS or CMake and Mbed-CE. Some of the errors originate from 3rd party libraries such as ESP32 driver, they were not written in a way that is compatible with CMake. Some of the errors are caused by loose reference. For example, the following file would build totally fine in Mbed Studio:

#include "mbed.h"
NetworkInterface * ifacePtr;

But with mbed-tools/CMake the following error will happen:

error: 'NetworkInterface' does not name a type

Another similar but easier to replicate error is to build the QSPIFBlockDevice example code with Mbed-CE, we will get the following error:

D:/Temp/mbed-ce-hello-world/main.cpp:13:10: fatal error: QSPIFBlockDevice.h: No such file or directory

Because CMake doesn’t know where to find the following reference:

#include "QSPIFBlockDevice.h"

Those are my observations so far, because there are so many errors, the migration seems quite daunting.

So my appeal is, can somebody with enough knowledge of both CMake, and Mbed write up tutorial/guideline on how to migrate? This will greatly help the diminishing but still sizeable (at least I hope) community.

Best regards,
ZL

You need to use Cmake target_link_libraries,
please check:

This will also add also the necessary include path.

Hi Johannes,

Thanks for the pointer. By adding mbed-storage-qspif into CMakeLists.txt file, I was able to compile the example code for QSPIFBlockDevice:

target_link_libraries(${CMAKE_PROJECT_NAME}  mbed-os mbed-storage-qspif)

So this is quite encouraging.

In the page you linked, it is mentioned that some libraries (including storage) are split from main mbed os. I also noticed that the build time by CMake is a lot shorter than Mbed Studio even on Windows. I assume quite a few libraries are not being built by CMake. Do you happen to know the full list of those libraries?

Best,
ZL

The linked page should be a reference for the existing modules and will be extended.

Yes, at first sight it looks less convenient, but I see it as great step to better modularity and Jamie has done a great job.
I have used Mbed5/6 also for tiny targets, and there it was annoying to need to compile so many files. And slowly on Windows compared to Linux or even WSL. Everything was woven to a big ball of wool due to the dependencies. In Mbed-CE, it is much more modular.
CMake requires to name what you need, and this is much better for larger projects. It is hard only in the first step, and I agree that it needs some good help as it is also hard to keep all the module name in mind.

Hi Johannes,

I agree 100% that the build time and also size of built-images have always been a pain in the rear. I remember that I had to wait for 10+ minutes when mechanical hard drive was still a thing, then we had to freeze Mbed-OS-5 at 5.14 so images built with the bare-metal profile can fit into STM32F042K.

But from a managerial perspective, it is always a lot cheaper to issue a faster laptop than to pay for all the developer-hours. Of course at some point this strategy becomes untenable. The good thing is we still have at least one year to make the transition.

Thanks for all the hard work you folks at Mbed-CE have done. I briefly looked into Zephyr which seems quite popular, and a few other alternatives. The conclusion is that Mbed-CE is the path of least resistance to migrate all existing projects.

Best,
ZL

1 Like

So I hope you can stick with Mbed :slight_smile:

Another big advantage of Mbed-CE is that it build archive files (.lib), but still regarding changes in source files when they affect a library.
I like to do simple test code and this is well supported by this design, you can simply create multiple projects and use the compiled OS or library stuff. I can recommend a project(s) structure like this:

I start with a simple app_hello with basic blinky and message over UART. Then I’m adding other code in different app_xxx directories.
The CMakeLists.txt is not difficult, for the main:

### add executable (necessary everytime)
#add_executable(${CMAKE_PROJECT_NAME} main.cpp)
add_subdirectory(app_hello EXCLUDE_FROM_ALL)
add_subdirectory(app_test_display EXCLUDE_FROM_ALL)
add_subdirectory(app_test_sdio EXCLUDE_FROM_ALL)

it is like in the mbed-ce-helloworld example, except that you add the app_ subdirectories instead of main.cpp and other sources.

In the app_ directories, the CMakeLists.txt look like e.g. for app_test_sdio with some more sources:

add_executable(test_sdio 
    main.cpp
    sdram.cpp
    storage.cpp
)

target_link_libraries(test_sdio 
    mbed-os
    mbed-storage-sdio
    mbed-storage
)

mbed_set_post_build(test_sdio) 

In VSCode, I use the CMakeTools Extension. There you can switch easily between the apps:

For building, there is a icon in the status/command bar.

Hope it helps,
LG
Johannes

I will caution on this feature. This is great when it works, but at times it can cause problems that are very hard to track down. I recently had to deal with an issue caused by shared mbed-os library folder and the failure of git to pull-in all the changes. As a result, one of our project ended up misbehaving mysteriously while on paper it should not and all other projects built with the same shared mbed-os folder work just fine. Eventually the problem was tracked down to git itself. While on the surface git has pulled in all the changes brought by mbed-os-6.17.0, but in reality changes in two files were not reflected in that local folder. We were able to solve it by hard reset git. But it took us a long time to get to that point, because shared mbed-os folder work totally fine for other projects that don’t need those two files.

My point is, with CMake and increased modularity, the build speed of mbed-ce is already fast enough, even on Windows. If we switch to Ubuntu/MacOS, the build time is probably going to be negligible. I will be totally OK to have a mbed-os folder in every project. The potential risk of introducing weird unpredictable problems outweighs the time/space saved by such feature. My 2 cents, hope this helps.

Just getting to this thread now!

Some of the errors originate from 3rd party libraries such as ESP32 driver

Actually Chris Snow has been working on a port of the ESP32 driver. The only reason it hasn’t been merged is that it hasn’t been tested yet, so if you could try it out, then we could merge it!

error: ‘NetworkInterface’ does not name a type

For this one you need to link mbed-netsocket. That will pull in the network drivers and the selected network stack.

And that’s really awesome to hear that you will be moving your projects to Mbed CE! I’m extremely honored that we can keep working together! Please let me know if you have any issues porting things over, I want to make the transition as easy as possible.

I have to use use also Windows as main OS for company stuff, but WSL is really great now. VSCode connects to WSL and so you don’t see a difference when you work in the IDE. Except that compiling is for some factors faster, the hello project with about 300 source files compiles in seconds on my laptop.
WSL is also fine now for using USB attached devices, so no problem to use STLink or other debug probes. The VCOM port is also attached to WSL, but you can run now also desktop programms like gtkerm or putty in a window, it is really seamless integrated.

Hi Mr. Smith,

Thanks for the pointer. I will give the revised ESP32 driver a try later and post back.

I briefly went through mbed-ce folk, the only thing that we use from official mbed-os that are not included in mbed-ce is cellular driver for QUECTEL. Those should be easy port.

The main obstacle is really CMake. I think with the write up on wiki and also additional information information in this thread, the migration process should be a lot faster than I thought. I am just glad that mbed-ce is available as an option. The other alternatives such as Zephyr seems a lot more daunting.

Best,
ZL

I agree that WSL has become really good. We mostly use it for server side development. We are able to ditch XAMMP all together and avoid related issues such as MySQL/MariaDB unexpectedly shutting down causing failure to restart. But WSL has its own caveats, one is that Windows upgrade can wipe WSL clean if storage is not moved out from default location. I will give mbed-ce/wsl a try at some point. For now I will stick with Ubuntu because we can work with both Mbed Studio and VSCode/CMake.

When you are at it, could you also ask Chris Snow that if he can port his NTPClient library to Mbed-CE? I don’t think I know it enough to tinker with it.

Hello,

I do not like CMake menu in VS Code so I use the bottom panel with modification.
image

About the compilation time. Just buy M.2 NVMe SSD and you do not need WSL. I am able to do complet build process under 45sec.

BR, Jan

Try and let me know - mbed-ce-libraries-examples/mbed-NTP

BR, Jan

Regarding the Quectel cellular modules, we do have a port of those, but only the EC2x and EG915 have been ported to Mbed CE yet. Which Quectel have you been using specifically?

We use EC2X as well. How do you handle the command to get ICCID? EC2X uses a command that is different from the driver shipped with Mbed-OS:
image

In mbed-os v5, we used a convoluted way to override that function, but I feel it might be easier just to override that whole file with CMake.

Build time is usually not a problem, because we usually only need to build the entire mbed-os folder once at the beginning and almost never need to do it again. It quickly becomes a problem once we need to tinker with mbed_app.json file, or customized_targets.json, which unfortunately we have to go through when trying new versions of mbed-os, or new target, or new library such as mcuboot. My laptop with I7-13700HX/32GB-RAM/M.2-SSD by no means is a slow machine, but still for whatever reason, the build time on Windows can go well over 3 minutes. It is very annoying to have the fans to go into rocket mode for minutes on end and over and over again. In such occasion, I would rather boot into a Ubuntu even on a laptop that is several years older.

One question about the linked wiki page: should the variable MyMbedOsExe used in libraries of our own project be the same as the project name in top level CMakeLists.txt?

### add executable (necessary everytime)
add_executable(${CMAKE_PROJECT_NAME} main.cpp)

From what I can see, our own libraries should be no different from other 3rd party libraries such as NTPClient, and we can write up CMakeLists.txt file the same way as well. Am I wrong?