{"id":13472740,"url":"https://github.com/ivmarkov/rust-esp32-std-demo","last_synced_at":"2025-09-30T17:30:28.214Z","repository":{"id":37934844,"uuid":"313106970","full_name":"ivmarkov/rust-esp32-std-demo","owner":"ivmarkov","description":"Rust on ESP32 STD demo app. A demo STD binary crate for the ESP32[XX] and ESP-IDF, which connects to WiFi, Ethernet, drives a small HTTP server and draws on a LED screen.","archived":true,"fork":false,"pushed_at":"2024-08-01T07:38:56.000Z","size":693,"stargazers_count":784,"open_issues_count":13,"forks_count":105,"subscribers_count":24,"default_branch":"main","last_synced_at":"2024-09-29T18:36:27.489Z","etag":null,"topics":["esp32","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivmarkov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-15T19:28:28.000Z","updated_at":"2024-09-26T10:09:33.000Z","dependencies_parsed_at":"2024-01-14T04:44:04.540Z","dependency_job_id":"ad8f6e19-5d12-41da-bc7a-6150b4fa69ee","html_url":"https://github.com/ivmarkov/rust-esp32-std-demo","commit_stats":{"total_commits":258,"total_committers":20,"mean_commits":12.9,"dds":0.4534883720930233,"last_synced_commit":"46c59d56c48831907bebf6e96e234b0b74e20d30"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Frust-esp32-std-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Frust-esp32-std-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Frust-esp32-std-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivmarkov%2Frust-esp32-std-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivmarkov","download_url":"https://codeload.github.com/ivmarkov/rust-esp32-std-demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234753665,"owners_count":18881436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esp32","rust"],"created_at":"2024-07-31T16:00:57.556Z","updated_at":"2025-09-30T17:30:27.815Z","avatar_url":"https://github.com/ivmarkov.png","language":"Rust","funding_links":[],"categories":["Rust","Projects"],"sub_categories":["`std`"],"readme":"# Rust on ESP32 STD demo app\n\nA demo STD binary crate for the ESP32[XX] and ESP-IDF, which connects to WiFi, Ethernet, drives a small HTTP server and draws on a LED screen.\n\n![CI](https://github.com/ivmarkov/rust-esp32-std-demo/actions/workflows/ci.yml/badge.svg)\n\n[Join in](https://matrix.to/#/#esp-rs:matrix.org) on the discussion!\n\n# Important Update\n\nThis GH repository is now **deprecated**, because all of the functionalities it demonstrates (and more!) are available in the form of **examples/** directly in the `esp-idf-sys`/`esp-idf-hal`/`esp-idf-svc` crates (see below).\n\n**To easily generate a \"Hello, world!\" binary crate for Espressif MCUs with ESP-IDF, use the [`esp-idf-template`](https://github.com/esp-rs/esp-idf-template)**.\n\nExamples:\n* `esp-idf-svc` [examples](https://github.com/esp-rs/esp-idf-svc/tree/master/examples)\n* `esp-idf-hal` [examples](https://github.com/esp-rs/esp-idf-hal/tree/master/examples)\n  * If you use `esp-idf-svc` already, just replace all `use esp_idf_hal::...` with `use esp_idf_svc::hal::...`\n* `esp-idf-sys` [examples](https://github.com/esp-rs/esp-idf-sys/tree/master/examples)\n  * If you use `esp-idf-svc` already, just replace all `use esp_idf_sys::...` with `use esp_idf_svc::sys::...`\n\nThe repository might also be *archived* soon.\n\n## Highlights:\n\n- **Pure Rust and pure Cargo build!** No CMake, no PlatformIO, no C helpers\n  - ... via [esp-idf-sys](https://crates.io/crates/esp-idf-sys) and [embuild](https://crates.io/crates/embuild)\n- **Support for Rust STD** (threads, console, TCP/IP) safe APIs\n  - ... upstreamed and [part of the Rust STD library](https://github.com/rust-lang/rust/pull/87666)\n- **New, experimental!** Support for asynchronous networking using [smol](https://github.com/smol-rs/smol)\n- Support for running in the [Espressif fork of QEMU](https://github.com/espressif/qemu/wiki)\n- Rust Safe APIs for various ESP-IDF services like WiFi, Ping, Httpd and logging\n  - ... via [esp-idf-svc](https://crates.io/crates/esp-idf-svc) ([embedded-svc](https://crates.io/crates/embedded-svc) abstractions implemented on top of ESP-IDF)\n- NAPT support (Router from the SoftAP to the STA interface). **NOTE**: In production, do NOT leave the SoftAP interface open (without password)!\n- Driving a LED screen with the [embedded-graphics](https://crates.io/crates/embedded-graphics) Rust crate\n  - ... via [esp-idf-hal](https://crates.io/crates/esp-idf-hal) ([embedded-hal](https://crates.io/crates/embedded-hal) drivers implemented on top of ESP-IDF)\n- (ESP32-S2 only) [Blink a LED](https://github.com/ivmarkov/rust-esp32-ulp-blink) by loading a pure Rust program onto the RiscV Ultra Low Power CPU\n\n## Build\n\n- Install the [Rust Espressif compiler toolchain and the Espressif LLVM Clang toolchain](https://github.com/esp-rs/rust-build)\n  - This is necessary, because support for the Xtensa architecture (ESP32 / ESP32-S2 / ESP32-S3) is not upstreamed in LLVM yet\n- Switch to the `esp` toolchain from the pre-built binaries: `rustup default esp`\n  - (You can also skip this step and switch to the `esp` toolchain *for the demo crate only* by executing `rustup override set esp` inside the `rust-esp32-std-demo` directory once you have cloned the demo as per below)\n  - **NOTE** For ESP32-C3 - which runs a RiscV32 chip - you can just use the stock nightly Rust compiler, and a recent, stock Clang (as in Clang 11+)\n  - (You can do this by issuing `rustup install nightly` and then `rustup default nightly` instead of installing/building the Rust \u0026 Clang ESP forks and switching to their `esp` toolchain as advised above)\n- If using the custom Espressif Clang, make sure that you DON'T have a system Clang installed as well, because even if you have the Espressif one first on your `$PATH`, Bindgen will still pick the system one\n  - A workaround that does not require uninstalling the system Clang is to do `export LIBCLANG_PATH=\u003cpath to the Espressif Clang lib directory\u003e` prior to continuing the build process\n- `cargo install ldproxy`\n- Clone this repo: `git clone https://github.com/ivmarkov/rust-esp32-std-demo`\n- Enter it: `cd rust-esp32-std-demo`\n- Export two environment variables that would contain the SSID \u0026 password of your wireless network:\n  - `export RUST_ESP32_STD_DEMO_WIFI_SSID=\u003cssid\u003e`\n  - `export RUST_ESP32_STD_DEMO_WIFI_PASS=\u003cpassword\u003e`\n- To configure the demo for your particular board, please uncomment the relevant [Rust target for your board](https://github.com/ivmarkov/rust-esp32-std-demo/blob/main/.cargo/config.toml#L2) and comment the others. Alternatively, just append the `--target \u003ctarget\u003e` flag to all `cargo build` lines below.\n- Build: `cargo build` or `cargo build --release`\n  - (Only if you happen to have a [TTGO T-Display board](http://www.lilygo.cn/prod_view.aspx?TypeId=50033\u0026Id=1126\u0026FId=t3:50033:3)): Add `ttgo` to the `--features` build flags above (as in `cargo build --features ttgo`) to be greeted with a `Hello Rust!` message on the board's LED screen\n  - (Only if you happen to have a [Waveshare board](https://www.waveshare.com/wiki/E-Paper_ESP32_Driver_Board) and a [waveshare 4.2\" e-paper screen](https://www.waveshare.com/wiki/4.2inch_e-Paper_Module)): Add `waveshare_epd` to the `--features` build flags above (as in `cargo build --features waveshare_epd`) to be greeted with a `Hello Rust!` message on the e-paper screen\n  - (Only if you happen to have an [ESP32-S2-Kaluga-1 board](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html)): Add `kaluga` to the `--features` build flags above (as in `cargo build --features kaluga`) to be greeted with a `Hello Rust!` message on the board's LED screen\n  - (Only if you happen to have a [Heltec LoRa 32 board](https://heltec.org/project/wifi-lora-32/)): Add `heltec` to the `--features` build flags above (as in `cargo build --features heltec`) to be greeted with a `Hello Rust!` message on the board's LED screen\n  - (Only if you happen to have an [ESP32-S3-USB-OTG](https://www.espressif.com/en/products/devkits)): Add `esp32s3_usb_otg` to the `--features` build flags above (as in `cargo build --features esp32s3_usb_otg`) to be greeted with a `Hello Rust!` message on the board's LED screen\n  - (Only if you happen to have an [Ethernet-to-SPI board based on the W5500 chip](https://www.wiznet.io/product-item/w5500/)): Add `w5500` to the `--features` build flags above (as in `cargo build --features w5500`) to have Ethernet connectivity as part of the demo\n    - Note that other Ethernet-to-SPI boards might work just fine as well, but you'll have to change the chip from `SpiEthDriver::W5500` to whatever chip your SPI board is using, in the demo code itself.\n  - (Only if you happen to have an [ESP32 board with an onboard IP101 LAN chip and/or a stock ESP32 board connected to an IP101 Ethernet board via RMII](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/hw-reference/esp32/get-started-ethernet-kit.html)): Add `ip101` to the `--features` build flags above (as in `cargo build --features ip101`) to have Ethernet connectivity as part of the demo\n    - Note that other RMII Ethernet boards might work just fine as well, but you'll have to change the chip from `RmiiEthDriver::IP101` to whatever chip your board is using, in the demo code itself.\n- (Only if you happen to have an ESP32-S2 board and can connect a LED to GPIO Pin 04 and GND): Try accessing `http://\u003cdhcp-ip-of-the-board\u003e\u003e/ulp` once build is flashed on the MCU\n\n## QEMU\n\n- Rather than flashing on the chip, you can now run the demo in QEMU:\n  - Clone and then build [the Espressif fork of QEMU](https://github.com/espressif/qemu) by following the [build instructions](https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/README.md)\n  - Uncomment `CONFIG_ETH_USE_OPENETH=y`, `CONFIG_MBEDTLS_HARDWARE_AES=n`, and `CONFIG_MBEDTLS_HARDWARE_SHA=n` in `sdkconfig.defaults.esp32` (it is not enabled by default because this somehow causes issues when compiling for the ESP32S2)\n  - Build the app with `cargo build --features qemu`\n  - NOTE: Only ESP32 is supported for the moment, so make sure that the `xtensa-esp32-espidf` target (the default one) is active in your `.cargo/config.toml` file (or override with `cargo build --features qemu --target xtensa-esp32-espidf`)\n  - Run it in QEMU by typing `./qemu.sh`. NOTE: You might have to change the `ESP_QEMU_PATH` in that script to point to the `build` subdirectory of your QEMU Espressif clone\n\n## Flash\n\n- `cargo install espflash`\n- `espflash flash -p /dev/ttyUSB0 target/[xtensa-esp32-espidf|xtensa-esp32s2-espidf|riscv32imc-esp-espidf]/debug/rust-esp32-std-demo`\n- Replace `dev/ttyUSB0` above with the USB port where you've connected the board\n\n**NOTE**: The above commands do use [`espflash`](https://crates.io/crates/espflash) and NOT [`cargo espflash`](https://crates.io/crates/cargo-espflash), even though both can be installed via Cargo. `cargo espflash` is essentially `espflash` but it has some extra superpowers, like the capability to build the project before flashing, or to generate an ESP32 .BIN file from the built .ELF image.\n\n## Alternative flashing\n\n- You can also flash with the [esptool.py](https://github.com/espressif/esptool) utility which is part of the Espressif toolset\n- Use the instructions below **only** if you have flashed successfully with `espflash` at least once, or else you might not have a valid bootloader and partition table!\n- The instructions below only (re)flash the application image, as the (one and only) factory image starting from 0x10000 in the partition table!\n- Install esptool using Python: `pip install esptool`\n- (After each cargo build) Convert the elf image to binary: `esptool.py --chip [esp32|esp32s2|esp32c3] elf2image target/xtensa-esp32-espidf/debug/rust-esp32-std-demo`\n- (After each cargo build) Flash the resulting binary: `esptool.py --chip [esp32|esp32s2|esp32c3] -p /dev/ttyUSB0 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x10000 target/xtensa-esp32-espidf/debug/rust-esp32-std-demo.bin`\n\n## Monitor\n\n- Once flashed, the board can be connected with any suitable serial monitor, e.g.:\n  - (Recommended) `espflash`: `espflash serial-monitor`\n  - Built-in Linux/MacOS screen: `screen /dev/ttyUSB0 115200` (use `Ctrl+A` and then type `:quit` to stop it)\n  - Miniterm: `miniterm --raw /dev/ttyUSB0 115200`\n\n- If the app starts successfully, it should be listening on the printed IP address from the WiFi connection logs, port 80.\n\n- Open a browser, and navigate to one of these:\n  - `http://\u003cprinted-ip-address\u003e`\n  - `http://\u003cprinted-ip-address\u003e/foo?key=value`\n  - `http://\u003cprinted-ip-address\u003e/bar`\n  - `http://\u003cprinted-ip-address\u003e/ulp` (ESP32-S2 only)\n\n- Alternatively you can connect directly to the ESP Accesspoint by connecting to the 'aptest' network using the default IP address: \n  - `http://192.168.71.1`\n\n- The monitor should output more or less the following:\n```\nHello, world from Rust!\nMore complex print [foo, bar]\nRust main thread: ...\nThis is thread number 0 ...\nThis is thread number 1 ...\nThis is thread number 2 ...\nThis is thread number 3 ...\nThis is thread number 4 ...\nAbout to join the threads. If ESP-IDF was patched successfully, joining will NOT crash\nJoins were successful.\nI (4761) wifi:wifi driver task: 3ffc1d80, prio:23, stack:6656, core=0\nI (4761) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE\nI (4761) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE\nI (4771) wifi:wifi firmware version: 3ea4c76\nI (4771) wifi:config NVS flash: disabled\nI (4781) wifi:config nano formating: disabled\nI (4781) wifi:Init dynamic tx buffer num: 32\nI (4791) wifi:Init data frame dynamic rx buffer num: 32\nI (4791) wifi:Init management frame dynamic rx buffer num: 32\nI (4801) wifi:Init management short buffer num: 32\nI (4801) wifi:Init static rx buffer size: 1600\nI (4811) wifi:Init static rx buffer num: 10\nI (4811) wifi:Init dynamic rx buffer num: 32\nI (4811) esp_idf_svc::wifi: Driver initialized\nI (4821) esp_idf_svc::wifi: Event handlers registered\nI (4821) esp_idf_svc::wifi: Initialization complete\nI (4831) rust_esp32_std_demo: Wifi created\nI (4831) esp_idf_svc::wifi: Setting configuration: Client(ClientConfiguration { ssid: \"\u003cyour-ssid\u003e\", bssid: None, auth_method: WPA2Personal, password: \"\u003cyour-pass\u003e\", ip_conf: Some(DHCP) })\nI (4851) esp_idf_svc::wifi: Stopping\nI (4861) esp_idf_svc::wifi: Disconnect requested\nI (4861) esp_idf_svc::wifi: Stop requested\nI (4871) esp_idf_svc::wifi: About to wait for status\nI (4871) esp_idf_svc::wifi: Providing status: Status(Stopped, Stopped)\nI (4881) esp_idf_svc::wifi: Waiting for status done - success\nI (4881) esp_idf_svc::wifi: Stopped\nI (4891) esp_idf_svc::wifi: Wifi mode STA set\nI (4891) esp_idf_svc::wifi: Setting STA configuration: ClientConfiguration { ssid: \"\u003cyour-ssid\u003e\", bssid: None, auth_method: WPA2Personal, password: \"\u003cyour-pass\u003e\", ip_conf: Some(DHCP) }\nI (4911) esp_idf_svc::wifi: Setting STA IP configuration: DHCP\nI (4921) esp_idf_svc::wifi: STA netif allocated: 0x3ffc685c\nI (4921) esp_idf_svc::wifi: STA IP configuration done\nI (4931) esp_idf_svc::wifi: STA configuration done\nI (4931) esp_idf_svc::wifi: Starting with status: Status(Starting, Stopped)\nI (4941) esp_idf_svc::wifi: Status is of operating type, starting\nI (5041) phy: phy_version: 4180, cb3948e, Sep 12 2019, 16:39:13, 0, 0\nI (5041) wifi:mode : sta (f0:08:d1:77:68:f0)\nI (5041) esp_idf_svc::wifi: Got wifi event: 2\nI (5051) esp_idf_svc::wifi: Recconecting\nI (5051) esp_idf_svc::wifi: Start requested\nI (5051) esp_idf_svc::wifi: Set status: Status(Started(Connecting), Stopped)\nI (5061) esp_idf_svc::wifi: About to wait for status with timeout 10s\nI (5071) esp_idf_svc::wifi: Wifi event 2 handled\nI (5091) esp_idf_svc::wifi: Providing status: Status(Started(Connecting), Stopped)\nI (5171) wifi:new:\u003c1,1\u003e, old:\u003c1,0\u003e, ap:\u003c255,255\u003e, sta:\u003c1,1\u003e, prof:1\nI (5941) wifi:state: init -\u003e auth (b0)\nI (5951) esp_idf_svc::wifi: Providing status: Status(Started(Connecting), Stopped)\nI (5951) wifi:state: auth -\u003e assoc (0)\nI (5961) wifi:state: assoc -\u003e run (10)\nI (5981) wifi:connected with muci, aid = 1, channel 1, 40U, bssid = 08:55:31:2e:c3:cf\nI (5981) wifi:security: WPA2-PSK, phy: bgn, rssi: -54\nI (5981) wifi:pm start, type: 1\n\nI (5991) esp_idf_svc::wifi: Got wifi event: 4\nI (5991) esp_idf_svc::wifi: Set status: Status(Started(Connected(Waiting)), Stopped)\nI (6001) esp_idf_svc::wifi: Wifi event 4 handled\nI (6011) wifi:AP's beacon interval = 102400 us, DTIM period = 1\nI (6451) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Waiting)), Stopped)\nI (6951) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Waiting)), Stopped)\nI (7451) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Waiting)), Stopped)\nI (7951) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Waiting)), Stopped)\nI (8221) esp_idf_svc::wifi: Got IP event: 0\nI (8221) esp_idf_svc::wifi: Set status: Status(Started(Connected(Done(ClientSettings { ip: 192.168.10.155, subnet: Subnet { gateway: 192.168.10.1, mask: Mask(24) }, dns: None, secondary_dns: None }))), Stopped)\nI (8231) esp_idf_svc::wifi: IP event 0 handled\nI (8241) esp_netif_handlers: staSTA netif allocated:  ip: 192.168.10.155, mask: 255.255.255.0, gw: 192.168.10.1\nI (8451) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Done(ClientSettings { ip: 192.168.10.155, subnet: Subnet { gateway: 192.168.10.1, mask: Mask(24) }, dns: None, secondary_dns: None }))), Stopped)\nI (8461) esp_idf_svc::wifi: Waiting for status done - success\nI (8461) esp_idf_svc::wifi: Started\nI (8471) esp_idf_svc::wifi: Configuration set\nI (8471) rust_esp32_std_demo: Wifi configuration set, about to get status\nI (8481) esp_idf_svc::wifi: Providing status: Status(Started(Connected(Done(ClientSettings { ip: 192.168.10.155, subnet: Subnet { gateway: 192.168.10.1, mask: Mask(24) }, dns: None, secondary_dns: None }))), Stopped)\nI (8501) rust_esp32_std_demo: Wifi connected, about to do some pings\nI (8511) esp_idf_svc::ping: About to run a summary ping 192.168.10.1 with configuration Configuration { count: 5, interval: 1s, timeout: 1s, data_size: 56, tos: 0 }\nI (8521) esp_idf_svc::ping: Ping session established, got handle 0x3ffc767c\nI (8531) esp_idf_svc::ping: Ping session started\nI (8531) esp_idf_svc::ping: Waiting for the ping session to complete\nI (8541) esp_idf_svc::ping: Ping success callback invoked\nI (8551) esp_idf_svc::ping: From 192.168.10.1 icmp_seq=1 ttl=64 time=14ms bytes=64\nI (9531) esp_idf_svc::ping: Ping success callback invoked\nI (9531) esp_idf_svc::ping: From 192.168.10.1 icmp_seq=2 ttl=64 time=1ms bytes=64\nI (10531) esp_idf_svc::ping: Ping success callback invoked\nI (10531) esp_idf_svc::ping: From 192.168.10.1 icmp_seq=3 ttl=64 time=2ms bytes=64\nI (11531) esp_idf_svc::ping: Ping success callback invoked\nI (11531) esp_idf_svc::ping: From 192.168.10.1 icmp_seq=4 ttl=64 time=0ms bytes=64\nI (12531) esp_idf_svc::ping: Ping success callback invoked\nI (12531) esp_idf_svc::ping: From 192.168.10.1 icmp_seq=5 ttl=64 time=1ms bytes=64\nI (13531) esp_idf_svc::ping: Ping end callback invoked\nI (13531) esp_idf_svc::ping: 5 packets transmitted, 5 received, time 18ms\nI (13531) esp_idf_svc::ping: Ping session stopped\nI (13531) esp_idf_svc::ping: Ping session 0x3ffc767c removed\nI (13541) rust_esp32_std_demo: Pinging done\nI (13551) esp_idf_svc::httpd: Started Httpd IDF server with config Configuration { http_port: 80, https_port: 443 }\nI (13561) esp_idf_svc::httpd: Registered Httpd IDF server handler Get for URI \"/\"\nI (13561) esp_idf_svc::httpd: Registered Httpd IDF server handler Get for URI \"/foo\"\nI (13571) esp_idf_svc::httpd: Registered Httpd IDF server handler Get for URI \"/bar\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivmarkov%2Frust-esp32-std-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivmarkov%2Frust-esp32-std-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivmarkov%2Frust-esp32-std-demo/lists"}