Creating a project with multiple executables.

12 Oct 2017

I'm working on a system using multiple distinct devices. There is a good amount of shared code and data, and they'll generally use a lot of the same libraries. I would like to have a single repository with the code for each of these devices. Ideally, I would have a single directory with shared libraries/includes, to include mbed-os, and a directory with several mbed programs (each in their own sub-directory) using these libraries. I have not been able to create such a project.

I could create a repository and use a submodule mbed project for each device, but this would mean importing a copy of mbed-os and any libraries for every device. Additionally, if I were to update a library in one device I might forget to update one of the others and end up with a system using several versions of the same library.

Can anyone point me in the right direction?

30 Oct 2017

Have you considered using an mbed_app.json? With this you can specify generic defines on a per-device basis.

21 Dec 2017

What compilation tool are you using? If you're using mbed CLI, I have set up my multi-binary/library application as follows:

You can initialize an mbed program in the root of your development directories. This will allow you to still use "mbed target <MCU>" and "mbed toolchain <toolchain>" to set a global target/toolchain for the build system.

mbed CLI allows you to build static libraries (detailed in the user guide here) and link to them using the "source" flag with "mbed compile"

The way I have set up multi-binary projects using a single repository is to use the "source" flag to tell mbed cli where all my static libraries, shared code files, and the actual application is. You can give mbed CLI multiple "source" flags and it will recursively search each directory for source files to compile.

You may need to make your own build scripts to streamline this process, but it's better than having several git submodules and copies of mbed-os all over the place.

For example, an mbed compile command for one of my project's applications may look like this:

mbed compile --build=BUILD --source=. --source=../../../lib/build_debug/ --source=../include --source=../common --profile=../../../mbed-os/tools/profiles/debug.json --app-config=./mbed_app.json

This will build the application residing in the current directory using the debug static libraries (also built with a command similar to this) along with the include/common source directories.

You can also customize build settings using the build profile .json file, and accomplish application level configuration by providing an mbed_app.json, which you can point mbed cli to using the app-config flag. Read more about compilation configuration here.

Another interesting feature I've been playing with is using mbed's built-in folder gating system to create different implementations for features. For example, if you use an ADC for some feature across your product line that includes different platforms/MCUs, you can provide separate implementations for one header file based on your mbed target setting.

If you've looked through the mbed-os codebase, you'll notice there's several folders that look like "FEATURE_BLANK" or "TARGET_BLANK" or something along those lines. I haven't found it documented anywhere, but mbed CLI actually uses these to conditionally build source directories for different targets.

If your project uses an "STM32F4" and a "KL43Z" and you want to provide separate implementations for a feature, you can do something like:

./common
.. FEATURE_ADC_THING
...... adc_thing.h
...... TARGET_STM32F4
............... adc_thing.cpp
...... TARGET_KL43Z
............... adc_thing.cpp

When mbed CLI looks in the "common" subdirectory and sees FEATURE_ADC_THING, it will only look in this folder if the target has ADC_THING as part of it's feature list (read more about targets here.

Additionally, if the target has feature ADC_THING, then it will look in the folder and see the two TARGET subdirectories. If the current target is/inherits from STM32F4, then it will look for source files in the that directory (and build the .cpp implementation for the STM32F4 MCUs). If it is/inherits from the KL43Z, then it will look in that TARGET subdirectory for source files. In this way you can maintain separate implementations of drivers for multiple platforms.

The caveat is that mbed's build scripts prohibit custom features, so you'll have to modify mbed-os/tools/config/init.py to allow your custom features. There's a list of allowed features somewhere in that script, you can just add yours in and the build system won't complain about them anymore.

There are a few other build configuration options you can look into. One useful one is .mbedignore, which works like .gitignore allowing you to specify files/subdirectories to exclude from mbed CLI's recursive search (good for documentation directories).

You can also specify "build hooks", which are detailed in the target creation guide I linked to above. These allow you to specify additional build steps after compilation (such as merging hex files or other post-processing stuff). You can add custom targets by putting a "custom_targets.json" file in your mbed-os root directory.

There may be a few other things I'm forgetting. I have a highly customized mbed build setup that makes it a bit more maintainable/professional... You could always export your project but maintaining makefiles became a headache for me. mbed CLI just works, but you have to learn it inside and out if you want the same flexibility as makefiles.

28 Dec 2017

Building offline with Qt Creator IDE and GNU Arm tool chain will allow you to share a single repository of mbed and user libraries with all projects rather than having a separate instance for each one.