Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move probe-rs chip name into boards/*.toml, remove scary matches #1903

Merged
merged 2 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions boards/donglet-g030.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32G030F6Px"
3 changes: 3 additions & 0 deletions boards/donglet-g031.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[probe-rs]
chip-name = "STM32G031F8Px"

2 changes: 2 additions & 0 deletions boards/gemini-bu-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimlet-b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimlet-c.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimlet-d.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimlet-e.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimlet-f.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimletlet-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/gimletlet-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/grapefruit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/lpcxpresso55s69.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "LPC55S69JBD100"
2 changes: 2 additions & 0 deletions boards/medusa-a.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/nucleo-h743zi2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H743ZITx"
2 changes: 2 additions & 0 deletions boards/nucleo-h753zi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/oxcon2023g0.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32G030J6Mx"
2 changes: 2 additions & 0 deletions boards/oxide-rot-1-selfsigned.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "LPC55S69JBD100"
2 changes: 2 additions & 0 deletions boards/oxide-rot-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "LPC55S69JBD100"
2 changes: 2 additions & 0 deletions boards/psc-b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/psc-c.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/rot-carrier-1.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "LPC55S28JBD100"
2 changes: 2 additions & 0 deletions boards/rot-carrier-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "LPC55S69JBD100"
2 changes: 2 additions & 0 deletions boards/sidecar-b.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/sidecar-c.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/sidecar-d.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32H753ZITx"
2 changes: 2 additions & 0 deletions boards/stm32f3-discovery.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32F303VCTx"
2 changes: 2 additions & 0 deletions boards/stm32f4-discovery.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32F407VGTx"
2 changes: 2 additions & 0 deletions boards/stm32g031-nucleo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32G031Y8Yx"
2 changes: 2 additions & 0 deletions boards/stm32g070-nucleo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "STM32G070KBTx"
14 changes: 14 additions & 0 deletions build/xtask/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,3 +800,17 @@ fn read_and_flatten_toml(
merge_toml_documents(&mut original, doc)?;
Ok(original)
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct BoardConfig {
/// Info about how to interact with this board using probe-rs.
pub probe_rs: Option<ProbeRsBoardConfig>,
}

#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct ProbeRsBoardConfig {
/// The "chip name" used by probe-rs for flashing.
pub chip_name: String,
}
6 changes: 2 additions & 4 deletions build/xtask/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub const DEFAULT_KERNEL_STACK: u32 = 1024;
/// that generates the Humility binary necessary for Hubris's CI has run.
/// Once that binary is in place, you should be able to bump this version
/// without breaking CI.
const HUBRIS_ARCHIVE_VERSION: u32 = 8;
const HUBRIS_ARCHIVE_VERSION: u32 = 9;

/// `PackageConfig` contains a bundle of data that's commonly used when
/// building a full app image, grouped together to avoid passing a bunch
Expand Down Expand Up @@ -872,10 +872,8 @@ fn build_archive(
// any external configuration files, serialize it, and add it to the
// archive.
//
if let Some(mut config) =
crate::flash::config(cfg.toml.board.as_str(), &chip_dir)?
{
config.flatten()?;
let config = crate::flash::config(&cfg.toml.board)?;
archive.text(
img_dir.join("flash.ron"),
ron::ser::to_string_pretty(
Expand Down
250 changes: 31 additions & 219 deletions build/xtask/src/flash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,236 +2,48 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use anyhow::Context as _;
use serde::Serialize;
use std::path::{Path, PathBuf};
use std::path::Path;

//
// We allow for enough information to be put in the archive for the image to
// be flashed based only on the archive (e.g., by Humility). Because flashing
// is itself a bit of a mess (requiring different programs for different
// targets), this is a bit gritty (e.g., any required external configuration
// files must themselves put in the archive). If these structures need to
// change, be sure to make corresponding changes to Humility.
//
#[derive(Debug, Serialize)]
pub enum FlashProgram {
PyOcd(Vec<FlashArgument>),
OpenOcd(FlashProgramConfig),
}

//
// Enum describing flash programs configuration (e.g., "openocd.cfg" for
// OpenOCD), either as a path in the file system or with the entire contents.
//
#[derive(Debug, Serialize)]
pub enum FlashProgramConfig {
Path(PathBuf),
Payload(String),
}

//
// An enum describing a single command-line argument to the flash program.
//
#[derive(Debug, Serialize)]
pub enum FlashArgument {
// A direct string
Direct(String),

// The filesystem path of the binary flash payload itself
Payload,
use crate::config::BoardConfig;

// A single argument consisting of a prefix and a suffix. When the
// argument is processed, a single argument should be generated consisting
// of the prefix, the path of the flash, and the suffix, all joined by
// spaces.
FormattedPayload(String, String),

// The filesystem path of the flash program configuration
Config,
}

#[derive(Debug, Serialize)]
#[derive(Debug, Serialize, Default)]
pub struct FlashConfig {
/// The name used by probe-rs to identify the chip.
chip: Option<String>,
program: FlashProgram,
args: Vec<FlashArgument>,
}

impl FlashProgramConfig {
fn new(path: PathBuf) -> Self {
FlashProgramConfig::Path(path)
}
pub fn config(board: &str) -> anyhow::Result<FlashConfig> {
Ok(FlashConfig {
chip: chip_name(board)?,
})
}

impl FlashConfig {
fn new(program: FlashProgram) -> Self {
FlashConfig {
chip: None,
program,
args: vec![],
}
}
pub fn chip_name(board: &str) -> anyhow::Result<Option<String>> {
let board_config_path = Path::new("boards").join(format!("{board}.toml"));

//
// Add a command-line argument to the flash program
//
fn arg<'a>(&'a mut self, val: &str) -> &'a mut Self {
self.args.push(FlashArgument::Direct(val.to_string()));
self
}
let board_config_text = std::fs::read_to_string(&board_config_path)
.with_context(|| {
format!(
"can't access board config at: {}",
board_config_path.display()
)
})?;

//
// Set the chip
//
fn set_chip(&mut self, val: &str) -> &mut Self {
self.chip = Some(val.to_string());
self
}

//
// Add the path to the payload as an argument to the flash program
//
fn payload(&mut self) -> &mut Self {
self.args.push(FlashArgument::Payload);
self
}
let board_config: BoardConfig = toml::from_str(&board_config_text)
.with_context(|| {
format!(
"can't parse board config at: {}",
board_config_path.display()
)
})?;

//
// Add a formatted payload as a single argument to the flash program. The
// argument will consists of the specified prefix, followed by the path to
// the payload, followed by the specified suffix.
//
fn formatted_payload<'a>(
&'a mut self,
prefix: &str,
suffix: &str,
) -> &'a mut Self {
self.args.push(FlashArgument::FormattedPayload(
prefix.to_string(),
suffix.to_string(),
));
self
if let Some(probe_rs) = &board_config.probe_rs {
Ok(Some(probe_rs.chip_name.clone()))
} else {
// tolerate the section missing for new chips, but we can't provide a
// chip name in this case.
Ok(None)
}

//
// Add a flasher configuration file as an argument to the flash program
//
fn config(&mut self) -> &mut Self {
self.args.push(FlashArgument::Config);
self
}

//
// Slurp in any flash program configuration file and flatten it into
// our overall configuration
//
pub fn flatten(&mut self) -> anyhow::Result<()> {
if let FlashProgram::OpenOcd(FlashProgramConfig::Path(path)) =
&self.program
{
let p: PathBuf = path.iter().collect();
let text = std::fs::read_to_string(p)?;
self.program =
FlashProgram::OpenOcd(FlashProgramConfig::Payload(text));
}

Ok(())
}
}

pub fn config(
board: &str,
chip_dir: &Path,
) -> anyhow::Result<Option<FlashConfig>> {
let mut flash = match board {
"lpcxpresso55s69"
| "rot-carrier-1"
| "rot-carrier-2"
| "oxide-rot-1"
| "oxide-rot-1-selfsigned" => {
let chip = if board == "rot-carrier-1" {
"lpc55s28"
} else {
"lpc55s69"
};

let mut args = vec![];

for arg in ["reset", "-t", chip].iter() {
args.push(FlashArgument::Direct(arg.to_string()));
}

let mut flash = FlashConfig::new(FlashProgram::PyOcd(args));

flash
.arg("flash")
.arg("-t")
.arg(chip)
.arg("--format")
.arg("hex")
.payload();

flash
}

"stm32f3-discovery" | "stm32f4-discovery" | "nucleo-h743zi2"
| "nucleo-h753zi" | "gemini-bu-1" | "gimletlet-1" | "gimletlet-2"
| "gimlet-b" | "gimlet-c" | "gimlet-d" | "gimlet-e" | "gimlet-f"
| "psc-b" | "psc-c" | "sidecar-b" | "sidecar-c" | "sidecar-d"
| "stm32g031-nucleo" | "donglet-g030" | "donglet-g031"
| "oxcon2023g0" | "stm32g070-nucleo" | "stm32g0b1-nucleo"
| "medusa-a" | "grapefruit" => {
let cfg = FlashProgramConfig::new(chip_dir.join("openocd.cfg"));

let mut flash = FlashConfig::new(FlashProgram::OpenOcd(cfg));

flash
.arg("-f")
.config()
.arg("-c")
.formatted_payload("program", "verify reset")
.arg("-c")
.arg("exit");

flash
}
_ => {
eprintln!("Warning: unrecognized board, won't know how to flash.");
return Ok(None);
}
};

flash.set_chip(chip_name(board)?);

Ok(Some(flash))
}

pub fn chip_name(board: &str) -> anyhow::Result<&'static str> {
let b = match board {
"lpcxpresso55s69"
| "rot-carrier-2"
| "oxide-rot-1"
| "oxide-rot-1-selfsigned" => "LPC55S69JBD100",
"rot-carrier-1" => "LPC55S28JBD100",
"stm32f3-discovery" => "STM32F303VCTx",
"stm32f4-discovery" => "STM32F407VGTx",
"nucleo-h743zi2" => "STM32H743ZITx",
"nucleo-h753zi" => "STM32H753ZITx",
"gemini-bu-1" | "gimletlet-1" | "gimletlet-2" | "gimlet-b"
| "gimlet-c" | "gimlet-d" | "gimlet-e" | "gimlet-f" | "psc-a"
| "psc-b" | "psc-c" | "sidecar-b" | "sidecar-c" | "sidecar-d"
| "medusa-a" | "grapefruit" => "STM32H753ZITx",
"donglet-g030" => "STM32G030F6Px",
"donglet-g031" => "STM32G031F8Px",
"stm32g031-nucleo" => "STM32G031Y8Yx",
"oxcon2023g0" => "STM32G030J6Mx",
"stm32g070-nucleo" => "STM32G070KBTx",
"stm32g0b1-nucleo" => anyhow::bail!(
"This board is not yet supported by probe-rs, \
please use OpenOCD directly"
),
_ => anyhow::bail!("unrecognized board {}", board),
};

Ok(b)
}
Loading