31. October 2022

openSUSE Rust Bevy application failed with “Unable to find a GPU”

Bevy is data-driven engine written in Rust. The repository of Bevy contains several examples which can be started by a command like:

git clone --depth 1 https://github.com/bevyengine/bevy.git
cd bevy
cargo run --example alien_cake_addict

Users of openSUSe might experience following error:

hread 'main' panicked at 'Unable to find a GPU! Make sure you have installed required drivers! For extra information, see: https://github.com/bevyengine/bevy/blob/latest/docs/linux_dependencies.md', crates/bevy_render/src/renderer/mod.rs:121:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The problem is caused by missing Vulkan libraries in the system. This can be confirmed by running vkcube which may result in the following error:

vkEnumerateInstanceExtensionProperties failed to find the VK_KHR_surface extension.

Do you have a compatible Vulkan installable client driver (ICD) installed?
Please look at the Getting Started guide for additional information.

Check which graphic card is installed in the system:

sudo lspci -nnk | grep -A3 VGA

Which might result in a message like this:

00:02.0 VGA compatible controller [0300]: Intel Corporation CometLake-U GT2

With this knowledge, it’s clear that library Vulkan Intel is missing and can be installed simply by:

sudo zupper install libvulkan_intel

Application vkcube should work after this change.

30. August 2022

Unable to flash ESP32 (S2, S3, C3) with these USB-C cables

USB-C is becoming more and more popular. A straightforward assumption is that you can replace the old cable with a USB-A connector with USB-C, and everything should be the same. This assumption is wrong.

Some cables do not work well with ESP32, S2, S3, and C3. Here you can find information about cables which does not work and it’s not possible to flash dev boards with the chip with espflash, idf.py or esptool.py.

A typical error message looks like this:

Serial port: /dev/tty.usbserial-110
Connecting...

Unable to connect, retrying with extra delay...
Unable to connect, retrying with default delay...
Unable to connect, retrying with extra delay...
Error: espflash::connection_failed

  × Error while connecting to device
  ╰─▶ Failed to connect to the device
  help: Ensure that the device is connected and the reset and boot pins are not being held down

USB-C to micro-USB connected to boards ESP32-S2-USB-OTG and ESP32-S3-USB-OTG, length 60 cm, marks on cable “AWM 80 C 30V VW-1 USB 2.0 CABLE”:

  • directly connected to mac M1 2020 – does not work
  • workaround #1: press and hold boot button on the board, start flash command, release boot button after flashing process starts
  • workaround #2: connect mac M1 to monitor/hub with USB-C and connect the cable there
  • workaround #3: use computer with Windows or Linux, the cable seems to work correctly with these OSes

1. April 2022

How to develop for ESP32-C3 with Rust on macOS with Lima using Dev Container in VS Code

Lima is a solution for macOS for managing Linux VM on macOS which plays well with Dev Containers. It has several advantages over Docker Desktop for macOS or Podman.

Let’s see how it can be used for the development of software for embedded hardware like ESP32-C3 using source code from Ferrous Systems training:

git clone https://github.com/ferrous-systems/espressif-trainings.git

Install Lima and Docker-CLI:

brew install lima docker

Create Linux VM with Dockerd (following instructions from Kevin O’Brien – Utilizing Docker CLI without Docker Desktop):

curl https://raw.githubusercontent.com/lima-vm/lima/master/examples/docker.yaml -O
limactl start ./docker.yaml
limactl shell docker
sudo systemctl enable ssh.service

There is one important tweak in the Lima configuration. It’s necessary to enable write operation otherwise, the workspace mounted from VS Code is read-only. Open file ~/.lima/docker/lima.yaml and add writable flag to desired folder:

mounts:
- location: "~"
  writable: true

Restart Lima to apply changes.

limactl stop docker
limactl start docker

Create context for Docker-CLI to connect to dockerd running in the VM:

docker context create lima --docker "host=unix://${HOME}/.lima/docker/sock/docker.sock"
docker context use lima

Open VS Code with the installed Remote Container plugin and click Re-Open in Container:

cd espressif-trainings
code .

Open terminal in VS Code and build the example:

cd intro/hardware-check
cp cfg.toml.example cfg.toml
cargo build

Flashing of the resulting file could be done by espflash and mounting the device to Lima or using a tool like Adafruit WebSerial ESPTool. The file for flashing is located in the directory target/release.

31. March 2022

How to develop for ESP32-C3 with Rust on macOS with Podman using Dev Container in VS Code

Development in Dev Containers using VS Code greatly simplifies bootstrapping of the development environment. The developer does not need to install toolchains locally and spends a lot of time composing the development environment.

The default installation of VS Code is configured to work with Docker. It requires some small additional steps to switch to Podman.

Let’s begin with development using examples from Ferrous Systems training:

git clone https://github.com/ferrous-systems/espressif-trainings.git

Install Podman and check version:

brew install podman
podman --version

The version should be at least 4.0. If you have a previous version, consider an upgrade.

Following step might not be obvious to Docker users. Docker creates VM for managing containers in the background without asking the user. In the case of Podman, this is more versatile and you can define what kind of machine do you want to create. Here are a few options recommended for development, when you omit them you’ll get smaller defaults.

podman machine init --disk-size 20 --cpus 8 -m 4096 -v ${HOME}/espressif-trainings:${HOME}/espressif-trainings
podman machine start

Please, notice also -v option which mounts the development directory to Podman VM, without this mount you’ll get:

Error: statfs espressif-trainings: no such file or directory

Now the Podman VM should be ready and we can spin up containers. Go to the project directory and open Visual Studio Code:

cd ${HOME}/espressif-trainings
code .

It’s necessary to install one additional dependency for Podman: podman-compose

pip3 install podman-compose

It’s necessary to tell VS Code to use podman instead of docker commands. Go into Settings and search for keyword docker. Replace docker by podman and docker-compose by podman-compose.

VS Code is ready and click Reopen in Container.

Pulling the base image might take a while.

Open terminal and build the first ESP32-C3 example:

cd intro/hardware-check
cp cfg.toml.example cfg.toml
cargo build

Note: If VS Code is complaining about existing vscode volume, it’s possible to remove it by command

podman volume rm vscode

Note 2: If the remove is blocked by the existing terminated container, it’s possible to clean the reference by command

podman container prune

Flashing of the resulting file could be done by espflash and mounting device to Podman or using the tool like Adafruit WebSerial ESPTool. The file for flashing is located in the directory target/release.

20. April 2021

How to statically link Rust application for Windows

Rust compiler can generate a single binary that contains all dependencies. This is a great feature for creating stand-alone tools or tools for containers.

There is one gotcha for Windows which does not appear on a developer’s machine. When you move the application to a brand new installation of Windows or you try to start the in Windows Docker Container which contains Windows for Datacenters the app won’t start.

Why? The system is missing Microsoft Visual C++ Redistributable 2015-2019 (vc_redist) which you can download from microsoft.com.

It’s quite inconvenient to force the user to install the package in the case of a stand-alone Rust tool. The package installation even requires elevation of privileges.

The alternative approach to distributing vc_redist is to statically link CRT library into the application. It will result in a slightly bigger application around +100KB.

It’s necessary to tell rustc to perform static linking of CRT.

In the project create file .cargo/config.toml:

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

Rebuild the application and the new binary is statically linked and can run even on Windows 8 without vc_redist.

The interesting part is how to determine the proper target name which is on the first line of the example configuration. Many examples on the internet are referring to target.i686-pc-windows-msvc which does not work. Use the following command to determine parts of the name of the target:

rustc --print cfg
target_arch="x86_64"
target_endian="little"
target_env="msvc"
target_family="windows"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_os="windows"
target_pointer_width="64"
target_vendor="pc"
windows

The target name is composed of values on the lines above.