Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

ESP32 development on a Mac, with Multipass for sandboxing the toolchain

NotificationsYou must be signed in to change notification settings

lure23/ESP32-Mac

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

..with focus onEmbassy

Getting started with ESP32 Rust development, using macOS host (for IDE) and a Multipass VM (other tooling).

Note: This repo builds uponESP32 on WSL (Windows and WSL; esp-idf; C/C++)

Aim 🍏⛓️

  • Minimal software installs on the host (Mac)
  • Ability to flash the device from within Multipass VM

Focus

  • RISC V only

    If you want Xtensa-based chips covered, please sign up as a co-author. This one doesn't own the chips. :)

  • Embassy async development

    Embassy is agenerational shift in embedded programming. Its support forasync without a separate RTOS makes concurrent programming linear to write. This is very similar to what Node.js did.

  • Only stable Rust

    ESP32 (RISC V variants) Rust development is possible using the stable Rust (Jun'24).

Requirements

**Alternative A. Connecting devices via Windows**
**Alternative B. Connecting devices via Raspberry Pi**
**Alternative C. Connecting devices directly to Mac**

Not recommended.

There's no good open source USB/IP server for macOS and Multipass doesn't have USB device management, unlike other VM solutions.

If you want to do this, also consider that attaching solderable electronics to a computer always carries risks. The author sees it beneficial to have an air gap between the USB/IP server and the development machine! ⚡️

Embedded hardware

The intention is to support as many common ESP32 (RISC V) development boards as possible. If you have access to boards not listed below, please consider giving a PR and/or becoming a co-author to the repo.

Warning!!

When powering the ESP32 boards for the first time,BEWARE OF THE STRONG LED LIGHT!! The author used a tape on top, until he reflashed the device. 😎🩹


boardhw version[1]chip revision[2]``[3]statusnotes
ESP32-C3-DevKitC-02"1.1"0.4works withespflash
ESP32-C3-DevKit-RUST-1"1.2a (04/2022)"0.4works withespflash
ESP32-C6-DevKitM-1"1.0"0.0works withespflash
`[1]`: version *physically printed* on the back side of the circuit board.

[2]: revision listed when runningespflash board-info or restarting a board. This matters to some functionality, e.g. for C3 boards JTAG functionality (with added cable) is available for chip revisions >= 0.4.

[3]: Earlier documentation and bootloaders (from the ESP-IDF 4 era; up till Dec'22) mention chip revisions "3" and "4", they mean 0.3 and 0.4.

Board specific notes

The boards have USB connectors, but whether these are standard "USB+UART" (serial port) or connected to an integrated JTAG debugging circuitry varies.

VID:PIDflashingcommsdebug
UART10c4:ea60-
JTAG303a:1001

You can use either port for programming, but need JTAG for interactive debugging. UART is the default foresp-hal. Below, we will cover both.

VID:PID are the device identifiers you'll see in USB access.

ESP32-C3-DevKitC-02

The board has just one Micro-USB port. To gain access to JTAG, you need to solder a USB cable to the board.Details here

pinUSBwire color
GPIO18D-⬜️
GPIO19D+🟩
5VV_BUS🟥
GNDGround⬛️

ESP32-C3-DevKit-RUST-1

Has only JTAG connection (USB-C).

ESP32-C6-DevKitM-01

The dev board has two USB ports:

For now,connect the cable to the "left" (uart) port. This way, the default settings ofesp-hal (we'll get there soon) will allowprintln messages to be see on the VM terminal.

Prepare

USB/IP sharing

  • Set up USB/IP sharing according to instructions in theESP32-WSL (ignore the WSL parts of it).

    You should have:

    • usbipd bind exposing the dev board to the network
    • IP of the computer doing the sharing

Multipass VM

We use a Multipass VM to keep the Rust development toolchain away from your main account. This is similar to using a dockerized workflow for development.

  • Study themp repo in detail!

    • Create therust-emb instance within it.

Connecting the device to Multipass

We presume you have the USB/IP server running, and know the IP of the machine (192.168.1.29 below - replace with yours).

$ multipass shell rust-emb

The following commands are to be given in therust-emb VM.

  1. Check that you can see the dev board (optional)

    $ usbip list -r 192.168.1.29
    **ESP32-C3-DevKitC-02**
    Exportable USB devices====================== - 192.168.1.29        3-1: Silicon Labs : CP210x UART Bridge (10c4:ea60)           : USB\VID_10C4&PID_EA60\BC2F214F809DED11AAFA5F84E259FB3E           : (Defined at Interface level) (00/00/00)           :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
    **ESP32-C3-DevKit-RUST-1**
    Exportable USB devices======================  - 192.168.1.29         3-1: unknown vendor : unknown product (303a:1001)            : USB\VID_303A&PID_1001\40:4C:CA:8D:9B:44            : Miscellaneous Device / ? / Interface Association (ef/02/01)            :  0 - Communications / Abstract (modem) / None (02/02/00)            :  1 - CDC Data / unknown subclass / unknown protocol (0a/02/00)            :  2 - Vendor Specific Class / Vendor Specific Subclass / unknown protocol (ff/ff/01)
    **ESP32-C6-DevKitM-1 (`uart`)**
     Exportable USB devices ======================  - 192.168.1.29         3-1: Silicon Labs : CP210x UART Bridge (10c4:ea60)            : USB\VID_10C4&PID_EA60\3086768A3759ED11B797B7301D62BC44            : (Defined at Interface level) (00/00/00)            :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
    **ESP32-C6-DevKitM-1 (`JTAG-serial`)**
     Exportable USB devices ======================  - 192.168.1.29         3-1: unknown vendor : unknown product (303a:1001)            : USB\VID_303A&PID_1001\54:32:04:07:15:10            : Miscellaneous Device / ? / Interface Association (ef/02/01)            :  0 - Communications / Abstract (modem) / None (02/02/00)            :  1 - CDC Data / unknown subclass / unknown protocol (0a/02/00)            :  2 - Vendor Specific Class / Vendor Specific Subclass / unknown protocol (ff/ff/01)
  2. Attach the dev board to your VM

    $ sudo usbip attach -r 192.168.1.29 -b 3-1
  3. Now you should see it in the device tree:

    $ lsusb
    **ESP32-C3-DevKitC-02**
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 009: ID 10c4:ea60 Silicon Labs CP210x UART BridgeBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    **ESP32-C6-DevKitM-1 (`uart`)**
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 007: ID 10c4:ea60 Silicon Labs CP210x UART BridgeBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    **ESP32-C6-DevKitM-1 (`JTAG-serial`)**
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hubBus 001 Device 003: ID 303a:1001 Espressif USB JTAG/serial debug unitBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
  4. Check withespflash

    $ espflash board-info
    **ESP32-C3-DevKitC-02**
    [2024-06-03T11:27:27Z INFO ] Serial port: '/dev/ttyUSB0'[2024-06-03T11:27:27Z INFO ] Connecting...[2024-06-03T11:27:28Z INFO ] Using flash stubChip type:         esp32c3 (revision v0.4)Crystal frequency: 40 MHzFlash size:        4MBFeatures:          WiFi, BLEMAC address:       54:32:04:41:7d:60
    **ESP32-C6-DevKitM-1 (`uart`)**
    [2024-06-03T11:00:18Z INFO ] Serial port: '/dev/ttyUSB0'[2024-06-03T11:00:18Z INFO ] Connecting...[2024-06-03T11:00:18Z INFO ] Using flash stubChip type:         esp32c6 (revision v0.0)Crystal frequency: 40 MHzFlash size:        4MBFeatures:          WiFi 6, BT 5MAC address:       54:32:04:07:15:10
    **ESP32-C6-DevKitM-1 (`JTAG-serial`)**
    [2024-06-03T11:25:36Z INFO ] Serial port: '/dev/ttyACM0'[2024-06-03T11:25:36Z INFO ] Connecting...[2024-06-03T11:25:36Z INFO ] Using flash stubChip type:         esp32c6 (revision v0.0)Crystal frequency: 40 MHzFlash size:        4MBFeatures:          WiFi 6, BT 5MAC address:       54:32:04:07:15:10

    Info:espflash is one of the commands you can use for interacting with the device (flashing and seeing its info).

  5. Check withprobe-rs

    $ probe-rs list
    **ESP32-C3-DevKitC-02**
    No debug probes were found.
    **ESP32-C6-DevKitM-1 (`uart`)**
    No debug probes were found.
    **ESP32-C6-DevKitM-1 (`JTAG-serial`)**
    The following debug probes were found:[0]: ESP JTAG -- 303a:1001:54:32:04:07:15:10 (EspJtag)

Run some examples fromesp-hal

Background: Theesp-hal repo (Hardware Abstraction Layer) has code that allows using the ESP32 hardware from Rust. It also includes anexamples folder that we'll look into.

Clone

Let's clone theesp-hal repo to your host (Mac):

$ git clone --depth 1 git@github.com:esp-rs/esp-hal.git

--depth 1 excludes history; we don't need it and same some disk space

Share the folder with VM

$ multipass stop rust-emb$ multipass mount --type=native esp-hal rust-emb:/home/ubuntu/esp-hal

Note: We don't need to enter theesp-hal folder on the host side. Just sharing it with the VM.

Now you haveesp-hal available within the VM.

Note: Unfortunately, using--type=native requires the VM to be shut down when adding/removing mounts. On the other side, it promises better performance than default Multipass mounts. The folder is huge (ca. 1.9GB) so we like to have the performance!!

Restart the VM

$ multipass shell rust-emb

Within the VM, re-attach the development kit. It was lost when we restarted the VM.

$ sudo usbip attach -r 192.168.1.29 -b 3-1

Build

Within the VM:

$ cd esp-hal

Study theesp-hal/examples/ folder.

This is a treasure trove of dealing with different sensors. To begin with, we just build (and run) thehello_world example.

Within theesp-hal folder in the VM:

$ cargo xtask run-example esp-hal esp32c6 hello_world

Output:

**ESP32-C3-DevKitC-02**
...Hello world!Hello world!
**ESP32-C6-DevKitM-1 (`uart`)**
...Hello world!Hello world!
**ESP32-C6-DevKitM-1 (`JTAG-serial`)**
...I (112) esp_image: segment 3: paddr=00017614 vaddr=40800020 size=00eech (  3820) loadI (120) boot: Loaded app from partition at offset 0x10000

(no output)

See the devkit specific appendix for an explanation.

Since console output only goes touart, it's probably best to move to using that port, for further examples.

More samples

To see which samples are suitable for e.g.esp32-c6:

$ git grep -P "(?<=% CHIPS:).*esp32c6" examples/src/

That gives 82 (65 for C3) matches! 😃

Embassy!

Theesp-hal andembassy repos seem to be arranged so (for ESP32, that is) that we don't need to switch repos. The examples for Embassy are withinesp-hal/examples/src/bin/embassy_*.rs (18 of them).

This is good.

What's special about Embassy? It harnesses theasync/await mechanism, making creatingconcurrent embedded codeeasy to write. This is brilliance - seeEmbassy.dev for more details or just hang on and let's give it a try! ☀️

$ cargo xtask run-example esp-hal esp32c6 embassy_hello_world
**ESP32-C3-DevKitC-02**
Init!Bing!Hello world from embassy using esp-hal-async!Hello world from embassy using esp-hal-async!
**ESP32-C6-DevKitM-1 (`uart`)**
...Init!Bing!Hello world from embassy using esp-hal-async!Hello world from embassy using esp-hal-async!
**ESP32-C6-DevKitM-1 (`JTAG-serial`)**
...Init!Bing!Hello world from embassy using esp-hal-async!Hello world from embassy using esp-hal-async!

AboutJTAG-serial anddefmt logging

The above example was able to be run also on C6JTAG-serial, with a one line configuration change inexamples/Cargo.toml:

-esp-println         = { path = "../esp-println", features = ["log"] }+esp-println         = { path = "../esp-println", default-features=false, features = ["log", "jtag-serial", "defmt-espflash"] }

The default (that works for C3 and C6uart) is targetinguart. Here, we prevented default features (default-features=false) and manually chose output to go tojtag-serial.

In addition - and this may be useful for any target -defmt-espflash was enabled. You canread online more aboutdefmt; in short it makes logging easier on the embedded side, causing smaller binary sizes. It's a Good Thing but needs support from the development toolchain. Which we seem to have.

All this works because theembassy_hello_world usesesp_println::println! for its output.

Other samples

Now is a good time to check through the other 24*embassy_*.rs samples (note that wifi ones start withesp_wifi_embassy).

What's so great about Embassy?

It just helps you code embedded in theright andefficient way. If all your code areawaiting something, it means the Embassy scheduler has placed the CPU to sleep mode. These are details you just don't need to be concerned of.

This author sees a bright future for the Embassy project, and now You can be part of it!

Outcome

We set out to create a development toolchain with the following aims:

  • Minimal software installs on the host (Mac)
  • Ability to flash the device from within Multipass VM

This was reached. :) You can now extend the reach by studying and modifying the other Embassy examples, and bringing your electronics and motor skills to the game!

This is probably a good place to stop the repo. It is doing its service if it made it easy for you to step in. Pleasespread the word and if you find any mistakes - or have other ESP32 boards you would like to be featured - chime in!

The plans of the author can be seen in the repo'sIssues section.

Happy Riscing! 🎉

Q/A & Hints

How doesprobe-rs find a development board?

Note the303a:1001 in e.g. thelsusb output. These are the "vendor id" and "product id" of your board.

They match a line in theudev rules file used byprobe-rs:

$ cat /etc/udev/rules.d/69-probe-rs.rules | grep 303a | grep 1001ATTRS{idVendor}=="303a", ATTRS{idProduct}=="1001", MODE="660", GROUP="plugdev", TAG+="uaccess"

How to make the VM more performant?

You can increase the number of cores Multipass is allowed to use by:

  • multipass stop rust-emb
  • multipass set local.rust-emb.cpus={X}

Thenmultipass shell rust-emb to get back in action.

DevKit specific

ESP32-C3-DevKitC-02

The device has a single USB port. From chip revisions 0.3 onwards, itdoes also have JTAG circuitry, but enabling this needs soldering a USB cable to the device.

The ESP32-C3 Devkit C doesn't expose the JTAG interface over USB by default, see theESP32-C3 debugging docs to configure the board for debugging or consider using the esp32c3-rust-board instead.source

Tried this, and it works. However, what benefits JTAG really brings over UART needs to be studied..

ESP32-C3-DevKit-RUST-1

Be aware before purchasing:

This board contains some peripherals to get started easier. Having Rust in its name seems enticing. It's intended for educational purposes.

However:

  • its availability may be worse than the other two
  • it comes without pins soldered so you must add those before using on a breadboard
  • anecdotally, the author's board cost 50 euros (about 5x more than the others!)
  • ..and he needed to fill all kinds ofexport forms that weren't needed by the other, computationally similar boards.

This is the kind of logistics friction we can do without. The shopping and using experience with the other two boards was smooth, in comparison!

ESP32-C6-DevKitM-1

As already mentioned, the kit has two USB ports,uart andJTAG-serial. Programming works on both, but passing the console (println) output is by default sent to theuart port.

  • See above on how to steer the output touart vs.jtag-serial, based on your needs.

  •  What are the benefits of such dedicated JTAG connection? (debugging; try and tell)tbd.

References

About

ESP32 development on a Mac, with Multipass for sandboxing the toolchain

Topics

Resources

Stars

Watchers

Forks


[8]ページ先頭

©2009-2025 Movatter.jp