Skip to main content

USB Logging

Overview

If you are developing ZMK on a device that does not have a built in UART for debugging and log/console output, Zephyr can be configured to create a USB CDC ACM device and the direct all printk, console output, and log messages to that device instead.

Battery Life Impact

Enabling logging increases the power usage of your keyboard, and can have a non-trivial impact to your time on battery. It is recommended to only enable logging when needed, and not leaving it on by default.

Kconfig

The CONFIG_ZMK_USB_LOGGING Kconfig enables USB logging. This can be set at the keyboard level, typically in the config/<your_keyboard>.conf file if you are using a user config repository. It can also be enabled at the ZMK level using the app/prj.conf file, or other search locations described in the configuration overview.

Logging can be further configured using Kconfig described in the Zephyr documentation. For instance, setting CONFIG_LOG_PROCESS_THREAD_STARTUP_DELAY_MS to a large value such as 8000 might help catch issues that happen near keyboard boot, before you can connect to view the logs.

note

In Github Actions, you can check the <Keyboard> Kconfig file step output to verify the options above have been enabled for you successfully.

# Turn on logging, and set ZMK logging to debug output
CONFIG_ZMK_USB_LOGGING=y

Viewing Logs

After flashing the updated ZMK image, the board should expose a USB CDC ACM device that you can connect to and view the logs.

On Linux, this should be a device like /dev/ttyACM0 and you can connect with minicom or tio as usual, e.g.:

sudo tio /dev/ttyACM0

From there, you should see the various log messages from ZMK and Zephyr, depending on which systems you have set to what log levels.

Adding USB Logging to a Board

Standard boards such as the nice!nano and Seeeduino XIAO family have the necessary configuration for logging already added, however if you are developing your own standalone board you may wish to add the ability to use USB logging in the future.

To add USB logging to a board you need to define the USB CDC ACM device that the serial output gets piped to, as well as adding the console in the chosen node inside <board>.dts.

Inside the USB device (&usbd), add the CDC ACM node:

&usbd {
status = "okay";
cdc_acm_uart: cdc_acm_uart {
compatible = "zephyr,cdc-acm-uart";
};
};

Then you can add the zephyr,console binding in the chosen node:

/ {
chosen {
...
zephyr,console = &cdc_acm_uart;
};
...
};