Printing goes nowhere with zephyr under PlatformIO

Hi,
When using a program compiled and installed with zephyr everything works fine.
I want to use zephyr under PlatformIO.
The same program (blinky) works fine for the LED. But printk and printf do nothing.
I have tried with and without USB-CDC, it’s the same.
I get no error. Neither at compile time, nor at execution. But no output.
Where does it go?
What to do to have it on my MAC?
In fact, no device is created in /dev when I plug the device.
As soon as I compile under zephyr env, the device appears in /dev.
So I doesn’t seem to be a zephyr issue.
The device is a nRF52840 dongle from Nordic semiconductor.
For uploading I use the USB connector.
Here’s my platformio.ini:

[env]
platform = nordicnrf52
board = nrf52840_dk
framework = zephyr
board_build.zephyr.variant = nrf52840dongle_nrf52840
extra_scripts = dfu_upload.py
upload_protocol = custom
build_flags = 
	-D ARDUINO_USB_MODE=1
	-D ARDUINO_USB_CDC_ON_BOOT=1

Here’s the zephyr/prj.conf

CONFIG_GPIO=y

CONFIG_SERIAL=y
CONFIG_CONSOLE=y

Here’s the dfu_upload.py

from os.path import basename
Import("env")
import os

platform = env.PioPlatform()

def dfu_upload(source, target, env):
    firmware_path = str(source[0])
    firmware_name = basename(firmware_path)

    print("Upload to nrf52840 dongle.")
    print("firmware_path = ",firmware_path)
    print("firmware_name = ",firmware_name)

    genpkg = "".join(["nrfutil-mac pkg generate --hw-version 52 --sd-req=0x00 --application ", firmware_path, " --application-version 1 firmware.zip"])
    dfupkg = "nrfutil-mac dfu serial -pkg firmware.zip -p /dev/cu.usbmodemFA92DCD2F3641 -b 115200"
    print( genpkg )
    os.system( genpkg )
    os.system( dfupkg )

    print("Uploading done.")


# Custom upload command and program name
env.Replace(PROGNAME="firmware", UPLOADCMD=dfu_upload)

And finally here’s the src/main.c

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

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

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

/* 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;

	printf("DEBUT\n");
	dev = device_get_binding(LED0);
	if (dev == NULL) {
		return;
	}

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

	while (1) {
		gpio_pin_set(dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;
		printk("LED state k: %s\n", led_is_on ? "ON" : "OFF");
		printf("LED state f: %s\n", led_is_on ? "ON" : "OFF");
		k_msleep(SLEEP_TIME_MS);
	}
}

The led blinks well. If I change the sleep_time it changes on the board.

My problem is only with the printf and printk.

Can someone help me?
Thanks

After reading many posts and the code in both environments (PlatformIO and zephyr), I have added the file zephyr/nrf52840dongle_nrf52840.overlay
it’s content is:

&uart0 {
  compatible = "nordic,nrf-uart";
  status = "okay";
  current-speed = <115200>;
  tx-pin = <20>;
  rx-pin = <24>;
};

I have then connected a ftdi to those pins.
20 should be 0.21 on the board, and 24 should be 0.25
Nothing goes to the monitor on the Mac.
I have tried all other pins with same result.

I think I’m not too far from the solution.
Maybe it’s just a matter of syntax.
If someone has encountered this problem could help me.

In fact, the overlay file was not necessary.
The file /Users/nb/.platformio/packages/framework-zephyr/boards/arm/nrf52840dongle_nrf52840/nrf52840dongle_nrf52840.dts is used.
Here is an extract of its contents:

        model = "Nordic nRF52840 Dongle NRF52840";
        compatible = "nordic,nrf52840-dongle-nrf52840";

        chosen {
                zephyr,console = &uart0;
                zephyr,shell-uart = &uart0;
                zephyr,uart-mcumgr = &uart0;
                zephyr,bt-mon-uart = &uart0;
                zephyr,bt-c2h-uart = &uart0;
                zephyr,sram = &sram0;
                zephyr,flash = &flash0;
                zephyr,code-partition = &slot0_partition;
        };
[...]
&uart0 {
        compatible = "nordic,nrf-uarte";
        status = "okay";
        current-speed = <115200>;
        tx-pin = <20>;
        rx-pin = <24>;
        rx-pull-up;
        rts-pin = <17>;
        cts-pin = <22>;
        cts-pull-up;
};
[...]

So output should be on pins 20 (0.21) and 24 (0.25).
The problem is that two pins are used by the reset button.
Unless the match above is wrong.
I’ve read that pins 0-31 go to 0. and 32-63 go to 1.
Of course I’ve checked all non power pins with the ftdi.
Before that I have defined uart in the program

        const struct device *uart_dev;
        struct uart_config uart_cfg;
        uart_dev = DEVICE_DT_GET(DT_NODELABEL(uart0));

        // Configure the UART device
        uart_cfg.baudrate = 115200;
        uart_cfg.parity = UART_CFG_PARITY_NONE;
        uart_cfg.stop_bits = UART_CFG_STOP_BITS_1;
        uart_cfg.data_bits = UART_CFG_DATA_BITS_8;
        uart_cfg.flow_ctrl = UART_CFG_FLOW_CTRL_NONE;

        printk("UART device configured");

I’m stuck.

I finally got my program to work with a nrf52840 dongle. I used the ACM CDC mode.
In case anyone’s interested, or if it’s of use to someone in my situation, here’s the information.

zephyr/prj.conf:

CONFIG_GPIO=y

CONFIG_LOG=y
CONFIG_LOG_PRINTK=y
#CONFIG_LOG_BACKEND_UART=y

CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr USB console sample"
CONFIG_USB_DEVICE_PID=0x0004

CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_LINE_CTRL=y
zephyr/nrf52840dongle_nrf52840.overlay
/ {
        chosen {
                zephyr,console = &cdc_acm_uart0;
        };
};

&zephyr_udc0 {
        cdc_acm_uart0: cdc_acm_uart0 {
                compatible = "zephyr,cdc-acm-uart";
                label = "CDC_ACM_0";
        };
};

src/main.c

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

#include <stdio.h>
#include <kernel.h>
#include <drivers/gpio.h>
#include <logging/log.h>

// For Console over CDC ACM UART
#include <usb/usb_device.h>
#include <drivers/uart.h>

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

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

LOG_MODULE_REGISTER(MyModule, LOG_LEVEL_INF);

/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

/**
 * @brief Validate that GPIO port is ready.
 *
 * @param spec GPIO specification from devicetree
 *
 * @retval true if the GPIO spec is ready for use.
 * @retval false if the GPIO spec is not ready for use.
 */
static inline bool gpio_is_ready_dt(const struct gpio_dt_spec *spec)
{
        /* Validate port is ready */
        return device_is_ready(spec->port);
}

int main(void)
{
	int ret;
	bool led_state = true;
	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
	uint32_t dtr = 0;

	if (usb_enable(NULL)) {
        	return -1;
	}

	while (!dtr) {
        	uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
        	k_sleep(K_MSEC(100));
	}

	printk("Console (printk) over CDC ACM works\n");
	LOG_ERR("Console (LOG_ERR) over CDC ACM works\n");

	if (!gpio_is_ready_dt(&led)) {
		return 0;
	}

	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
	if (ret < 0) {
		return 0;
	}

	while (1) {
		ret = gpio_pin_toggle_dt(&led);
		if (ret < 0) {
			return 0;
		}

		led_state = !led_state;
		printk("LED (printk) state: %s\n", led_state ? "ON" : "OFF");
		LOG_ERR("LED (LOG_ERR) state: %s\n", led_state ? "ON" : "OFF");
		k_msleep(SLEEP_TIME_MS);
	}
	return 0;
}