diff --git a/Cargo.lock b/Cargo.lock index 877ce74..dbba0ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,21 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" +dependencies = [ + "git2", +] + [[package]] name = "byteorder" version = "1.3.4" @@ -74,6 +89,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + [[package]] name = "cfg-if" version = "0.1.10" @@ -90,6 +115,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "const-str" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3618cccc083bb987a415d85c02ca6c9994ea5b44731ec28b9ecf09658655fba9" + [[package]] name = "cortex-m" version = "0.6.7" @@ -204,6 +235,15 @@ dependencies = [ "void", ] +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -232,6 +272,19 @@ dependencies = [ "version_check", ] +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.4.2", + "libc", + "libgit2-sys", + "log", + "url", +] + [[package]] name = "hash32" version = "0.1.1" @@ -254,12 +307,61 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + [[package]] name = "libm" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a" +[[package]] +name = "libz-sys" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "log" version = "0.4.11" @@ -342,6 +444,18 @@ dependencies = [ "cortex-m-semihosting", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + [[package]] name = "postcard" version = "0.5.1" @@ -469,7 +583,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e4a069bef843d170df47e7c0a8bf8d037f217d9f5b325865acc3e466ffe40d3" dependencies = [ - "bitflags", + "bitflags 1.2.1", "byteorder", "log", "managed", @@ -553,7 +667,9 @@ version = "0.0.0" dependencies = [ "bare-metal 1.0.0", "bit_field", + "built", "byteorder", + "const-str", "cortex-m 0.6.7", "cortex-m-log", "cortex-m-rt 0.6.13", @@ -576,12 +692,42 @@ dependencies = [ "usbd-serial", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "typenum" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-xid" version = "0.2.1" @@ -599,6 +745,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "usb-device" version = "0.2.7" @@ -622,6 +779,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876e32dcadfe563a4289e994f7cb391197f362b6315dc45e8ba4aa6f564a4b3c" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index 4775d89..2117b6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,10 @@ serde = { version = "1.0", default-features = false, features = ["derive"] } heapless = "0.5" serde-json-core = "0.1" sfkv = "0.1" +const-str = { version = "0.5.7" } + +[build-dependencies] +built = { version = "0.7", features = ["git2"] } [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/README.md b/README.md index 3e37ccf..7a19f09 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ formatted as line-delimited JSON. | `fcurve ` | Set fan controller curve coefficients (see *Fan control* section) | | `fcurve default` | Set fan controller curve coefficients to defaults (see *Fan control* section) | | `hwrev` | Show hardware revision, and settings related to it | +| `version` | Show firmware version | ## USB diff --git a/build.rs b/build.rs index 98f603e..c701e95 100644 --- a/build.rs +++ b/build.rs @@ -15,4 +15,6 @@ fn main() { // Only re-run the build script when memory.x is changed, // instead of when any part of the source code changes. println!("cargo:rerun-if-changed=memory.x"); + + built::write_built_file().expect("Failed to acquire build-time information"); } diff --git a/flake.nix b/flake.nix index eafafa2..fdc59cc 100644 --- a/flake.nix +++ b/flake.nix @@ -42,6 +42,7 @@ nativeBuildInputs = [ pkgs.llvm ]; + NIX_DRV_DIRTY_REV = "${toString (self.rev or self.dirtyRev or "unknown")}"; buildPhase = '' cargo build --release --bin thermostat ''; diff --git a/src/command_handler.rs b/src/command_handler.rs index 31f3dcd..ed5cc7b 100644 --- a/src/command_handler.rs +++ b/src/command_handler.rs @@ -6,6 +6,7 @@ use super::{ }, config::ChannelConfig, dfu, + firmware_ver, flash_store::FlashStore, hw_rev::HWRev, net, FanCtrl, CHANNEL_CONFIG_KEY, @@ -42,6 +43,10 @@ pub enum Error { Flash, } +mod built_info { + include!(concat!(env!("OUT_DIR"), "/built.rs")); +} + pub type JsonBuffer = Vec; fn send_line(socket: &mut TcpSocket, data: &[u8]) -> bool { @@ -463,6 +468,20 @@ impl Handler { } } + fn show_firmware_version(socket: &mut TcpSocket) -> Result { + match firmware_ver::summary() { + Ok(buf) => { + send_line(socket, &buf); + Ok(Handler::Handled) + } + Err(e) => { + error!("unable to serialize FirmwareVer summary: {:?}", e); + let _ = writeln!(socket, "{{\"error\":\"{:?}\"}}", e); + Err(Error::Report) + } + } + } + pub fn handle_command( command: Command, socket: &mut TcpSocket, @@ -523,6 +542,7 @@ impl Handler { } Command::FanCurveDefaults => Handler::fan_defaults(socket, fan_ctrl), Command::ShowHWRev => Handler::show_hwrev(socket, hwrev), + Command::ShowFirmwareVer => Handler::show_firmware_version(socket), } } } diff --git a/src/command_parser.rs b/src/command_parser.rs index b923e51..ae9bfd1 100644 --- a/src/command_parser.rs +++ b/src/command_parser.rs @@ -194,6 +194,7 @@ pub enum Command { }, FanCurveDefaults, ShowHWRev, + ShowFirmwareVer, } fn end(input: &[u8]) -> IResult<&[u8], ()> { @@ -578,6 +579,7 @@ fn command(input: &[u8]) -> IResult<&[u8], Result> { fan, fan_curve, value(Ok(Command::ShowHWRev), tag("hwrev")), + value(Ok(Command::ShowFirmwareVer), tag("version")), ))(input) } @@ -867,4 +869,10 @@ mod test { let command = Command::parse(b"hwrev"); assert_eq!(command, Ok(Command::ShowHWRev)); } + + #[test] + fn parse_firmware_ver() { + let command = Command::parse(b"version"); + assert_eq!(command, Ok(Command::ShowFirmwareVer)); + } } diff --git a/src/firmware_ver.rs b/src/firmware_ver.rs new file mode 100644 index 0000000..c150441 --- /dev/null +++ b/src/firmware_ver.rs @@ -0,0 +1,44 @@ +use crate::command_handler::JsonBuffer; +use serde::Serialize; + +mod built_info { + include!(concat!(env!("OUT_DIR"), "/built.rs")); +} + +#[derive(Serialize)] +pub struct FirmwareSummary { + git_hash: Option<&'static str>, + git_dirty: Option, +} + +impl FirmwareSummary { + pub const fn get() -> FirmwareSummary { + if let Some(rev) = option_env!("NIX_DRV_DIRTY_REV") { + if const_str::equal!(rev, "unknown") { + FirmwareSummary { + git_hash: None, + git_dirty: None, + } + } else if const_str::ends_with!(rev, "-dirty") { + FirmwareSummary { + git_hash: const_str::strip_suffix!(rev, "-dirty"), + git_dirty: Some(true), + } + } else { + FirmwareSummary { + git_hash: Some(rev), + git_dirty: Some(false), + } + } + } else { + FirmwareSummary { + git_hash: built_info::GIT_COMMIT_HASH, + git_dirty: built_info::GIT_DIRTY, + } + } + } +} + +pub fn summary() -> Result { + serde_json_core::to_vec(&FirmwareSummary::get()) +} diff --git a/src/main.rs b/src/main.rs index aa07c0a..9daeb92 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,7 @@ mod flash_store; use command_handler::Handler; mod fan_ctrl; use fan_ctrl::FanCtrl; +mod firmware_ver; mod hw_rev; const HSE: MegaHertz = MegaHertz(8);