Rust嵌入式开发库corepc-node的使用,高性能硬件控制与PC端节点通信解决方案

Rust嵌入式开发库corepc-node的使用,高性能硬件控制与PC端节点通信解决方案

示例代码

以下是使用corepc-node库的示例代码:

// 当启用了下载功能时,启动一个regtest节点很简单
#[cfg(feature = "download")]
{
  let node = corepc_node::Node::from_downloaded().unwrap();
  assert_eq!(0, node.client.get_blockchain_info().unwrap().blocks);
}

如果不使用自动下载功能,有以下选项:

if let Ok(exe_path) = corepc_node::exe_path() {
  let node = corepc_node::Node::new(exe_path).unwrap();
  assert_eq!(0, node.client.get_blockchain_info().unwrap().blocks);
}

完整示例

下面是一个完整的嵌入式开发示例,展示了如何使用corepc-node进行高性能硬件控制与PC端节点通信:

use corepc_node::{Node, Conf};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 配置节点参数
    let conf = Conf {
        temp_dir_root: Some("/dev/shm".into()), // 使用RAM磁盘作为临时目录
        ..Default::default()
    };

    // 启动节点
    #[cfg(feature = "download")]
    let node = Node::from_downloaded_with_conf(conf)?;
    
    #[cfg(not(feature = "download"))]
    let node = {
        let exe_path = corepc_node::exe_path()?;
        Node::with_conf(exe_path, conf)?
    };

    // 获取区块链信息
    let info = node.client.get_blockchain_info()?;
    println!("当前区块高度: {}", info.blocks);

    // 生成新区块
    node.client.generate(1)?;
    
    // 再次获取区块链信息
    let info = node.client.get_blockchain_info()?;
    println!("新区块高度: {}", info.blocks);

    // 节点会在node变量离开作用域时自动关闭
    Ok(())
}

特性

  • 等待bitcoind守护进程准备好接受RPC命令
  • 使用临时目录作为数据目录
  • 从操作系统请求空闲端口
  • 当结构体离开作用域时自动终止进程
  • 允许轻松启动依赖进程

最低支持的Rust版本(MSRV)

该库应始终能在Rust 1.63.0上编译通过。

文档构建

构建文档的命令:

RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --features download,doc --open

许可证

MIT许可证


1 回复

Rust嵌入式开发库corepc-node的使用:高性能硬件控制与PC端节点通信解决方案

完整示例demo

下面是一个完整的嵌入式设备与PC通信的示例,包含嵌入式端和PC端的代码实现:

嵌入式端完整代码 (src/main.rs)

use corepc_node::{Node, HardwareController, CommunicationProtocol, HardwareEvent, GpioPin};
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化硬件控制器
    let mut hw = HardwareController::new()?;
    
    // 配置GPIO引脚
    let led_pin = hw.configure_pin(5, GpioPin::Output)?;
    let button_pin = hw.configure_pin(6, GpioPin::Input)?;
    
    // 初始化UART通信协议
    let uart = CommunicationProtocol::uart("/dev/ttyUSB0", 115200)?;
    
    // 创建节点实例
    let mut node = Node::new(hw, uart);
    
    // 设置硬件事件处理
    node.on_event(move |event| {
        match event {
            HardwareEvent::ButtonPressed => {
                println!("Button pressed, toggling LED");
                node.hardware().write_pin(led_pin, true).unwrap();
            }
            HardwareEvent::ButtonReleased => {
                node.hardware().write_pin(led_pin, false).unwrap();
            }
            HardwareEvent::ReceivedData(data) => {
                println!("Received command: {}", data);
                match data.as_str() {
                    "LED_ON" => node.hardware().write_pin(led_pin, true).unwrap(),
                    "LED_OFF" => node.hardware().write_pin(led_pin, false).unwrap(),
                    _ => println!("Unknown command"),
                }
            }
            _ => {}
        }
    });
    
    // 启动传感器数据采集线程
    std::thread::spawn(move || loop {
        let temp = read_temperature_sensor(); // 伪代码,读取温度传感器
        node.send_data(format!("TEMP:{}", temp)).unwrap();
        std::thread::sleep(Duration::from_secs(5));
    });
    
    // 运行主节点循环
    node.run()?;
    
    Ok(())
}

// 模拟温度传感器读取
fn read_temperature_sensor() -> f32 {
    25.0 + rand::random::<f32>() * 5.0
}

PC端完整代码 (pc_client/src/main.rs)

use corepc_node::{PcNode, CommunicationProtocol};
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 初始化PC节点,使用UART协议
    let mut pc_node = PcNode::new(
        CommunicationProtocol::uart("/dev/ttyACM0", 115200)?
    );
    
    println!("PC node started, waiting for commands...");
    
    // 发送LED控制命令
    pc_node.send_command("LED_ON").await?;
    tokio::time::sleep(Duration::from_secs(2)).await;
    pc_node.send_command("LED_OFF").await?;
    
    // 创建接收数据的异步任务
    let recv_task = tokio::spawn(async move {
        loop {
            if let Ok(Some(data)) = pc_node.receive_data().await {
                println!("[Embedded Device] {}", data);
                
                // 如果收到高温警告
                if data.contains("TEMP:") {
                    let temp = data.split(':').nth(1).unwrap();
                    if let Ok(temp) = temp.parse::<f32>() {
                        if temp > 30.0 {
                            pc_node.send_command("ALARM_ON").await.unwrap();
                        }
                    }
                }
            }
            tokio::time::sleep(Duration::from_millis(100)).await;
        }
    });
    
    // 主循环处理用户输入
    loop {
        println!("Enter command (LED_ON/LED_OFF/QUIT):");
        let mut input = String::new();
        std::io::stdin().read_line(&mut input).unwrap();
        
        match input.trim() {
            "LED_ON" => pc_node.send_command("LED_ON").await?,
            "LED_OFF" => pc_node.send_command("LED_OFF").await?,
            "QUIT" => break,
            _ => println!("Unknown command"),
        }
    }
    
    recv_task.abort();
    Ok(())
}

项目结构说明

/rust_embedded_project
├── Cargo.toml            # 嵌入式项目配置
├── .cargo
│   └── config.toml       # 交叉编译配置
├── src
│   ├── main.rs           # 嵌入式主程序
│   ├── hardware.rs       # 硬件抽象层
│   └── protocol.rs       # 通信协议实现
└── pc_client
    ├── Cargo.toml        # PC客户端配置
    └── src
        └── main.rs       # PC客户端程序

Cargo.toml 配置示例

嵌入式端:

[package]
name = "embedded-app"
version = "0.1.0"
edition = "2021"

[dependencies]
corepc-node = "0.3.0"
rand = "0.8"  # 用于模拟温度传感器数据

PC端:

[package]
name = "pc-client"
version = "0.1.0"
edition = "2021"

[dependencies]
corepc-node = "0.3.0"
tokio = { version = "1.0", features = ["full"] }

功能说明

  1. 嵌入式端功能:

    • 控制GPIO引脚(LED和按钮)
    • 处理来自PC的命令
    • 定期发送传感器数据
    • 响应硬件事件(按钮按下/释放)
  2. PC端功能:

    • 发送控制命令到嵌入式设备
    • 接收并处理传感器数据
    • 用户交互界面
    • 高温报警功能

这个完整示例展示了corepc-node库在实际项目中的应用,包括硬件控制、双向通信、异步处理和错误处理等核心功能。

回到顶部