zeroclaw/src/hardware/introspect.rs
ehu shubham shaw de3ec87d16
Ehu shubham shaw contribution --> Hardware support (#306)
* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: add ZeroClaw firmware for ESP32 and Nucleo

* Introduced new firmware for ZeroClaw on ESP32 and Nucleo-F401RE, enabling JSON-over-serial communication for GPIO control.
* Added `zeroclaw-esp32` with support for commands like `gpio_read` and `gpio_write`, along with capabilities reporting.
* Implemented `zeroclaw-nucleo` firmware with similar functionality for STM32, ensuring compatibility with existing ZeroClaw protocols.
* Updated `.gitignore` to include new firmware targets and added necessary dependencies in `Cargo.toml` for both platforms.
* Created README files for both firmware projects detailing setup, build, and usage instructions.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

* feat: enhance hardware peripheral support and documentation

- Added `Peripheral` trait implementation in `src/peripherals/` to manage hardware boards (STM32, RPi GPIO).
- Updated `AGENTS.md` to include new extension points for peripherals and their configuration.
- Introduced comprehensive documentation for adding boards and tools, including a quick start guide and supported boards.
- Enhanced `Cargo.toml` to include optional dependencies for PDF extraction and peripheral support.
- Created new datasheets for Arduino Uno, ESP32, and Nucleo-F401RE, detailing pin aliases and GPIO usage.
- Implemented new tools for hardware memory reading and board information retrieval in the agent loop.

This update significantly improves the integration and usability of hardware peripherals within the ZeroClaw framework.

* feat: Introduce hardware auto-discovery and expanded configuration options for agents, hardware, and security.

* chore: update dependencies and improve probe-rs integration

- Updated `Cargo.lock` to remove specific version constraints for several dependencies, including `zerocopy`, `syn`, and `strsim`, allowing for more flexibility in version resolution.
- Upgraded `bincode` and `bitfield` to their latest versions, enhancing serialization and memory management capabilities.
- Updated `Cargo.toml` to reflect the new version of `probe-rs` from `0.24` to `0.30`, improving hardware probing functionality.
- Refactored code in `src/hardware` and `src/tools` to utilize the new `SessionConfig` for session management in `probe-rs`, ensuring better compatibility and performance.
- Cleaned up documentation in `docs/datasheets/nucleo-f401re.md` by removing unnecessary lines.

* fix: apply cargo fmt

* docs: add hardware architecture diagram.

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:40:10 -05:00

121 lines
4.1 KiB
Rust

//! Device introspection — correlate serial path with USB device info.
use super::discover;
use super::registry;
use anyhow::Result;
/// Result of introspecting a device by path.
#[derive(Debug, Clone)]
pub struct IntrospectResult {
pub path: String,
pub vid: Option<u16>,
pub pid: Option<u16>,
pub board_name: Option<String>,
pub architecture: Option<String>,
pub memory_map_note: String,
}
/// Introspect a device by its serial path (e.g. /dev/ttyACM0, /dev/tty.usbmodem*).
/// Attempts to correlate with USB devices from discovery.
#[cfg(feature = "hardware")]
pub fn introspect_device(path: &str) -> Result<IntrospectResult> {
let devices = discover::list_usb_devices()?;
// Try to correlate path with a discovered device.
// On Linux, /dev/ttyACM0 corresponds to a CDC-ACM device; we may have multiple.
// Best-effort: if we have exactly one CDC-like device, use it. Otherwise unknown.
let matched = if devices.len() == 1 {
devices.first().cloned()
} else if devices.is_empty() {
None
} else {
// Multiple devices: try to match by path. On Linux we could use sysfs;
// for stub, pick first known board or first device.
devices
.iter()
.find(|d| d.board_name.is_some())
.cloned()
.or_else(|| devices.first().cloned())
};
let (vid, pid, board_name, architecture) = match matched {
Some(d) => (Some(d.vid), Some(d.pid), d.board_name, d.architecture),
None => (None, None, None, None),
};
let board_info = vid.and_then(|v| pid.and_then(|p| registry::lookup_board(v, p)));
let architecture =
architecture.or_else(|| board_info.and_then(|b| b.architecture.map(String::from)));
let board_name = board_name.or_else(|| board_info.map(|b| b.name.to_string()));
let memory_map_note = memory_map_for_board(board_name.as_deref());
Ok(IntrospectResult {
path: path.to_string(),
vid,
pid,
board_name,
architecture,
memory_map_note,
})
}
/// Get memory map: via probe-rs when probe feature on and Nucleo, else static or stub.
#[cfg(feature = "hardware")]
fn memory_map_for_board(board_name: Option<&str>) -> String {
#[cfg(feature = "probe")]
if let Some(board) = board_name {
let chip = match board {
"nucleo-f401re" => "STM32F401RETx",
"nucleo-f411re" => "STM32F411RETx",
_ => return "Build with --features probe for live memory map (Nucleo)".to_string(),
};
match probe_memory_map(chip) {
Ok(s) => return s,
Err(_) => return format!("probe-rs attach failed (chip {}). Connect via USB.", chip),
}
}
#[cfg(not(feature = "probe"))]
let _ = board_name;
"Build with --features probe for live memory map via USB".to_string()
}
#[cfg(all(feature = "hardware", feature = "probe"))]
fn probe_memory_map(chip: &str) -> anyhow::Result<String> {
use probe_rs::config::MemoryRegion;
use probe_rs::{Session, SessionConfig};
let session = Session::auto_attach(chip, SessionConfig::default())
.map_err(|e| anyhow::anyhow!("{}", e))?;
let target = session.target();
let mut out = String::new();
for region in target.memory_map.iter() {
match region {
MemoryRegion::Ram(ram) => {
let (start, end) = (ram.range.start, ram.range.end);
out.push_str(&format!(
"RAM: 0x{:08X} - 0x{:08X} ({} KB)\n",
start,
end,
(end - start) / 1024
));
}
MemoryRegion::Nvm(flash) => {
let (start, end) = (flash.range.start, flash.range.end);
out.push_str(&format!(
"Flash: 0x{:08X} - 0x{:08X} ({} KB)\n",
start,
end,
(end - start) / 1024
));
}
_ => {}
}
}
if out.is_empty() {
out = "Could not read memory regions".to_string();
}
Ok(out)
}