6个版本
0.3.0 | 2022年11月15日 |
---|---|
0.2.0 | 2021年1月6日 |
0.1.3 | 2020年1月29日 |
#676 in 硬件支持
220KB
4.5K SLoC
LinuxCNC HAL接口用于Rust
请考虑成为赞助者,以便我在业余时间继续维护这个crate!
文档
LinuxCNC HAL (硬件抽象层)模块的安全、高级接口。
对于低级、不安全的用法,请参阅linuxcnc-hal-sys
crate。
开发环境搭建
要运行和调试任何HAL组件,可以设置LinuxCNC模拟器。这里有Linux Mint(及其他Debian衍生版)的指南在此。
项目设置
此crate依赖于linuxcnc-hal-sys
crate,该crate需要将LINUXCNC_SRC
环境变量设置为正确的值以正确生成C绑定。该值必须是LinuxCNC源代码根目录的绝对路径。
LinuxCNC源代码的版本必须与机器控制中使用的LinuxCNC版本相匹配。
# Clone LinuxCNC source code into linuxcnc/
git clone https://github.com/LinuxCNC/linuxcnc.git
# Check out a specific version tag. This may also be a commit, but must match the version in use by the machine control.
cd linuxcnc && git checkout v2.8.0 && cd ..
# Create your component lib
cargo new --lib my_comp
cd my_comp
# Add LinuxCNC HAL bindings as a Cargo dependency with cargo-edit
cargo add linuxcnc-hal
LINUXCNC_SRC=/path/to/linuxcnc/source/code cargo build
如果LinuxCNC配置为原地运行,则在启动时可能找不到liblinuxcnchal.so.0
。为了修复,请尝试使用例如export LD_LIBRARY_PATH=~/Repositories/linuxcnc/lib
设置库路径。
示例
创建具有输入和输出的组件
此示例创建了一个名为"pins"
的组件,该组件具有单个输入("input-1"
)和输出引脚("output-1"
)。它进入一个无限循环,每秒更新output-1
的值。LinuxCNC约定组件和引脚名称应该是连字符式
。
此示例可以用类似的.hal
文件加载到LinuxCNC中,如下所示
loadusr -W /path/to/your/component/target/debug/comp_bin_name
net input-1 spindle.0.speed-out pins.input-1
net output-1 pins.output-1
引脚和其他资源使用 Resources
特性进行注册。本例创建了一个 Pins
结构体,该结构体包含两个引脚。 HalComponent::new
处理组件创建、资源(引脚、信号等)初始化以及 UNIX 信号处理程序注册。
use linuxcnc_hal::{
error::PinRegisterError,
hal_pin::{InputPin, OutputPin},
prelude::*,
HalComponent, RegisterResources, Resources,
};
use std::{
error::Error,
thread,
time::{Duration, Instant},
};
struct Pins {
input_1: InputPin<f64>,
output_1: OutputPin<f64>,
}
impl Resources for Pins {
type RegisterError = PinRegisterError;
fn register_resources(comp: &RegisterResources) -> Result<Self, Self::RegisterError> {
Ok(Pins {
input_1: comp.register_pin::<InputPin<f64>>("input-1")?,
output_1: comp.register_pin::<OutputPin<f64>>("output-1")?,
})
}
}
fn main() -> Result<(), Box<dyn Error>> {
rtapi_logger::init();
// Create a new HAL component called `rust-comp`
let comp: HalComponent<Pins> = HalComponent::new("rust-comp")?;
// Get a reference to the `Pins` struct
let pins = comp.resources();
let start = Instant::now();
// Main control loop
while !comp.should_exit() {
let time = start.elapsed().as_secs() as i32;
// Set output pin to elapsed seconds since component started
pins.output_1.set_value(time.into())?;
// Print the current value of the input pin
println!("Input: {:?}", pins.input_1.value());
// Sleep for 1000ms. This should be a lower time if the component needs to update more
// frequently.
thread::sleep(Duration::from_millis(1000));
}
// The custom implementation of `Drop` for `HalComponent` ensures that `hal_exit()` is called
// at this point. Registered signal handlers are also deregistered.
Ok(())
}
许可证
许可方式如下:
- Apache 许可证 2.0 版(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确表示,否则根据 Apache-2.0 许可证定义的,您有意提交并包含在本作品中的任何贡献,都将按照上述方式双许可,不附加任何额外条款或条件。
依赖项
~0.5–2.7MB
~55K SLoC