4个版本 (破坏性)
0.3.0 | 2024年8月5日 |
---|---|
0.2.0 | 2023年10月18日 |
0.1.0 | 2023年6月29日 |
0.0.0 | 2023年1月3日 |
676 在 嵌入式开发 中
每月7,055次下载
用于 20 个crate(6个直接使用)
255KB
5.5K SLoC
embassy-net-driver-channel
该crate提供了一组工具,用于以比直接实现embassy-net-driver
特质更高级的方式实现embassy-net
驱动程序。
embassy-net-driver
特质是基于轮询的。要实现它,你必须手动编写数据包接收/发送状态机,并将embassy-net
提供的Waker
连接到正确的中断处理程序,以便embassy-net
知道何时再次轮询你的驱动程序以取得更多进展。
使用embassy-net-driver-channel
,你将获得一个“通道式”接口,你可以将数据包从embassy-net发送到/接收自embassy-net。预期的使用方式是在后台启动一个“驱动程序任务”,该任务执行此操作,在硬件和通道之间传递数据包。
关于死锁的说明
当使用此crate实现驱动程序时,可能会诱使你以最直接的方式编写它
loop {
// Wait for either..
match select(
// ... the chip signaling an interrupt, indicating a packet is available to receive, or
irq_pin.wait_for_low(),
// ... a TX buffer becoming available, i.e. embassy-net wants to send a packet
tx_chan.tx_buf(),
).await {
Either::First(_) => {
// a packet is ready to be received!
let buf = rx_chan.rx_buf().await; // allocate a rx buf from the packet queue
let n = receive_packet_over_spi(buf).await;
rx_chan.rx_done(n);
}
Either::Second(buf) => {
// a packet is ready to be sent!
send_packet_over_spi(buf).await;
tx_chan.tx_done();
}
}
}
然而,这段代码存在潜在的死锁错误。症状是它在负载下可能会在rx_chan.rx_buf().await
处挂起。
原因是在负载下,TX和RX队列可能会同时满。当这种情况发生时,由于TX队列已满,embassy-net
任务会暂停尝试发送,因此它停止处理RX队列中的数据包。由于RX队列已满,你的驱动程序任务也会暂停,因此它停止处理TX队列中的数据包。
修复方法是确保在等待RX队列中的空间可用时,始终维护TX队列。例如,选择“tx_chan.tx_buf()可用”或“INT低且rx_chan.rx_buf()可用”。
loop {
// Wait for either..
match select(
async {
// ... the chip signaling an interrupt, indicating a packet is available to receive
irq_pin.wait_for_low().await;
// *AND* the buffer is ready...
rx_chan.rx_buf().await
},
// ... or a TX buffer becoming available, i.e. embassy-net wants to send a packet
tx_chan.tx_buf(),
).await {
Either::First(buf) => {
// a packet is ready to be received!
let n = receive_packet_over_spi(buf).await;
rx_chan.rx_done(n);
}
Either::Second(buf) => {
// a packet is ready to be sent!
send_packet_over_spi(buf).await;
tx_chan.tx_done();
}
}
}
示例
这些embassy-net
驱动程序使用此crate实现。您可以从中获取灵感。
cyw43
是用于CYW43xx芯片的WiFi,用于Raspberry Pi Pico W。embassy-usb
用于支持USB(CDC NCM)的以太网。embassy-net-wiznet
用于Wiznet SPI以太网MAC+PHY芯片。embassy-net-esp-hosted
用于将ESP32芯片与esp-hosted
固件一起作为另一个非ESP32 MCU的WiFi适配器。
互操作性
此crate可以在任何executor上运行。
依赖项
~1–1.4MB
~28K SLoC