Repository navigation
Copper Application Overview
This page shows a minimal Copper application: a task graph definition in RON and the Rust code that implements a simple task and runtime.
(
tasks: [
(
id: "src",
type: "FlippingSource",
),
(
id: "gpio",
type: "cu_rp_gpio::RPGpio",
config: {
"pin": 4,
},
),
],
cnx: [
(src: "src", dst: "gpio", msg: "cu_rp_gpio::RPGpioMsg"),
],
)use std::path::PathBuf;
use cu29::prelude::*;
#[copper_runtime(config = "copperconfig.ron")]
struct MyApplication {}
pub struct FlippingSource {
state: bool,
}
impl CuSrcTask for FlippingSource {
type Output<'m> = output_msg!(RPGpioPayload);
fn new(config: Option<&copper::config::ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
{
Ok(Self { state: true })
}
fn process(&mut self, clock: &RobotClock, output: &mut Self::Output<'_>) -> CuResult<()> {
self.state = !self.state;
output.set_payload(RPGpioPayload {
on: self.state,
creation: Some(clock.now()).into(),
actuation: Some(clock.now()).into(),
});
Ok(())
}
}
fn main() {
let logger_path = "/tmp/mylogfile.copper";
debug!("Creating application... ");
let mut application = MyApplication::builder()
.with_log_path(logger_path, Some(10 * 1024 * 1024))
.expect("Failed to setup logger.")
.build()
.expect("Failed to create runtime.");
debug!("Running... starting clock: {}.", application.clock().now());
application.run().expect("Failed to run application.");
debug!("End of program: {}.", application.clock().now());
}Enable cu29/self-describing-logs and use the ordinary application builder.
During construction, before resource initialization, Copper serializes native
encoding descriptions for every compiled mission and saves one compressed catalog
in static log metadata. Matching appended runs reuse it. The catalog and application
metadata survive byte-addressed rollover; data sections identify their run,
instance and mission, so surviving CopperLists remain decodable after startup
markers rotate out.
The producer supports no_std and uses bounded memory for startup compression.
Native payload encoding retains its existing recording pass. Host readers enable
cu29/decode-catalog for allocated value trees. Use the standalone CLI's catalog,
extract-copperlists and fsck --deep commands, or its Python API, to inspect logs.
Expose the feature in your application's Cargo.toml:
[features]
self-describing-logs = ["cu29/self-describing-logs"]Record with cargo run --features self-describing-logs. From a Copper checkout,
inspect the resulting log with:
just logextract logs/app.copper catalog
just logextract logs/app.copper extract-copperlists --export-format jsonl
just logextract logs/app.copper fsck --deepFor a deeper explanation of task lifecycle hooks and scheduling, see Task Lifecycle.
Start
- Home
- Copper Book
- Release Notes
- Project Templates
- Copper Application Overview
- Build and Deploy a Copper Application
- Copper Configuration file Reference
- Task Automation with just
Concepts
- Copper Runtime Overview
- Copper Configuration and Mission Visualization
- Copper Tasks lifecycle overview
- Copper Bridge concept
- Resources
- Modular Configuration
Embedded
Reference
- Reading Unified Logs
- Self-describing logs
- Remote Debugging
- SDK Features
- Copper Component Catalog
- FAQ
External