feature/espflash2 #1

Merged
hibas123 merged 11 commits from feature/espflash2 into main 2024-01-17 22:02:46 +00:00
7 changed files with 1864 additions and 952 deletions

70
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,70 @@
---
name: Continuous Integration
on:
push:
branches:
- main
paths-ignore:
- "**/README.md"
- "**/release.yml"
pull_request:
paths-ignore:
- "**/README.md"
- "**/release.yml"
env:
CARGO_TERM_COLOR: always
jobs:
cargo-checks:
name: CI checks
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
action:
- command: build
args: --release
- command: fmt
args: --all -- --check
- command: clippy
args: --all-targets --all-features --workspace -- -D warnings
- command: doc
args: --no-deps --document-private-items --all-features --workspace --examples
- command: publish
args: --dry-run
steps:
- name: Install dependencies
run: |
sudo sed -i 's/azure.archive.ubuntu.com/archive.ubuntu.com/' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libudev-dev
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Enable caching
uses: Swatinem/rust-cache@v2
- name: Cargo command
run: cargo ${{ matrix.action.command }} ${{ matrix.action.args }}
msrv:
name: MSRV check
runs-on: ubuntu-20.04
steps:
- name: Install dependencies
run: |
sudo sed -i 's/azure.archive.ubuntu.com/archive.ubuntu.com/' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install musl-tools libudev-dev
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.65.0
- name: Enable caching
uses: Swatinem/rust-cache@v2
- name: Cargo check
run: cargo check

View File

@ -45,6 +45,7 @@ jobs:
- name: Install dependencies - name: Install dependencies
if: matrix.job.os == 'ubuntu-20.04' if: matrix.job.os == 'ubuntu-20.04'
run: | run: |
sudo sed -i 's/azure.archive.ubuntu.com/archive.ubuntu.com/' /etc/apt/sources.list
sudo apt-get update sudo apt-get update
sudo apt-get install libudev-dev librust-libudev-sys-dev pkg-config sudo apt-get install libudev-dev librust-libudev-sys-dev pkg-config

2438
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,26 @@
[package] [package]
name = "web-flash" name = "web-flash"
version = "0.2.1" version = "0.2.2"
edition = "2021" edition = "2021"
description = "A web server to flash Espressif devices given an ELF file."
rust-version = "1.65"
authors = [
"Björn Quentin <bjoern.quentin@mobile-j.de>",
"Sergio Gasquez Arcos <sergio.gasquez@gmail.com>",
"Fabian Stamm <dev@fabianstamm.de>",
]
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/esp-rs/esp-web-flash-server"
keywords = ["cli", "embedded", "esp"]
categories = ["command-line-utilities", "development-tools", "embedded"]
[dependencies] [dependencies]
rocket = "0.5.0-rc.2" rocket = "0.5"
espflash = { rev = "55bce336c6718c1c7f019e4da718f97c8cdf1b95", git = "https://github.com/esp-rs/espflash" } espflash = "2.1"
clap = { version = "4.1.4", features = ["env", "derive"] } esp-idf-part = "0.4"
opener = "0.5.2" clap = { version = "4", features = ["env", "derive"] }
anyhow = "1.0.69" opener = "0.6"
anyhow = "1"
xmas-elf = "0.9"

View File

@ -1,20 +1,42 @@
# esp-web-flash-server # web-flash
Starts a local server serving a web page to flash a given ELF file. Starts a local server serving a web page to flash a given ELF file.
## Installation
``` ```
web-flash 0.1.0 cargo install web-flash
```
USAGE: ## Usage
web-flash.exe [OPTIONS] --chip <CHIP> <ELF> ```
Usage: web-flash [OPTIONS] --chip <CHIP> <ELF>
ARGS:
<ELF> Arguments:
<ELF>
OPTIONS: Path to the ELF file
-b, --bootloader <BOOTLOADER> path to bootloader
-c, --chip <CHIP> chip name Options:
-h, --help Print help information -c, --chip <CHIP>
-p, --partition-table <PARTITION_TABLE> path to partition table csv Chip name
-V, --version Print version information
Possible values:
- esp32: ESP32
- esp32c2: ESP32-C2, ESP8684
- esp32c3: ESP32-C3, ESP8685
- esp32c6: ESP32-C6
- esp32s2: ESP32-S2
- esp32s3: ESP32-S3
- esp32h2: ESP32-H2
- esp8266: ESP8266
-b, --bootloader <BOOTLOADER>
Path to bootloader
-p, --partition-table <PARTITION_TABLE>
Path to partition table CSV
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version
``` ```

5
Rocket.toml Normal file
View File

@ -0,0 +1,5 @@
[default.shutdown]
ctrlc = true
signals = ["term", "hup"]
grace = 5
mercy = 4

View File

@ -3,7 +3,8 @@ use anyhow::Result;
use std::{path::PathBuf, time::Duration}; use std::{path::PathBuf, time::Duration};
use clap::Parser; use clap::Parser;
use espflash::{elf::FirmwareImageBuilder, Chip, FlashSize, PartitionTable}; use esp_idf_part::PartitionTable;
use espflash::{elf::ElfFirmwareImage, flasher::FlashSize::_4Mb, targets::Chip};
use rocket::{response::content, State}; use rocket::{response::content, State};
#[macro_use] #[macro_use]
@ -12,18 +13,19 @@ extern crate rocket;
#[derive(Parser, Debug, Clone)] #[derive(Parser, Debug, Clone)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
struct Args { struct Args {
/// chip name /// Chip name
#[arg(short, long)] #[clap(short, long)]
chip: Chip, chip: Chip,
/// path to bootloader /// Path to bootloader
#[arg(short, long)] #[clap(short, long)]
bootloader: Option<PathBuf>, bootloader: Option<PathBuf>,
/// path to partition table csv /// Path to partition table CSV
#[arg(short, long)] #[clap(short, long)]
partition_table: Option<PathBuf>, partition_table: Option<PathBuf>,
/// Path to the ELF file
elf: PathBuf, elf: PathBuf,
} }
@ -47,6 +49,19 @@ fn index() -> content::RawHtml<&'static str> {
content::RawHtml( content::RawHtml(
" "
<html> <html>
<head>
<style>
body {
background-color: #cdcdcd;
font-family: Arial, Helvetica, sans-serif;
color: #343434;
}
h1 {
margin-left: 40px;
}
</style>
</head>
<body> <body>
<center> <center>
<h1>ESP Web Flasher</h1> <h1>ESP Web Flasher</h1>
@ -54,11 +69,13 @@ fn index() -> content::RawHtml<&'static str> {
<div id=\"main\" style=\"display: none;\"> <div id=\"main\" style=\"display: none;\">
<br> <br>
<script type=\"module\" src=\"https://unpkg.com/esp-web-tools@8.0.2/dist/web/install-button.js?module\"> <script type=\"module\" src=\"https://unpkg.com/esp-web-tools@9.4.3/dist/web/install-button.js?module\">
</script> </script>
<esp-web-install-button id=\"installButton\" manifest=\"manifest.json\"></esp-web-install-button> <esp-web-install-button id=\"installButton\" manifest=\"manifest.json\"></esp-web-install-button>
<br> <br>
<span><i>NOTE: Make sure to close anything using your devices com port (e.g. Serial monitor)</i></span> <br>
<br>
<span><i>NOTE: Make sure to close anything using your device's com port (e.g. serial monitor)</i></span>
</div> </div>
<div id=\"notSupported\" style=\"display: none;\"> <div id=\"notSupported\" style=\"display: none;\">
Your browser does not support the Web Serial API. Try Chrome Your browser does not support the Web Serial API. Try Chrome
@ -90,72 +107,123 @@ fn manifest() -> content::RawJson<&'static str> {
"new_install_prompt_erase": true, "new_install_prompt_erase": true,
"builds": [ "builds": [
{ {
"chipFamily": "ESP32", "chipFamily": "ESP32",
"parts": [ "parts": [
{ {
"path": "bootloader.bin", "path": "bootloader.bin",
"offset": 4096 "offset": 4096
}, },
{ {
"path": "partitions.bin", "path": "partitions.bin",
"offset": 32768 "offset": 32768
}, },
{ {
"path": "firmware.bin", "path": "firmware.bin",
"offset": 65536 "offset": 65536
} }
] ]
}, },
{ {
"chipFamily": "ESP32-C3", "chipFamily": "ESP32-C2",
"parts": [ "parts": [
{ {
"path": "bootloader.bin", "path": "bootloader.bin",
"offset": 0 "offset": 0
}, },
{ {
"path": "partitions.bin", "path": "partitions.bin",
"offset": 32768 "offset": 32768
}, },
{ {
"path": "firmware.bin", "path": "firmware.bin",
"offset": 65536 "offset": 65536
} }
] ]
}, },
{ {
"chipFamily": "ESP32-S2", "chipFamily": "ESP32-C3",
"parts": [ "parts": [
{ {
"path": "bootloader.bin", "path": "bootloader.bin",
"offset": 4096 "offset": 0
}, },
{ {
"path": "partitions.bin", "path": "partitions.bin",
"offset": 32768 "offset": 32768
}, },
{ {
"path": "firmware.bin", "path": "firmware.bin",
"offset": 65536 "offset": 65536
} }
] ]
}, },
{ {
"chipFamily": "ESP32-S3", "chipFamily": "ESP32-C6",
"parts": [ "parts": [
{ {
"path": "bootloader.bin", "path": "bootloader.bin",
"offset": 0 "offset": 0
}, },
{ {
"path": "partitions.bin", "path": "partitions.bin",
"offset": 32768 "offset": 32768
}, },
{ {
"path": "firmware.bin", "path": "firmware.bin",
"offset": 65536 "offset": 65536
} }
] ]
},
{
"chipFamily": "ESP32-H2",
"parts": [
{
"path": "bootloader.bin",
"offset": 0
},
{
"path": "partitions.bin",
"offset": 32768
},
{
"path": "firmware.bin",
"offset": 65536
}
]
},
{
"chipFamily": "ESP32-S2",
"parts": [
{
"path": "bootloader.bin",
"offset": 4096
},
{
"path": "partitions.bin",
"offset": 32768
},
{
"path": "firmware.bin",
"offset": 65536
}
]
},
{
"chipFamily": "ESP32-S3",
"parts": [
{
"path": "bootloader.bin",
"offset": 0
},
{
"path": "partitions.bin",
"offset": 32768
},
{
"path": "firmware.bin",
"offset": 65536
}
]
} }
] ]
} }
@ -164,7 +232,7 @@ fn manifest() -> content::RawJson<&'static str> {
} }
struct PartsData { struct PartsData {
chip: String, _chip: String,
bootloader: Vec<u8>, bootloader: Vec<u8>,
partitions: Vec<u8>, partitions: Vec<u8>,
firmware: Vec<u8>, firmware: Vec<u8>,
@ -174,6 +242,7 @@ fn prepare() -> Result<PartsData> {
let opts = Args::parse(); let opts = Args::parse();
let elf = std::fs::read(opts.elf)?; let elf = std::fs::read(opts.elf)?;
let elf = xmas_elf::ElfFile::new(&elf).expect("Invalid elf file");
let p = if let Some(p) = &opts.partition_table { let p = if let Some(p) = &opts.partition_table {
Some(PartitionTable::try_from_bytes(std::fs::read(p)?)?) Some(PartitionTable::try_from_bytes(std::fs::read(p)?)?)
@ -187,9 +256,7 @@ fn prepare() -> Result<PartsData> {
None None
}; };
let firmware = FirmwareImageBuilder::new(&elf) let firmware = ElfFirmwareImage::new(elf);
.flash_size(Some(FlashSize::Flash4Mb)) // TODO make configurable
.build()?;
let chip = opts.chip; let chip = opts.chip;
let chip_name = match chip { let chip_name = match chip {
@ -198,16 +265,22 @@ fn prepare() -> Result<PartsData> {
Chip::Esp32s2 => "ESP32-S2", Chip::Esp32s2 => "ESP32-S2",
Chip::Esp32s3 => "ESP32-S3", Chip::Esp32s3 => "ESP32-S3",
Chip::Esp8266 => "ESP8266", Chip::Esp8266 => "ESP8266",
Chip::Esp32c2 => "ESP32-C2",
Chip::Esp32c6 => "ESP32-C6",
Chip::Esp32h2 => "ESP32-H2",
_ => panic!("Unsupported chip"),
}; };
let image = chip.get_flash_image(&firmware, b, p, None, None)?; let image =
chip.into_target()
.get_flash_image(&firmware, b, p, None, None, None, Some(_4Mb), None)?;
let parts: Vec<_> = image.flash_segments().collect(); let parts: Vec<_> = image.flash_segments().collect();
let bootloader = &parts[0]; let bootloader = &parts[0];
let partitions = &parts[1]; let partitions = &parts[1];
let app = &parts[2]; let app = &parts[2];
Ok(PartsData { Ok(PartsData {
chip: chip_name.to_string(), _chip: chip_name.to_string(),
bootloader: bootloader.data.to_vec(), bootloader: bootloader.data.to_vec(),
partitions: partitions.data.to_vec(), partitions: partitions.data.to_vec(),
firmware: app.data.to_vec(), firmware: app.data.to_vec(),