PlatformIO Community

Cannot compile stm32 zephyr C++

Hallo altogether,
I have a project in C using Zephyr OS on STM32 BluePill. My OS is Debian Linux. Now I want to switch to c++.

After renaming my main file to main.cpp I can use c++ features as classes, but I cannot use any c++ stl header files. I verified that they are present in the toolchain at a ~/.platformio/packages/toolchain-gccarmnoneeabi/arm-none-eabi/include subdirectory.

When I look at the verbose build output I see that the compile option -nostdinc is used and that the C++ include paths are not given. Unfortunately I do not understand where this comes from.

What can I do to get this working? I tried to add the c++ include directories to the build_flags manually, but there is a conflict with the C headers then.

Any help is highly appreciated!

Stephan

If I set the platformio.ini to

[env:bluepill]
platform = ststm32
board = bluepill_f103c8
framework = zephyr

and use the example project at platform-ststm32/examples/zephyr-blink at develop · platformio/platform-ststm32 · GitHub but replace the main.c with a main.cpp of modified content

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <vector>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0	DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN	DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS	DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0	""
#define PIN	0
#define FLAGS	0
#endif

void main(void)
{
	const struct device *dev;
	bool led_is_on = true;
	int ret;

	dev = device_get_binding(LED0);
	if (dev == NULL) {
		return;
	}

	ret = gpio_pin_configure(dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
	if (ret < 0) {
		return;
	}

    std::vector<int> delay_times {500, 250, 500, 250};
    int index = 0;
	while (1) {
		gpio_pin_set(dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;
		k_msleep(delay_times.at(index));
        index = (index + 1) % delay_times.size();
	}
}

and additionally write my zephyr/prj.conf as

CONFIG_GPIO=y
CONFIG_SERIAL=n
CONFIG_CPLUSPLUS=y
CONFIG_NEWLIB_LIBC=y

since per Unable to use C++ Standard Library · Issue #15603 · zephyrproject-rtos/zephyr · GitHub that is needed to activate C++ supprt in Zephyr, it does compile.

RAM:   [==        ]  20.1% (used 4113 bytes from 20480 bytes)
Flash: [==        ]  15.7% (used 10286 bytes from 65536 bytes)
Building .pio\build\bluepill\firmware.bin
========================= [SUCCESS] Took 11.88 seconds =========================

Interestingly enough I also tried

build_unflags = -nostdinc
build_flags = -lstdc++

in the platformio.ini, which did compile, and generated a smaller firmware, but doesn’t seem to be intended way, so you should rather stick to above.

Thank you, maxgerhardt, you made my day!

I was googling for hours, but did not find the github issue you mentioned. I also missed the prj.conf settings.

Hi @steho , @maxgerhardt

Hi, sorry if the question is very tribal but I am starting Zephyr totally lost … I am unable to see in which file the pin assignments are made … if for example I want to toggle PB3 or PA10, … do you know how to proceed?

Thank you in advance for the help

The way I see it you have to configure the device tree of the board, per documentation

Not sure if there’s a more direct way, but the documentation is there.

1 Like

so if I am not wrong if I wanted to define a led in PB7 I would have to define something like ?

	leds {
		compatible = "gpio-leds";
		green_led_2: led_2 {
			gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>;
			label = "User LD2";
		};
	};