I need help to understand the way Mbed OS makes things "simpler"

Please forgive me if I am talking about has already been discussed or it is a wrong topic.

How I got here:

I am an embedded engineer, who has mostly used STM32 MCU-s, and for programming they used STM32CubeMX generated templates. From the tools, I have tried many things - from Keil to Eclipse-based solutions like STMWorkbench and Atollic True Studio.

Most of the programming I do is for the custom cost-optimized boards that we manufacture in hundreds to thousands.

I have a new project that uses the STM32L422 MCU (the cheapest one that meets the requirement) and ublox SARA G450 GSM/GPRS modem.

I thought about going my usual route - use the FreeRTOS and write most of my libraries. You can imagine my excitement when I found Mbed OS that has official ublox libraries, and so many features- HTTP support, device management, OTA updates and so much more!

For the last week, I have been trying to configure Mbed for my use, unsuccessfully so far.

It seems like the Mbed isn’t targeted for serious people who actually want to use their own hardware? Because everything is targeted for “officially supported boards” - the boards that no one will ever use in production.

For example, my board will cost me about 30 EUR in production, but a similar functionality board like u-Blox C030-U201 costs about 150 EUR. And that is okay, devkits are usually expensive.

But then why is PORTING MADE SO COMPLICATED for any other “unsupported target”? It even seems like most of the porting documentation is targeted for people wanting to make their board public - which is almost never the case with proprietary designs. I am not interested in making an official bord and I don’t need to run all of your tests, I just need to use the OS as-is.

Why is everything so focused on USB copy/paste programming when that doesn’t work in series production? Why are IDE/development tools so archaic? Where is line-by-line debugging?

You have to dig to find anything, and you have to dig even harder to find anything on working with custom designs - and even then on forums its a link to the official porting page that both have too little and too much information.

Am I missing something? there are apparently 40 big companies using this in their devices, in production, making smart lamps and such - but all resources available are from people using NUCLEO boards?

Hi @aoreskovic! –

I went through the same process as you and struggled a lot with our custom design.

We saved our selves a lot of time and issues by using an “officially supported board” as a template to create our own. In the process we gained a deeper understanding on how and why mbed works the way it does.

We are a very small team ( 2 devs with basic electronic skills) and we decided to use mbed for the same reason as you: it provides a lot of things!

Our design process mainly consisted in finding the right MCU, modules, flash, etc., that would meet our requirements and still be compatible with mbed. We spent countless hours diving in hundred pages long specs to make sure things would click and work. We changed modules at the last minute because of one line we missed somewhere.

In the end, our custom board works great, we don’t have (or very little) to work on the low level drivers, we can spend our time on the application and on the few modules (Bluetooth BM64 to be precise) for which we need to write our own drivers.

Our board has:

  • STM32F769
  • MIPI-DSI LCD Screen
  • QSPI Flash
  • BLE
  • Wifi
  • Bluetooth
  • Audio
  • Motors + driver
  • Sensors (a lot!)
  • LEDs
  • etc.

Regarding tools, we really don’t like IDE that hide all the magic behind, where configuration is made by checking boxes in a GUI and that don’t work well with SCM such as Git.

So we do everything from the command line. I wasn’t able to configure vim for autocomplete easily, so I use Visual Studio Code and the mbed-vscode-generator.

Regarding creating a custom target, I’ve only worked with ST and once we understood the structure, the ideas and the tools available, it was quite easy to create new target.

As you mentioned the porting guides seems to tell you to share you target but in practice your don’t have to. You can just have your own target directory in your app tree and create a custom_targets.json with the info needed.

I’m happy to help if you have more specific questions.

– Ladislas

Hi Ante,
maybe you should ask more detailed questions.
There is already a large section in the documents, but porting to custiom board is really an advanced subject:

The good thing is, Mbed-os has become very stable due to lot of testing. That can be done only with common hardware. And specially for STM, there a now a lot of similiar MCU that can be used as a template for deriving new boards. However, this is an error prone process and Mbed is very agile, so there are breaking changes because your hardware is not covered by the tests.

For the L422, the L432 looks similiar with less resources. So the way is to start with creating a custom_target dir and add the target specific files and the custom_target.json description.
You need to adust the linker script, the clock configuration and peripherial/pinnames.
The bonus is that you get lots of stuff like rtos, filesystems and connectivity for free.

I debug on Nucleo boards with GDB. I reflashed the on-board debugger to Segger so it works properly and stops popping up as a mass storage device. With a custom board you won’t have these problems, you can place your preferred debug header.

For building I use mbed-cli in Docker. The ELFs show up in the build directory. I use a makefile to flash and load GDB and so on.

I think Docker is essential for managing tools like mbed-cli. It has particular Python dependencies that will conflict with the rest of your system.

+1 for Docker! Need to set on up for my team as well.

If you have any feedback or documentation to share, let me know :slight_smile:

As always, I suggest giving my mbed-cmake tool a shot for any serious, long-term embedded project. First and foremost, it concentrates all dependencies in a single repo, removing some of the worries associated with how Mbed downloads/updates things from the Internet and guaranteeing that it will work exactly the same years in the future. Also, it lets you use almost any IDE you want (including VS Code and CLion, which are both very capable), or just build and upload code from the command line.

Also, re boards, my team has been using a custom PCB in our avionics unit for years, but we still have it configured in Mbed OS as the “dev board” for that chip. This works just fine as long as some of the basic PCB components (such as the clock IC) are the same type as on the dev board, but yeah if you wanted to changed those then you need a custom board.

My Docker file isn’t in version control but it’s based on this on this one.

Hi everyone!

so about two weeks have passed and I can pinpoint my frustrations a bit more clearly.

It seems to me that Mbed is both very mature - in regards to thousands of machines being unit tested to ensure that the OS is compatible and very young in terms of tools it provides.

Some of my problems come, from what I assume is mbed-os code provided by the STM. I chose STM32L422CBT since it covers all my requirements for the cheapest price. Closest supported chip was TARGET_STM32L432xC. The C on the end indicates more features than B, one which is DAC. DAC definition in common objects isn’t covered by an #if DEVICE_ANALOGOUT so it caused errors. You really have to dig to find something like this. There were some similar problems with SPI for example 422 has SPI1 and SPI2, and there are no #if guards around SPI3, so the compilation halts because there is no SPI3.

But, Mbed tools also have a bunch of problems of their own. @ladislas, @MultipleMonomials, and @cjhdev - I appreciate the suggestions for the tools! I haven’t tried all of them, tried the mbed-cmake but with not much luck.

One of the major problems I have is a lack of debugging support. I find PyOCD to be a joke - the whole industry uses OpenOCD which is tried and tested, and works. I spend 2 days debugging why PyOCD wasn’t working.

One of the reasons is that Mbed studio (for windows) provides required libraries for PyOCD, one of which is PyYAML, but provides PyYAML 4.3 something, while requirements.txt state that it requires version 5.1 or larger. So I had to manually remove that and install a newer version. I had some problems that were solved by moving to a specific version of STLINKV2 firmware, but I am still stuck since libusb dependency crashes.

If it doesn’t crash it’s stuck at “Reading symbols from XYZ.elf…” with no options to step/pause/reset the device.

I even tried to set up Ubuntu to try it, and it worked better - no dependency errors at least, but I get “GBD timeout” for debug, and stuck at 39% for flash (which from LOG show that it is waiting to ST-LINK with serial number …"

I have never had those problems with OpenOCD. And sure, I can use OpenOCD, but I can’t use it in Mbed Studio - a program whose purpose is to make Mbed programming simpler.

Most debugging support for Mbed is “once you have STDIO you can look at the messages”, but so little is provided in terms of actual line-by-line debugging.

Those are ones I found so far, and I am sure to find many more. That’s where the title comes from. I am spending more time setting up tools and finding OS/Vendor bugs than actual programming.

As far as help goes - I need help with setting up OpenOCD in an actual IDE, whichever it may be. I tried to port to Eclipse, but that was a nightmare. Mbed studio almost works with PyOCD after a few days, as I described, but it doesn’t actually debug.

1 Like

Just curious, what happened when you tried to use mbed-cmake? btw mbed-cmake also supports OpenOCD if you want to use it.

you can use also VSCode + Cortex-Debug extension. This extension kann use several debug probes, I’m happy with BlackMagicProbe because it does not need configuration. You have a launch.json with some settings for the debugger and a taks.json where build or tasks can be defined.
Only the Intellisense is a bit difficult because it sees all targets and the includes must be defined. This configuration can be done by a vscode exporter.


I haven’t figured figured out how to make it work for custom targets, ones not found in in mbed-src/targets.

WIth Mbed Studio you put TARGET_X folder and custom_targets.json in root of your project.

I’m working on a template project using mbed-cmake.

I haven’t tried the custom target yet but I will (maybe today if I get time) as it is something I need as well.

I’ll let you know how it goes.

So I added my board to the mbed-src and updated targets.json, now it finds it.

but I am stuck here https://github.com/USCRPL/mbed-cmake/wiki/Project-Configuration at step 6.

As far as I understand - I create a new folder anywhere and point it to the folder where I ran the configure_for_target.py command?

The -GMinGW32 flag doesn’t work, but -MiniGW does work.

I get an error
command line error D8021: invalid numeric argument '/Wextra' [C:\MbedCmake\test\CMakeFiles\CMakeTmp\cmTC_cefeb.vcxproj]

Another alternative on Linux is to build and debug offline with the QtCreator IDE. It takes some time to configure but then it pays off.

The flag you want is "-GMinGW Makefiles" (the quotes are important).

@MultipleMonomials Okay, after a whole day, I set it up with both minigw32 and ninja. But what now? I dont have any gui, I don’t know how to debug trough command line, I have no IDE set up.

if you use vscode, you can use cmake tools to get autocompletion and code checking.

You can follow the instructions here: https://code.visualstudio.com/docs/cpp/cmake-linux

@aoreskovic I’ve updated mbed-cmake-template to be able to use custom targets easily.

1 Like


DAC definition in common objects isn’t covered by an #if DEVICE_ANALOGOUT so it caused errors. You really have to dig to find something like this. There were some similar problems with SPI for example 422 has SPI1 and SPI2, and there are no #if guards around SPI3, so the compilation halts because there is no SPI3

I fully agree to add #if guards every where it is needed.
Don’t hesitate to push a pull request, we will review it and merge it!


1 Like

I use qt creator for all of my embedded work. It has excellent support for openocd, and debugging just works. I use the creator project format (not qmake or cmake) and GN for the build system. It’s turned out to work really well.