From 9cfc02340b50a2296ba23c36eb38ab1859daaeb2 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Oct 2024 18:22:37 +0200 Subject: [PATCH 1/5] Added usb serial communication --- Cargo.lock | 55 +++++++++++++++++++++++++++++--------------- firmware/src/main.rs | 6 ++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index beda8fd..a179a36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,9 +123,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", @@ -204,9 +204,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.50" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "shlex", @@ -565,6 +565,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "fern" version = "0.7.1" @@ -577,9 +587,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "form_urlencoded" @@ -905,9 +915,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" @@ -1247,9 +1257,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" [[package]] name = "postcard" @@ -1301,9 +1311,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -1514,9 +1524,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "scopeguard" @@ -1577,15 +1587,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.146" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -1639,10 +1649,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -2337,3 +2348,9 @@ checksum = "df94495e7f28d551b72b2bf5304267fbb0075d78b182b49fbfb74f8910d63fec" dependencies = [ "embedded-hal 1.0.0", ] + +[[package]] +name = "zmij" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d6085d62852e35540689d1f97ad663e3971fc19cf5eceab364d62c646ea167" diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 71f9a63..4738239 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -47,6 +47,9 @@ mod app { use radomctl_protocol::{HostMessage, *}; use crate::bootloader; + + use radomctl_protocol::*; + use rtic_monotonics::systick::prelude::*; systick_monotonic!(Mono, 4000); @@ -101,8 +104,6 @@ mod app { Mono::start(cx.core.SYST, rcc.clocks.sysclk().to_Hz()); - defmt::info!("Clock Setup done"); - // Acquire the GPIO peripherials let gpioa = cx.device.GPIOA.split(&mut rcc); let gpiob = cx.device.GPIOB.split(&mut rcc); @@ -159,7 +160,6 @@ mod app { .unwrap() .build() }; - defmt::info!("USB Setup done"); // Todo: Check if internal pullups work here From 72bf0d87930ee2404eca255150c560f2b1fc0b12 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Oct 2024 22:54:05 +0200 Subject: [PATCH 2/5] Triggering the dfu bootloader works --- Cargo.lock | 73 +++++++++++++++++++++++++++++++++++ daemon/Cargo.toml | 7 +++- daemon/src/bin/trigger-dfu.rs | 16 ++++++++ daemon/src/main.rs | 6 ++- firmware/src/bootloader.rs | 18 ++++++--- firmware/src/main.rs | 37 ++++++------------ memory.x | 16 +++++++- 7 files changed, 137 insertions(+), 36 deletions(-) create mode 100644 daemon/src/bin/trigger-dfu.rs diff --git a/Cargo.lock b/Cargo.lock index a179a36..8eb3a32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1118,6 +1118,15 @@ dependencies = [ "nom", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num" version = "0.4.3" @@ -1395,6 +1404,8 @@ dependencies = [ "tokio-serial", "tokio-util", "tower-http", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1641,6 +1652,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1821,6 +1841,15 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "time" version = "0.3.44" @@ -1959,9 +1988,21 @@ checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -1969,6 +2010,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -2059,6 +2126,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcell" version = "0.1.3" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 2cda2bc..79b7d20 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -14,8 +14,6 @@ serde_json = "1.0.118" serialport = "4.5.1" tokio = {version = "1.37.0", features = ["full"]} tower-http = { version = "0.6.8", features = ["fs", "trace"] } -radomctl-protocol = { path = "../protocol" } -postcard = {version = "1.0.10", features = ["use-std"]} dfu-libusb = "0.5.5" rusb = "0.9" clap = { version = "4.5.19", features = ["derive"] } @@ -25,3 +23,8 @@ tokio-util = { version = "0.7.13", features = ["codec", "rt"] } bytes = "1.9.0" futures = "0.3.31" nom-language = "0.1.0" +tracing = "0.1.40" +tracing-subscriber = "0.3.18" +radomctl-protocol = { path = "../protocol" } +postcard = {version = "1.0.10", features = ["use-std"]} + diff --git a/daemon/src/bin/trigger-dfu.rs b/daemon/src/bin/trigger-dfu.rs new file mode 100644 index 0000000..472f081 --- /dev/null +++ b/daemon/src/bin/trigger-dfu.rs @@ -0,0 +1,16 @@ +use std::time::Duration; + +use postcard::{from_bytes_cobs, to_stdvec_cobs}; +use radomctl_protocol::*; +use radomctld::logger::setup_logger; + +pub fn main() -> () { + let mut port = serialport::new("/dev/ttyACM0", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open port"); + + let host_msg = HostMessage::TriggerDFUBootloader; + let msg_bytes = to_stdvec_cobs(&host_msg).unwrap(); + port.write_all(&msg_bytes).unwrap(); +} diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 29f94a2..c4aad25 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -12,13 +12,17 @@ use tokio::{ task::JoinSet, }; use tokio_serial; -use tower_http::{services::ServeFile, trace::TraceLayer}; use radomctld::{ logger::setup_logger, rotctlprotocol::{parse_command, Command}, rotor::control_rotor, }; +use tower_http::{ + services::{ServeDir, ServeFile}, + trace::TraceLayer, +}; + async fn process_socket( socket: TcpStream, diff --git a/firmware/src/bootloader.rs b/firmware/src/bootloader.rs index c186b18..0c87fe3 100644 --- a/firmware/src/bootloader.rs +++ b/firmware/src/bootloader.rs @@ -1,5 +1,5 @@ use core::mem::MaybeUninit; - +use core::ptr::addr_of_mut; use stm32f4xx_hal::pac; fn jump_to_bootloader() { @@ -23,19 +23,25 @@ fn jump_to_bootloader() { const BOOTLOADER_REQUESTED: u32 = 0xdecafbad; -#[link_section = ".uninit.DFU_FLAG"] -static mut DFU_FLAG: MaybeUninit = MaybeUninit::uninit(); +fn magic_mut_ptr() -> *mut u32 { + extern "C" { + #[link_name = "_dfu_magic"] + static mut magic: u32; + } + + unsafe { addr_of_mut!(magic) } +} fn get_bootloader_flag() -> u32 { - unsafe { DFU_FLAG.assume_init() } + unsafe { magic_mut_ptr().read_volatile() } } fn set_bootloader_flag() { - unsafe { DFU_FLAG.write(BOOTLOADER_REQUESTED) }; + unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; } fn clear_bootloader_flag() { - unsafe { DFU_FLAG.write(0) }; + unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; } pub fn init() { diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 4738239..a651168 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -23,10 +23,15 @@ mod app { use as5048a::AS5048A; + use crate::bootloader; use core::fmt::Write; use heapless::{String, Vec}; use num_traits::{Float, FloatConst}; use postcard::{from_bytes_cobs, to_vec_cobs}; + use qmc5883l::{self, QMC5883L}; + use radomctl_protocol::*; + use radomctl_protocol::{HostMessage, *}; + use rtic_monotonics::systick::prelude::*; use stm32f4xx_hal::{ gpio::{gpioa, gpiob, gpioc, Output, PushPull}, i2c, @@ -39,20 +44,9 @@ mod app { use usb_device::prelude::*; use usb_device::{class_prelude::UsbBusAllocator, device}; use usbd_serial::SerialPort; - use xca9548a::{SlaveAddr, Xca9548a}; - use qmc5883l::{self, QMC5883L}; - - use radomctl_protocol::{HostMessage, *}; - - use crate::bootloader; - - use radomctl_protocol::*; - - use rtic_monotonics::systick::prelude::*; - - systick_monotonic!(Mono, 4000); + systick_monotonic!(Mono, 1000); const USB_BUFFER_SIZE: usize = 64; @@ -104,6 +98,8 @@ mod app { Mono::start(cx.core.SYST, rcc.clocks.sysclk().to_Hz()); + defmt::info!("Clock Setup done"); + // Acquire the GPIO peripherials let gpioa = cx.device.GPIOA.split(&mut rcc); let gpiob = cx.device.GPIOB.split(&mut rcc); @@ -132,22 +128,11 @@ mod app { let usb_serial = usbd_serial::SerialPort::new(unsafe { USB_BUS.as_ref().unwrap() }); - let serial = unsafe { - let u_id0 = 0x1FFF_7A10 as *const u32; - let u_id2 = 0x1FFF_7A18 as *const u32; - - defmt::debug!("UID0: {:x}", u_id0.read()); - defmt::debug!("UID2: {:x}", u_id2.read()); - - // See https://community.st.com/t5/stm32-mcus-products/usb-bootloader-serial-number/td-p/432148 - (u_id0.read() as u64 + u_id2.read() as u64) << 16 - | (u_id2.read() as u64 & 0xFF00) >> 8 - | (u_id2.read() as u64 & 0x00FF) << 8 - }; + let uid = signature::Uid::get(); static mut SERIAL: String<16> = String::new(); unsafe { - write!(SERIAL, "{:X}", serial).unwrap(); + write!(SERIAL, "{}{:x}{:x}", uid.lot_num(), uid.x(), uid.y()).unwrap(); } let usb_dev = unsafe { @@ -177,7 +162,7 @@ mod app { defmt::info!("I2C Setup done"); let mut i2cmux = Xca9548a::new(i2c, SlaveAddr::default()); - i2cmux.select_channels(0b0000_0001).unwrap(); + //i2cmux.select_channels(0b0000_0001).unwrap(); defmt::info!("I2C MUX Setup done"); diff --git a/memory.x b/memory.x index 78b279a..33fd2a3 100644 --- a/memory.x +++ b/memory.x @@ -1,9 +1,23 @@ MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 256K - RAM : ORIGIN = 0x20000000, LENGTH = 64K + UNINIT : ORIGIN = 0x20000000, LENGTH = 0x10 + RAM : ORIGIN = 0x20000010, LENGTH = 64K - LENGTH(UNINIT) } +SECTIONS { + .uninit_flags (NOLOAD) : ALIGN(4) + { + . = ALIGN(4); + __suninit_flags = .; + _dfu_magic = .; . += 4; + *(.uninit_flags .uninit_flags.*) + . = ALIGN(4); + __euninit_flags = .; + } > UNINIT +} + + /* This is where the call stack will be allocated. */ /* The stack is of the full descending type. */ /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ From 523338dfc90a3321abc1a9ddd24995dee34b5253 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 28 Dec 2025 13:07:42 +0100 Subject: [PATCH 3/5] Fixed memory layout to avoid running into segfaults --- firmware/src/bootloader.rs | 18 ++++++------------ memory.x | 16 +--------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/firmware/src/bootloader.rs b/firmware/src/bootloader.rs index 0c87fe3..c186b18 100644 --- a/firmware/src/bootloader.rs +++ b/firmware/src/bootloader.rs @@ -1,5 +1,5 @@ use core::mem::MaybeUninit; -use core::ptr::addr_of_mut; + use stm32f4xx_hal::pac; fn jump_to_bootloader() { @@ -23,25 +23,19 @@ fn jump_to_bootloader() { const BOOTLOADER_REQUESTED: u32 = 0xdecafbad; -fn magic_mut_ptr() -> *mut u32 { - extern "C" { - #[link_name = "_dfu_magic"] - static mut magic: u32; - } - - unsafe { addr_of_mut!(magic) } -} +#[link_section = ".uninit.DFU_FLAG"] +static mut DFU_FLAG: MaybeUninit = MaybeUninit::uninit(); fn get_bootloader_flag() -> u32 { - unsafe { magic_mut_ptr().read_volatile() } + unsafe { DFU_FLAG.assume_init() } } fn set_bootloader_flag() { - unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; + unsafe { DFU_FLAG.write(BOOTLOADER_REQUESTED) }; } fn clear_bootloader_flag() { - unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; + unsafe { DFU_FLAG.write(0) }; } pub fn init() { diff --git a/memory.x b/memory.x index 33fd2a3..78b279a 100644 --- a/memory.x +++ b/memory.x @@ -1,23 +1,9 @@ MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 256K - UNINIT : ORIGIN = 0x20000000, LENGTH = 0x10 - RAM : ORIGIN = 0x20000010, LENGTH = 64K - LENGTH(UNINIT) + RAM : ORIGIN = 0x20000000, LENGTH = 64K } -SECTIONS { - .uninit_flags (NOLOAD) : ALIGN(4) - { - . = ALIGN(4); - __suninit_flags = .; - _dfu_magic = .; . += 4; - *(.uninit_flags .uninit_flags.*) - . = ALIGN(4); - __euninit_flags = .; - } > UNINIT -} - - /* This is where the call stack will be allocated. */ /* The stack is of the full descending type. */ /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ From 524ed8f2c69a31270b406eeaee08e91ac5f3f436 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 3 Oct 2024 22:54:05 +0200 Subject: [PATCH 4/5] Triggering the dfu bootloader works --- Cargo.lock | 73 +++++++++++++++++++++++++++++++++++ daemon/Cargo.toml | 7 +++- daemon/src/bin/trigger-dfu.rs | 16 ++++++++ daemon/src/main.rs | 6 ++- firmware/src/bootloader.rs | 18 ++++++--- firmware/src/main.rs | 20 +++------- memory.x | 16 +++++++- 7 files changed, 131 insertions(+), 25 deletions(-) create mode 100644 daemon/src/bin/trigger-dfu.rs diff --git a/Cargo.lock b/Cargo.lock index beda8fd..8f2ca00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1108,6 +1108,15 @@ dependencies = [ "nom", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num" version = "0.4.3" @@ -1385,6 +1394,8 @@ dependencies = [ "tokio-serial", "tokio-util", "tower-http", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1631,6 +1642,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1810,6 +1830,15 @@ dependencies = [ "syn 2.0.111", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "time" version = "0.3.44" @@ -1948,9 +1977,21 @@ checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -1958,6 +1999,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", ] [[package]] @@ -2048,6 +2115,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcell" version = "0.1.3" diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 2cda2bc..79b7d20 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -14,8 +14,6 @@ serde_json = "1.0.118" serialport = "4.5.1" tokio = {version = "1.37.0", features = ["full"]} tower-http = { version = "0.6.8", features = ["fs", "trace"] } -radomctl-protocol = { path = "../protocol" } -postcard = {version = "1.0.10", features = ["use-std"]} dfu-libusb = "0.5.5" rusb = "0.9" clap = { version = "4.5.19", features = ["derive"] } @@ -25,3 +23,8 @@ tokio-util = { version = "0.7.13", features = ["codec", "rt"] } bytes = "1.9.0" futures = "0.3.31" nom-language = "0.1.0" +tracing = "0.1.40" +tracing-subscriber = "0.3.18" +radomctl-protocol = { path = "../protocol" } +postcard = {version = "1.0.10", features = ["use-std"]} + diff --git a/daemon/src/bin/trigger-dfu.rs b/daemon/src/bin/trigger-dfu.rs new file mode 100644 index 0000000..472f081 --- /dev/null +++ b/daemon/src/bin/trigger-dfu.rs @@ -0,0 +1,16 @@ +use std::time::Duration; + +use postcard::{from_bytes_cobs, to_stdvec_cobs}; +use radomctl_protocol::*; +use radomctld::logger::setup_logger; + +pub fn main() -> () { + let mut port = serialport::new("/dev/ttyACM0", 115_200) + .timeout(Duration::from_millis(10)) + .open() + .expect("Failed to open port"); + + let host_msg = HostMessage::TriggerDFUBootloader; + let msg_bytes = to_stdvec_cobs(&host_msg).unwrap(); + port.write_all(&msg_bytes).unwrap(); +} diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 29f94a2..c4aad25 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -12,13 +12,17 @@ use tokio::{ task::JoinSet, }; use tokio_serial; -use tower_http::{services::ServeFile, trace::TraceLayer}; use radomctld::{ logger::setup_logger, rotctlprotocol::{parse_command, Command}, rotor::control_rotor, }; +use tower_http::{ + services::{ServeDir, ServeFile}, + trace::TraceLayer, +}; + async fn process_socket( socket: TcpStream, diff --git a/firmware/src/bootloader.rs b/firmware/src/bootloader.rs index c186b18..0c87fe3 100644 --- a/firmware/src/bootloader.rs +++ b/firmware/src/bootloader.rs @@ -1,5 +1,5 @@ use core::mem::MaybeUninit; - +use core::ptr::addr_of_mut; use stm32f4xx_hal::pac; fn jump_to_bootloader() { @@ -23,19 +23,25 @@ fn jump_to_bootloader() { const BOOTLOADER_REQUESTED: u32 = 0xdecafbad; -#[link_section = ".uninit.DFU_FLAG"] -static mut DFU_FLAG: MaybeUninit = MaybeUninit::uninit(); +fn magic_mut_ptr() -> *mut u32 { + extern "C" { + #[link_name = "_dfu_magic"] + static mut magic: u32; + } + + unsafe { addr_of_mut!(magic) } +} fn get_bootloader_flag() -> u32 { - unsafe { DFU_FLAG.assume_init() } + unsafe { magic_mut_ptr().read_volatile() } } fn set_bootloader_flag() { - unsafe { DFU_FLAG.write(BOOTLOADER_REQUESTED) }; + unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; } fn clear_bootloader_flag() { - unsafe { DFU_FLAG.write(0) }; + unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; } pub fn init() { diff --git a/firmware/src/main.rs b/firmware/src/main.rs index 71f9a63..cc5eaee 100644 --- a/firmware/src/main.rs +++ b/firmware/src/main.rs @@ -27,6 +27,8 @@ mod app { use heapless::{String, Vec}; use num_traits::{Float, FloatConst}; use postcard::{from_bytes_cobs, to_vec_cobs}; + use radomctl_protocol::*; + use rtic_monotonics::systick::prelude::*; use stm32f4xx_hal::{ gpio::{gpioa, gpiob, gpioc, Output, PushPull}, i2c, @@ -39,7 +41,6 @@ mod app { use usb_device::prelude::*; use usb_device::{class_prelude::UsbBusAllocator, device}; use usbd_serial::SerialPort; - use xca9548a::{SlaveAddr, Xca9548a}; use qmc5883l::{self, QMC5883L}; @@ -131,22 +132,11 @@ mod app { let usb_serial = usbd_serial::SerialPort::new(unsafe { USB_BUS.as_ref().unwrap() }); - let serial = unsafe { - let u_id0 = 0x1FFF_7A10 as *const u32; - let u_id2 = 0x1FFF_7A18 as *const u32; - - defmt::debug!("UID0: {:x}", u_id0.read()); - defmt::debug!("UID2: {:x}", u_id2.read()); - - // See https://community.st.com/t5/stm32-mcus-products/usb-bootloader-serial-number/td-p/432148 - (u_id0.read() as u64 + u_id2.read() as u64) << 16 - | (u_id2.read() as u64 & 0xFF00) >> 8 - | (u_id2.read() as u64 & 0x00FF) << 8 - }; + let uid = signature::Uid::get(); static mut SERIAL: String<16> = String::new(); unsafe { - write!(SERIAL, "{:X}", serial).unwrap(); + write!(SERIAL, "{}{:x}{:x}", uid.lot_num(), uid.x(), uid.y()).unwrap(); } let usb_dev = unsafe { @@ -177,7 +167,7 @@ mod app { defmt::info!("I2C Setup done"); let mut i2cmux = Xca9548a::new(i2c, SlaveAddr::default()); - i2cmux.select_channels(0b0000_0001).unwrap(); + //i2cmux.select_channels(0b0000_0001).unwrap(); defmt::info!("I2C MUX Setup done"); diff --git a/memory.x b/memory.x index 78b279a..33fd2a3 100644 --- a/memory.x +++ b/memory.x @@ -1,9 +1,23 @@ MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 256K - RAM : ORIGIN = 0x20000000, LENGTH = 64K + UNINIT : ORIGIN = 0x20000000, LENGTH = 0x10 + RAM : ORIGIN = 0x20000010, LENGTH = 64K - LENGTH(UNINIT) } +SECTIONS { + .uninit_flags (NOLOAD) : ALIGN(4) + { + . = ALIGN(4); + __suninit_flags = .; + _dfu_magic = .; . += 4; + *(.uninit_flags .uninit_flags.*) + . = ALIGN(4); + __euninit_flags = .; + } > UNINIT +} + + /* This is where the call stack will be allocated. */ /* The stack is of the full descending type. */ /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */ From 24b46a5fff2f25a6ce362d6003093baef03290d0 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 28 Dec 2025 13:07:42 +0100 Subject: [PATCH 5/5] Fixed memory layout to avoid running into segfaults --- firmware/src/bootloader.rs | 18 ++++++------------ memory.x | 16 +--------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/firmware/src/bootloader.rs b/firmware/src/bootloader.rs index 0c87fe3..c186b18 100644 --- a/firmware/src/bootloader.rs +++ b/firmware/src/bootloader.rs @@ -1,5 +1,5 @@ use core::mem::MaybeUninit; -use core::ptr::addr_of_mut; + use stm32f4xx_hal::pac; fn jump_to_bootloader() { @@ -23,25 +23,19 @@ fn jump_to_bootloader() { const BOOTLOADER_REQUESTED: u32 = 0xdecafbad; -fn magic_mut_ptr() -> *mut u32 { - extern "C" { - #[link_name = "_dfu_magic"] - static mut magic: u32; - } - - unsafe { addr_of_mut!(magic) } -} +#[link_section = ".uninit.DFU_FLAG"] +static mut DFU_FLAG: MaybeUninit = MaybeUninit::uninit(); fn get_bootloader_flag() -> u32 { - unsafe { magic_mut_ptr().read_volatile() } + unsafe { DFU_FLAG.assume_init() } } fn set_bootloader_flag() { - unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; + unsafe { DFU_FLAG.write(BOOTLOADER_REQUESTED) }; } fn clear_bootloader_flag() { - unsafe { magic_mut_ptr().write_volatile(BOOTLOADER_REQUESTED) }; + unsafe { DFU_FLAG.write(0) }; } pub fn init() { diff --git a/memory.x b/memory.x index 33fd2a3..78b279a 100644 --- a/memory.x +++ b/memory.x @@ -1,23 +1,9 @@ MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 256K - UNINIT : ORIGIN = 0x20000000, LENGTH = 0x10 - RAM : ORIGIN = 0x20000010, LENGTH = 64K - LENGTH(UNINIT) + RAM : ORIGIN = 0x20000000, LENGTH = 64K } -SECTIONS { - .uninit_flags (NOLOAD) : ALIGN(4) - { - . = ALIGN(4); - __suninit_flags = .; - _dfu_magic = .; . += 4; - *(.uninit_flags .uninit_flags.*) - . = ALIGN(4); - __euninit_flags = .; - } > UNINIT -} - - /* This is where the call stack will be allocated. */ /* The stack is of the full descending type. */ /* NOTE Do NOT modify `_stack_start` unless you know what you are doing */