5 个版本
0.6.2 | 2023年11月29日 |
---|---|
0.6.1 | 2023年11月16日 |
0.6.0 | 2023年11月3日 |
0.5.1 | 2023年8月22日 |
0.5.0 | 2023年7月7日 |
#708 in 嵌入式开发
每月46次下载
在 flem-serial-rs 中使用
39KB
602 行
FLEM Rust 0.6.2
FLEM 代表灵活、轻量、嵌入式消息,是一个用于在多种总线类型上与嵌入式系统目标通信的小端消息协议。
变更日志
变更日志 0.6.2
- 添加了功能 = ["std"]
- 添加了
Channel
特征。这个特征需要功能 = ["std"]。它作为一组特征,可用于实现不同的硬件或模拟设备。它使用std
库进行线程处理和mpsc
通道。 - 添加了示例,展示了如何使用
Channel
特征来模拟设备。
变更日志 0.6.1
- 为数据包添加了 fmt::Debug 特征,该特征打印标题、校验和、请求、响应、长度和状态。
变更日志 0.6.0(从 0.5.0)
- 现在请求是 2 字节 u16,而不是 1 字节 u8
- 现在响应是 2 字节 u16,而不是 1 字节 u8
- 事件不再是概念。相反,每个设备应检查传入的数据包中的请求并按正常方式处理它们。这应该简化代码并防止意外混淆请求/响应/事件。
- 内置的响应已更改:已移除 busy,并将 SUCCESS 从 0x00 移至 0x0001。ASYNC 现在是 0x0000,表示发送数据包而不询问,这是数据包重置或实例化时的默认选项。
- 更新了单元测试和示例
概念
在核心上,FLEM 由包含标题和数据有效负载的数据包组成。标题是 10 字节,包括
- 标题 - 2 字节 - 应始终为 0x5555 的值
- 校验和 - 2 字节 - 包的 CRC-16(IBM)(不包括标题和校验和字节)
- 请求 - 2 字节 - 从 0 到 65535 的值,表示客户端应执行的操作。有一些保留值,见下文。
- 响应 - 2 字节 - 从 0 到 65535 的值,表示有关客户端的附加信息。
- 长度 - 2 字节 - 在
data
缓冲区中传输的字节数。可以是 0 到 u16::MAX。 - 数据 - 一个数组,大小最多为 u16::MAX_SIZE。在创建新的数据包时设置,表示可以发送或接收的数据的最大长度;小于最大值的数据也可以传输。数据包使用 MAX_SIZE 字节作为缓冲区,这是在低内存系统中需要考虑的问题。
重置数据包
在重复使用之前,应重置数据包。为此提供了两种方法
reset()
- 通过将所有字节(包括数据字节)清零来执行数据包的完全重置。lazy_reset()
- 重置校验和、请求、响应和长度字节。
打包数据包
添加数据后,应打包数据包,其中配置了头部、校验和、请求、响应和长度,并计算以下字节上的校验和
- 请求
- 响应
- 长度
- 数据
在 Rust 中,提供了一些便利函数来执行 lazy_reset
数据包,添加数据,设置头部字节,并执行打包操作
pack_data
- 向数据包添加数据,响应字节为SUCCESS
,请求字节由用户设置。pack_error
- 向数据包添加数据,请求和响应字节由用户指定。如果不需要传输数据,请使用空数据数组&[]
。
注意:如果不需要传输数据,请将数据设置为空数据数组 &[]
。
头部
头部是一个值为 0x5555 的值,表示可以快速扫描以确定数据包开始的一组字节。这可能在未来扩展,以允许其他头部字节模式。
校验和
一个 CRC-16 (IBM) 校验和,可用于确保数据在传输和接收过程中没有错误。校验和计算 不包括 头部或校验和字节;确保它们为零或跳过,如果它们在另一种语言中实现。
请求
通常,主机向客户端发送一个 2 字节请求。请求不需要有数据负载,在这种情况下,一个简单的请求数据包是 10 字节。响应数据包应始终回显请求,以确保合作伙伴设备可以双重检查并正确路由响应。
注意,客户端不需要响应。客户端的响应有助于确保命令被发送并成功(或未成功)处理。它还将帮助通过校验和验证数据硬件传输是否按预期执行。
请求通常留给用户来实现,尽管有一个预定义的
- Id (0x01) - 使用 FLEM 的每个设备都应该实现一个
DataId
结构,该结构指示一个版本、序列号、名称或其他信息(30 字节,字符),以及一个 u16,指示合作伙伴的最大数据包大小。这要求客户端/主机使用至少 30 字节的数据包大小。可以使用更小的 Id,或者不响应,但这取决于用户来实现。
我们的公司有一个独立的项目,其中包含每个项目的所有响应和请求,分别在不同的 Rust 子模块中。通常,每个项目都有类似以下内容
pub mod host_requests {
pub const READ_CONFIG: u16 = ...;
pub const WRITE_CONFIG: u16 = ...;
}
pub mod client_requests {
pub const INTERRUPT: u16 = ...;
pub const DATA_ACQUIRED: u16 = ...;
}
响应
响应是 2 字节代码,用于指示合作伙伴设备的状态,如果需要。
如果请求是事件,则响应字节
还有一些保留的非事件响应
- ASYNC - 0x0000 - 数据包正在发送,而不进行询问
- SUCCESS - 0x0001 - 处理请求没有错误,请求同样在响应数据包中回显。
- UNKNOWN_REQUEST - 0xFFFD - 请求未被合作伙伴识别
- 校验错误 - 0xFFFF - 校验值计算不正确
长度
两个字节表示数据包数据字段中预期数据的数量。这可以是 0 到 u16::MAX,尽管通常会更小。
数据
数据包数据负载。可以是 0 到 u16::MAX 字节。
特性
FLEM 提供了一个 DataInterface
特性,可以在一个结构体上实现,允许用户将结构体编码和解码为 FLEM 数据包。通常,在编码时检查结构体是否适合数据包,在解码时检查数据包是否有足够的数据适合结构体。
完成此检查后,可以将数据移动到或从结构体中,确保编码和解码顺序一致。请参阅 examples/traits.rs
中的示例。在 src/buffer.rs
中有方便的函数可以在解码时使用,这些函数的单元测试在 tests/tests.rs
中。
示例
请参阅 examples/example.rs
中的主机到客户端请求和客户端到主机响应。