Provides unsafe, non-realtime Rust bindings for the LinuxCNC hal
module. Useful for writing drivers for external hardware.
For a safe, high-level interface see the linuxcnc-hal
crate.
bash
cargo add linuxcnc-hal-sys
Please consider becoming a sponsor so I may continue to maintain this crate in my spare time!
| This crate | LinuxCNC version | | --------------------------------------------------------- | ---------------------------------------------------------- | | v0.1.6 | v2.7.15 |
More examples can be found in the examples/
folder.
```rust,norun use linuxcnchalsys::*; use signalhook::iterator::Signals; use std::{ffi::CString, mem, thread, time::Duration};
unsafe { let ret = halinit(CString::new("pins").unwrap().asptr() as *const i8);
// Check that component was created successfully
let component_id = match ret {
x if x == -(EINVAL as i32) => panic!("Failed to initialise component"),
x if x == -(ENOMEM as i32) => panic!("Not enough memory to initialise component"),
id if id > 0 => id,
code => unreachable!("Hit unreachable error code {}", code),
};
println!("Component registered with ID {}", component_id);
let signals = Signals::new(&[signal_hook::SIGTERM, signal_hook::SIGINT]).unwrap();
let storage = hal_malloc(mem::size_of::<f64>() as i64) as *mut *mut f64;
if storage.is_null() {
panic!("Failed to allocate storage");
}
let pin_name = CString::new("pins.input-1").unwrap();
let ret = hal_pin_float_new(
pin_name.as_ptr() as *const i8,
hal_pin_dir_t_HAL_IN,
storage,
component_id,
);
// Check that pin was registered successfully
match ret {
0 => println!("Pin registered successfully"),
x if x == -(EINVAL as i32) => panic!("Failed to register pin"),
x if x == -(EPERM as i32) => {
panic!("HAL is locked. Register pins before calling hal_ready()`")
}
x if x == -(ENOMEM as i32) => panic!("Failed to register pin"),
code => unreachable!("Hit unreachable error code {}", code),
}
let ret = hal_ready(component_id);
// Check that component is ready
match ret {
0 => println!("Component is ready"),
x if x == -(EINVAL as i32) => panic!("HAL component was not found or is already ready"),
code => unreachable!("Hit unreachable error code {}", code),
}
while !signals.pending().any(|signal| match signal {
signal_hook::SIGTERM | signal_hook::SIGINT | signal_hook::SIGKILL => true,
_ => false,
}) {
println!("Input {:?}", **storage);
thread::sleep(Duration::from_millis(500));
}
} ```
bindgen
must be set up correctly. Follow the requirements section of its docs.
To run and debug any HAL components, the LinuxCNC simulator can be set up. There's a guide here for Linux Mint (and other Debian derivatives).
bash
cargo build
You can also run ./build.sh
to run all the commands that would normally be run in CI.
bash
cargo test
The docs make heavy use of intra-rustdoc-links. To get the links to render correctly, run with nightly:
bash
rustup toolchain add nightly
cargo +nightly doc
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.