#serde #framing #cobs

no-std postcard-rpc

适用于 Rust 的 no_std + serde 兼容的 RPC 库

12 个版本 (5 个重大变更)

0.6.0 2024年7月29日
0.5.1 2024年6月14日
0.4.0 2024年2月23日
0.3.1 2023年11月26日

#371嵌入式开发

Download history 142/week @ 2024-05-18 16/week @ 2024-05-25 2/week @ 2024-06-01 92/week @ 2024-06-08 62/week @ 2024-06-15 1/week @ 2024-06-22 84/week @ 2024-07-06 302/week @ 2024-07-13 332/week @ 2024-07-20 271/week @ 2024-07-27 148/week @ 2024-08-03 156/week @ 2024-08-10 121/week @ 2024-08-17

每月下载量 726
erdnuss-comms 中使用

MIT/Apache

125KB
2.5K SLoC

Postcard RPC

用于处理 RPC 风格的请求-响应类型的宿主(PC)和客户端(MCU)库。

请参阅 overview.md 以获取文档。

请参阅 postcard-rpc 书籍 以获取示例教程。

您还可以观看 James 的 RustNL 谈话,了解此软件包的功能。

许可证

许可协议为以下之一

任选其一。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义,您提交的任何有意包含在作品中的贡献,将按上述方式双重许可,不附加任何额外条款或条件。


lib.rs:

Postcard RPC 的目标是使主机 PC 与受限设备(如微控制器)通信更加容易。

请参阅 仓库 中的示例,以及 概述 以获取更多关于如何使用此软件包的详细信息。

定义架构

通常,您将在共享架构软件包中定义您的 "线类型"。该软件包本质上定义了两个或多个设备之间使用的协议。

架构包含几个必要的项目

线类型

我们需要定义我们将在协议中使用的所有类型。我们指定正常 Rust 类型,这些类型需要实现或推导三个重要的特质

  • serde's Serialize 特质 - 定义了如何将类型转换为线上的字节
  • 《serde》库中的 Deserialize 特性 - 该特性定义了如何将线上的字节转换为一种类型。
  • 《postcard》库中的 Schema 特性 - 该特性为给定的类型生成一个反射式模式值。

以下是我们将在未来示例中使用的三个类型的示例。

// Consider making your shared "wire types" crate conditionally no-std,
// if you want to use it with no-std embedded targets! This makes it no_std
// except for testing and when the "use-std" feature is active.
//
// You may need to also ensure that `std`/`use-std` features are not active
// in any dependencies as well.
#![cfg_attr(not(any(test, feature = "use-std")), no_std)]

use serde::{Serialize, Deserialize};
use postcard::experimental::schema::Schema;

#[derive(Serialize, Deserialize, Schema)]
pub struct Alpha {
    pub one: u8,
    pub two: i64,
}

#[derive(Serialize, Deserialize, Schema)]
pub enum Beta {
    Bib,
    Bim(i16),
    Bap,
}

#[derive(Serialize, Deserialize, Schema)]
pub struct Delta(pub [u8; 32]);

#[derive(Serialize, Deserialize, Schema)]
pub enum WireError {
    ALittleBad,
    VeryBad,
}

端点

现在我们有一些将在线上使用的基本类型,我们需要开始构建我们的协议。我们首先可以构建的是 [Endpoint](端点),它表示一个双向的 "请求"/"响应" 关系。我们的一个设备将充当客户端(发出请求并接收响应),另一个设备将充当服务器(接收请求并发送响应)。每个请求都应该由恰好一个响应(最终)跟随。

一个端点包括

  • 请求的类型
  • 响应的类型
  • 一个字符串 "路径",类似于 HTTP URI,唯一标识该端点。

定义端点最简单的方法是使用 [endpoint!][endpoint] 宏。

#
#
#
use postcard_rpc::endpoint;

// Define an endpoint
endpoint!(
    // This is the name of a marker type that represents our Endpoint,
    // and implements the `Endpoint` trait.
    FirstEndpoint,
    // This is the request type for this endpoint
    Alpha,
    // This is the response type for this endpoint
    Beta,
    // This is the path/URI of the endpoint
    "endpoints/first",
);

主题

有时,你只想在单一方向上发送数据,不期望有响应。这可能是因为异步日志记录、定期盲目发送传感器数据或其他任何你能想到的原因。

主题没有 "客户端" 或 "服务器" 角色,任何设备都可以决定在特定主题上发送消息。

一个主题包括

  • 消息的类型
  • 一个字符串 "路径",类似于 HTTP URI,唯一标识该主题。

定义主题最简单的方法是使用 [topic!][topic] 宏。

#
#
use postcard_rpc::topic;

// Define a topic
topic!(
    // This is the name of a marker type that represents our Topic,
    // and implements `Topic` trait.
    FirstTopic,
    // This is the message type for the endpoint (note there is no
    // response type!)
    Delta,
    // This is the path/URI of the topic
    "topics/first",
);

使用模式

目前,这个库主要面向

  • 单个客户端,通常是一个带有 std 访问权限的 PC
  • 单个服务器,通常是一个 MCU,没有 std 访问权限

有关客户端功能,请参阅 host_client 模块,特别是 HostClient 结构体。这仅在 use-std 功能激活时可用。

带有 cobs 编码的串行端口传输可以通过 cobs-serial 功能使用。此功能将向 HostClient 添加 new_serial_cobs 构造函数。

有关服务器功能,请参阅 Dispatch 结构体。无论是否使用标准库,它都可用。

依赖项

~1–35MB
~538K SLoC