3个版本 (破坏性更新)

0.2.0 2024年8月5日
0.1.0 2024年1月11日
0.0.0 2020年10月31日

#113 in 嵌入式开发

Download history 230/week @ 2024-04-22 103/week @ 2024-04-29 123/week @ 2024-05-06 240/week @ 2024-05-13 220/week @ 2024-05-20 207/week @ 2024-05-27 181/week @ 2024-06-03 138/week @ 2024-06-10 132/week @ 2024-06-17 174/week @ 2024-06-24 92/week @ 2024-07-01 87/week @ 2024-07-08 112/week @ 2024-07-15 113/week @ 2024-07-22 113/week @ 2024-07-29 354/week @ 2024-08-05

每月下载量702
7 crates中使用

MIT/Apache

1MB
22K SLoC

Embassy nRF HAL

HALs实现安全的、惯用的Rust API以使用硬件功能,因此不需要原始寄存器操作。

Embassy nRF HAL针对Nordic Semiconductor nRF系列硬件。HAL实现了许多外设的阻塞和异步API。使用异步API的好处是HAL负责在低功耗模式下等待外设完成操作和处理中断,从而使应用程序能够专注于更重要的事情。

注意:Embassy HALs可用于同步和非同步操作。对于异步,您可以选择要使用的运行时。

有关可用外设和功能的完整列表,请参阅embassy-nrf文档

硬件支持

embassy-nrf HAL支持nRF系列的多数变体

大多数外设都得到支持,但可能因芯片系列而异。要检查可用的内容,请确保在文档顶部菜单中选择您要针对的MCU。

对于具有TrustZone支持的MCU,支持安全(S)和非安全(NS)模式。在安全模式下运行允许在不使用SPM或TF-M二进制文件的情况下运行Rust代码,节省闪存空间并简化开发。

时间驱动程序

如果启用了time-driver-rtc1功能,HAL使用RTC外设作为embassy-time的全局时间驱动程序,频率为32768 Hz。

嵌入式-hal

embassy-nrf HAL实现了嵌入式HAL(v0.2和1.0)和嵌入式HAL-Async的特性和嵌入式IO以及嵌入式IO-Async

互操作性

该crate可以在任何执行器上运行。

可选地,一些需要embassy-time的功能可以通过启用time功能来激活。如果您启用它,必须在您的项目中链接一个embassy-time驱动程序。

EasyDMA注意事项

在nRF芯片上,外设可以使用所谓的EasyDMA功能来卸载与外设交互的任务。它负责在各种总线协议(TWI/I2C、UART、SPI)上发送/接收数据。然而,EasyDMA要求用于发送和接收数据的缓冲区位于RAM中。不幸的是,Rust切片并不总是这样。以下使用SPI外设的示例显示了可能发生这种情况的常见情况

// As we pass a slice to the function whose contents will not ever change,
// the compiler writes it into the flash and thus the pointer to it will
// reference static memory. Since EasyDMA requires slices to reside in RAM,
// this function call will fail.
let result = spim.write_from_ram(&[1, 2, 3]);
assert_eq!(result, Err(Error::BufferNotInRAM));

// The data is still static and located in flash. However, since we are assigning
// it to a variable, the compiler will load it into memory. Passing a reference to the
// variable will yield a pointer that references dynamic memory, thus making EasyDMA happy.
// This function call succeeds.
let data = [1, 2, 3];
let result = spim.write_from_ram(&data);
assert!(result.is_ok());

每个使用EasyDMA的外设结构(例如SpimUarteTwim)都有它们变异函数的两个变体

  • 具有后缀的函数(例如write_from_ramtransfer_from_ram)如果传入的切片不在RAM中,将返回错误。
  • 没有后缀的函数(例如writetransfer)将检查数据是否在RAM中,并在传输之前将其复制到内存中。

由于复制会产生开销,您可以选择从具有后缀的_from_ram变体中选择,这些变体将失败并通知您,或者选择更方便的无后缀版本,这些版本可能略微低效一些。请注意,这种开销不仅包括指令计数,还包括内存使用,因为无后缀的方法将分配一个静态大小的缓冲区(对于nRF52840,最多512字节)。

请注意,像readtransfer_in_place这样的读取数据的函数没有相应的_from_ram变体,因为可变切片始终位于RAM中。

依赖关系

~6–20MB
~545K SLoC