Quick start: Hello world

Let us create a simple program which contains a single worker. The worker has got a 1-ms cycle and prints a number of cycles elapsed every 10k cycles.

Creating a new Rust project

If Rust is not installed yet, install it using instructions from https://www.rust-lang.org/tools/install

Then install RoboPLC CLI:

cargo install roboplc-cli

And create a new RoboPLC project:

robo new hello

The Rust project is ready. Its Cargo.toml should look like:

[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
roboplc = "0.1"
tracing = { version = "0.1", features = ["log"] }

The tracing crate is added by default for logging. It is not a mandatory thing, the logging can be done in any other preferred way.

Program code

The file src/main.rs contains the default code for the new project. Modify the function run of the Worker1 to look like:

fn run(&mut self, _context: &Context<(), ()>) -> WResult {
    for (cycles, _) in roboplc::time::interval(Duration::from_millis(1)).enumerate() {
        if cycles % 10_000 == 0 {
            tracing::info!(cycles, worker = self.worker_name(), "stats");
        }
    }
    Ok(())
}

The full code should look like:

use roboplc::controller::prelude::*;
use roboplc::prelude::*;

const SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);

type Message = ();
type Variables = ();

#[derive(WorkerOpts)]
#[worker_opts(cpu = 0, priority = 50, scheduling = "fifo", blocking = true)]
struct Worker1 {}

impl Worker<Message, Variables> for Worker1 {
    fn run(&mut self, _context: &Context<(), ()>) -> WResult {
        for (cycles, _) in roboplc::time::interval(Duration::from_millis(1)).enumerate() {
            if cycles % 10_000 == 0 {
                tracing::info!(cycles, worker = self.worker_name(), "stats");
            }
        }
        Ok(())
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    roboplc::setup_panic();
    roboplc::configure_logger(roboplc::LevelFilter::Info);
    if !roboplc::is_production() {
        roboplc::thread_rt::set_simulated();
    }
    roboplc::thread_rt::prealloc_heap(10_000_000)?;
    let mut controller = Controller::<Message, Variables>::new();
    controller.spawn_worker(Worker1 {})?;
    controller.register_signals(SHUTDOWN_TIMEOUT)?;
    controller.block();
    Ok(())
}

Configuring the remote

How we need to prepare the remote (a board, an industrial computer etc.) to run the program. To do this, see Configuring the system section.

Flashing

Modify the file robo.toml in the project root directory with the following content:

[remote]
url = "http://IP:7700"
key = "roboplc"

where IP is the remote IP address.

Then execute:

robo flash --run

The tool will do all the necessary steps to build the program and to flash the binary to the remote. The program on the remote machine will be started automatically.

See more: Flashing.