Embedded Development in CLion
For the specific instructions and details, check out our webhelp for Embedded Development in CLion.
What is supported
Q: Does CLion support embedded Linux?
A: Yes, it does. A project for Embedded Linux has to be compiled with a cross-compiler and then deployed and run on the target device under remote debugger. Here is an example project that demonstrates both embedded Linux support and a workaround for a related feature request.
In some cases, on-chip debugging using SWD/JTAG can be helpful, and this is also supported via the Embedded GDB server.
Q: What kind of bare-metal hardware is supported?
A: While we don’t test CLion extensively with all possible types of hardware, in general, any hardware that is supported by a relatively recent GCC toolchain or by IAR compilers should work. For example, expressif32(ESP8266, ESP32), mips32(pic32), avr8(arduino), and risc-v etc are likely to work fine. Please see our webhelp for the officially supported hardware types. CLion also offers special support for STM32 MCUs and a snippet of CMakeLists.txt, which may be a starting point for projects based on other MCU series.
Q: Is it possible to debug on a microcontroller with CLion?
A: That depends on the hardware type. For instance, AVR firmware can be compiled and flashed to the hardware, but an on-chip debugger is not supported because of hardware limitations. For many other target platforms, like ARM or RISC-V, on-chip debugging is supported via the gdbserver protocol. At the moment our primary target is ARM Cortex-M kernels: on-chip debugging is fully supported there using SEGGER, ST-LINK, and some other debug adapters.
Q: Are all STM32 chips supported out of the box?
A: The answer depends on the MCU series. For most of the STM32 MCUs, the project sources may be generated with STM2CubeMX for STM32CubeIDE, and then opened with CLion directly. Unfortunately, there are some exceptions where this approach does not work:
- Dual-core STM32H7. The generated project is not supported, but there is an experimental snippet of CMakeLists.txt. Just copy it into the generated project, look through all the “todo” comments, make the necessary changes, and then open it as a CLion project.
- STM32L5 and STM32U5 with TrustZone enabled. However, you can manually write CMakeLists.txt for your project; the example snippet above might help. STM32L5 with TrustZone disabled works out of the box.
- STM32MP1. The generated project contains two parts – Linux for Cortex A7 and bare metal for Cortex M4. This is not supported out of the box, but specific CMakeLists.txt should work. This has yet to be documented.
Q: Which hardware probes may be used?
A: You can use any probes that have gdbserver support, either via OpenOCD or via vendor-specific gdbservers. The verified hardware includes:
- stm STLINK/V2
- Segger J-Link
- Raspberry Pi direct GPIO connection
- PE-Micro Multilink Universal FX
- Some specific configs like FT232 in bitbang mode
Q: Which build systems are supported?
A: The primary project model is CMake. Starting from 2020.2, CLion also supports the Makefile build system. When configured properly, any project model should work via Compilation Database and Custom Build Targets. However, some IDE features are still limited to CMake only.
Q: How to start a project for a non-STM ARM-based MCU?
A: Make sure you have the following:
- Toolchain installed
- CMakeLists.txt for your project (feel free to use https://gist.github.com/elmot/3b4f0e9f8b23864fdf8bb509c329d051 as a basis)
- Linker script (specific to the chip)
- The CMSIS library necessary for all ARM devices
- Chip vendor libraries
- GDB server
The linker script and the libraries usually can be taken from a standard example for the chip.
As a toolchain, you should use compilers from the GNU ARM toolchain, as well as a debugger – either the GDB from the toolchain or CLion’s bundled GDB.
The GDB server is specific to your debug probe. It can be ST-Link, Segger, PE Micro, or something else. The setup procedure is briefly described in this article. You may use Raspberry Pi as well.
Troubleshooting
I’m seeing strange Gdbserver behavior, like missed or miracle breakpoints, strange hangs, etc. (especially with SEGGER J-Link).
Make sure that you have only one gdbserver instance running. Those GDB servers MUST be run in single-run mode (-s CLI switch in the case of SEGGER).
There is a limit on how many hardware breakpoints are used. For most Cortexes, the limit is 6 breakpoints simultaneously (not counting disabled ones). If more breakpoints are set, gdb will not work properly. However, some probes, such as advanced models of Segger J-Link, can help overcome the problem.
When I use a custom CMake project, diagnostics like “Compiler can’t compile a simple program” appear.
The solution is straightforward: disable the compiler check by adding the following before the project clause:
SET(CMAKE_C_COMPILER_WORKS 1)
SET(CMAKE_CXX_COMPILER_WORKS 1)
Here’s a slightly more accurate and less radical solution: relax the compiler check by adding the following before the project clause:
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
Also, for non-Linux projects, it’s worth adding the following before the project clause:
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION 1)
Is there a way to provide more than one .cfg file for openocd?
There is another, more universal way: write a new .cfg file that calls all the required files plus adjustments, and additional commands, if required.
The syntax should be quite self-explanatory, for example, st_nucleo_f103rb.cfg:
# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip.
# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875
source [find interface/stlink.cfg]
transport select hla_swd
source [find target/stm32f1x.cfg]
reset_config srst_only
I cannot seem to get the debugger working properly with Nordic Semiconductor Bluetooth MCU (nRF52x). After reaching a breakpoint and trying to continue the execution, the application crashes.
This is a very generic problem for the Bluetooth stack. The protocol has very strict timings, and any debugger activity breaks those timings. When that happens, an nRF soft device either hangs or falls into a hard fault. This is not specific to CLion but happens under any IDE or debugger. It might be that double-core Bluetooth MCUs (nRF53xxx, STM32WBxxx, etc.) work better, but we haven't tried those yet. Unfortunately, not much can be done about this.
One possible workaround would be to develop and debug all the functionality that is not related to Bluetooth first, and only then add the communication level.
You could also use prehistoric printf diagnostics via UART, RTT, or SWO.
We’re planning to implement a “live data” feature where the debugger will be able to display near-real time memory changes without stopping MCU cores. Feel free to follow and upvote CPP-22056.
For more information about CLion and nRF52x firmware development, we recommend this nRF Connect 5 SDK blog post, thanks to Nick Brook from NRB Tech.
Please sign in to leave a comment.
Are there examples or a tutorial on setting up a Docker Dev Environments image for embedded programming and on chip debugging that can be used under the new docker integration offered in CLion 21.3 and 22.1 EAP?
I see, on the Docker site, that I can create an image of a dev environment for VCS. Is it possible to use the image created for VCS directly in CLion? Could I'm not sure whether or not such a VCS based environment could be created for on chip debugging but if it could it would be extremely useful.
Hello,
Could you please clarify your question, provide more details/links. Also I'm right that when you mention "VCS", you mean Visual Studio Code (VSC)?
Hi,
Yes VCS = Visual code studio. I'm referring to the Docker Development environments which are Docker images set up with compilers/debuggers $env variables etc. oven ready for a particular development profile. They allow container snapshots, mid-development, to be taken and shared with others. It allows a programmer to share the entire programming environment, warts and all, with a colleague without fear that platform specific differences will mean that problems cannot be easily found.
See https://docs.docker.com/desktop/dev-environments/
Docker offer the option of setting up dev environments that are baked specifically for Visual Code Studio. You can access Dev Environments directly from the Docker menu, just select Dashboard > Dev Environments. You will then see the option to set up for VCS or not.
My question is can these be used/adapted for use with CLion? I know that the CLion Docker integration has really improved since 21.3 and I am hoping that I can use it to make use of this great idea from Docker.
Thanks for looking into this. I apologise if I wasn't as clear with my question as I should have been.
I didn't check it clearly, but I suppose it can be adopted for CLion (you don't need to start VSC backend in the container).
But to be honest I think it's easier to customize for example the basic ubuntu-based Dockerfile for building your own dev environment:
https://github.com/JetBrains/clion-remote/blob/master/Dockerfile.cpp-env-ubuntu
Then you need to build the image: `docker build -t clion/ubuntu/cpp-env:1.0 -f Dockerfile.cpp-env-ubuntu .` and you can use it in CLion.
BTW, it *is* possible for Linux users to debug AVR targets with CLion. Bloom was designed for this very purpose: https://bloom.oscillate.io/
Bloom interfaces with many of Microchip's debug tools (the Atmel-ICE, MPLAB SNAP, Curiosity Nano dev board, etc) and exposes a GDB server, for CLion to connect to. Effectively, Bloom provides CLion with an interface to the AVR target. Users can perform pretty much all debugging operations (breakpoints, program flow control, evaluate expressions, etc), with the exception of programming the target. Currently, Bloom cannot program the target, so users can't use GDB's "load" command. But support for this is currently in consideration (see the ticket on GitHub and vote for it: https://github.com/navnavnav/Bloom/issues/23).
Bloom supports pretty much all 8-bit AVR targets on sale today.
For instructions on configuring CLion to interface with Bloom, see https://bloom.oscillate.io/docs/clion-debugging-setup
BTW, I am the author of Bloom.
Nav, hello again, your bloom looks interesting, I'll have a close look at it soon, and contact you.