ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

embassy-net-wiznet 0.3.0 演进解读:WIZnet SPI 以太网驱动的多芯片支持与中断寄存器重构

embassy-net-wiznet 0.3.0 演进解读:WIZnet SPI 以太网驱动的多芯片支持与中断寄存器重构 嵌入式物联网异步编程【免费下载链接】embassyModern embedded framework, using Rust and async.项目地址https://gitcode.com/gh_mirrors/em/embassy点击查看免费下载本文围绕embassy-net-wiznet驱动 crate 的版本演进记录即 embassy-net-wiznet/CHANGELOG.md深入剖析其在 W5100S / W5500 / W6100 / W6300 四款 WIZnet SPI 以太网芯片上的实现细节重点讲解 0.3.0 版本引入的SOCKET_INTR_CLR中断清除寄存器设计、W6100/W6300 的 MAC 过滤关闭策略以及该驱动如何在 embassy-net 生态中完成 MACRAW 模式的数据收发。读完本文你将掌握该驱动的版本演进脉络、各芯片寄存器差异、底层收发原理并能依据源码快速完成驱动集成与芯片选型。版本记录概览从首发到多芯片支持embassy-net-wiznet是 embassy-net 生态中面向 WIZnet 系列 SPI 以太网控制器的驱动工作在MACRAW 模式下即由芯片完成物理层与链路层的帧收发而上层 TCP/IP 协议栈完全交给embassy-net处理。其 CHANGELOG 记录了如下版本历程版本日期核心内容0.1.12025-08-14首个附带 changelog 的发布版本0.2.12025-08-26维护版本无条目记录0.3.02026-03-10新增实验性 W6100 驱动禁用 MAC 过滤、新增 W6300 驱动、引入SOCKET_INTR_CLR寄存器、升级 embassy-net-driver-channel 至 0.4.0Unreleased—待发布条目从当前仓库的 Cargo.toml 可以看到crate 版本号与 CHANGELOG 保持同步version 0.3.0且遵循语义化版本控制0.3.0 是一次功能性演进embassy-net-driver-channel随之从旧版升至0.4.0这意味着依赖本驱动的下游项目在升级时需要同步调整embassy-net相关依赖版本。0.3.0 的核心变更一新增 W6100 与 W6300 芯片驱动0.3.0 最大的变化是芯片支持面从两款扩展到四款。从 chip/mod.rs 的模块声明可以看出驱动通过统一的Chiptrait 抽象屏蔽了不同芯片的寄存器布局差异mod w5500; pub use w5500::W5500; mod w5100s; pub use w5100s::W5100S; mod w6100; pub use w6100::W6100; mod w6300; use embedded_hal_async::spi::SpiDevice; pub use w6300::W6300;Chiptrait 由公开的Chip与密封的SealedChip两层构成SealedChip定义了驱动运行所需的全部关键常量与方法CHIP_VERSION芯片版本号用于初始化时校验芯片型号以及 SPI 通信是否正常COMMON_*与SOCKET_*系列寄存器地址覆盖模式、MAC 地址、中断、缓冲大小、收发指针、命令等寄存器BUF_SIZEsocket 收发缓冲区大小AUTO_WRAP读写数据时硬件是否自动回卷auto wraprx_addr/tx_addr将逻辑地址映射为 RX/TX 缓冲区的物理地址bus_read/bus_write不同芯片各自实现的 SPI 总线帧格式。四款芯片的参数对比将 w5100s.rs、w5500.rs、w6100.rs、w6300.rs 中的常量汇总对比如下参数W5100SW5500W6100W6300CHIP_VERSION0x510x040x460x11Address类型u16线性地址(RegisterBlock, u16)(RegisterBlock, u16)(RegisterBlock, u16)BUF_SIZE0x20008 KB0x400016 KB0x10004 KB0x10004 KBAUTO_WRAPfalsetruetruetrueSOCKET_MODE_VALUE(12) \| (16)(12) \| (17)0b0000_01110b0000_0111SOCKET_INTR地址0x402(Socket0, 0x02)(Socket0, 0x0020)(Socket0, 0x0020)SOCKET_INTR_CLR地址0x402同SOCKET_INTR(Socket0, 0x02)同SOCKET_INTR(Socket0, 0x0028)独立寄存器(Socket0, 0x0028)独立寄存器其中CHIP_VERSION的差异W5100S 为0x51、W5500 为0x04、W6100 为0x46、W6300 为0x11正是 device.rs 中初始化校验的依据——读取COMMON_VERSION寄存器后与期望值比对不匹配即返回InitError::InvalidChipVersion { expected, actual }。这既防止了选错芯片型号也相当于一次 SPI 通路自检。不同芯片的 SPI 帧格式四款芯片的 SPI 访问协议各不相同源码中通过各自bus_read/bus_write实现W5500w5500.rs3 字节控制帧2 字节地址 1 字节块/读写控制位后跟数据阶段W6100w6100.rs地址阶段拆分为 2 字节地址 1 字节控制段即 4 阶段事务W6300w6300.rs在 W6100 基础上额外增加一个指令字节写入时置位 bit5 表示写访问与一个 dummy 阶段W5100Sw5100s.rs使用 3 字节帧高字节固定0x0F/0xF0区分读写 2 字节地址地址空间为线性u16。这也是 CHANGELOG 中特别注明W6300 仅支持 Single SPI的原因——其 SPI 时序与 W5500/W6100 并不兼容需要单独适配。0.3.0 的核心变更二SOCKET_INTR_CLR 寄存器的引入0.3.0 变更记录中提到IntroducedSOCKET_INTR_CLRregister which is needed on W6100 and later models (on W5100/W5500 this is shared withSOCKET_INTRand the address is the same)这是一个典型的跨代芯片寄存器语义差异处理在 W5100S 与 W5500 上写中断状态寄存器SOCKET_INTR0x402或(Socket0, 0x02)即可同时清除中断标志因此读与清除共用同一地址在 W6100 与 W6300 上芯片将中断状态寄存器Sn_IR地址(Socket0, 0x0020)与中断清除寄存器Sn_IRCLR地址(Socket0, 0x0028)分离为两个独立寄存器必须写入Sn_IRCLR才能正确清除接收中断。因此SealedChiptrait 中新增了独立的SOCKET_INTR_CLR常量见 chip/mod.rs并由 device.rs 中的reset_interrupt()统一调用async fn reset_interrupt(mut self, code: Interrupt) - Result(), SPI::Error { let data [code as u8]; self.bus_write(C::SOCKET_INTR_CLR, data).await }Interrupt::Receive定义为0b00100_u8。接收中断的清除在read_frame()中、实际读取数据之前完成从而避免中断引脚持续拉低导致int.wait_for_low()永远等待。0.3.0 的核心变更三W6100/W6300 的 MAC 过滤为何被禁用0.3.0 明确记载 W6100 驱动为experimental且“禁用 MAC 过滤”does not currently work with it enabled。这一决定的背景可以从 w6100.rs 的源码注释中读到Note: Bit 7 is MAC filter. On the W5500 this is normally turned ON however the W6100 will not successfully retrieve an IP address with this enabled. Disabling for now and will have live with the extra noise.W5500 的SOCKET_MODE_VALUE为(12) | (17)bit7MAC 过滤默认开启而 W6100 与 W6300 均使用0b0000_0111即关闭了 bit7 的 MAC 过滤。原因是实测中发现 W6100/W6300 在开启 MAC 过滤后无法成功获取 IP 地址这会让 DHCP/静态 IP 下的 ARP 与广播流量无法正常接收因此暂时关闭代价是驱动会收到不属于本机的多余帧noise需要上层协议栈自行过滤。同理w6300.rs 沿用了相同的SOCKET_MODE_VALUE 0b0000_0111设定。这一取舍对集成者的实际影响是在 W6100/W6300 上网卡会收到更多无关广播帧占用部分 RX 队列与中断开销但对功能正确性无影响。底层收发流程MACRAW 模式如何工作驱动在 MACRAW 模式下将整个 socket 视作一个原始以太网通道。初始化时device.rs依次完成通过COMMON_MODE寄存器复位芯片写入0x80读取COMMON_VERSION校验CHIP_VERSION启用中断引脚写COMMON_SOCKET_INTR为0x01并通过SOCKET_INTR_MASK使能接收中断写入 MAC 地址COMMON_MAC依据BUF_SIZE设置 socket 的 TX/RX 缓冲区大小寄存器写入SOCKET_MODE_VALUE进入 MACRAW 模式下发Command::Open0x01打开 socket。收帧路径read_framedevice.rs的关键点读取SOCKET_RECVD_SIZE得到待收字节数连续读两次取相等结果以规避 SPI 读取过程中寄存器被硬件更新的竞态帧头前两字节为帧长度含这两字节自身解析出真实载荷长度同时做了防御处理若长度 2 视为损坏帧头直接丢弃并推进读指针若帧长超过传入缓冲区则截断并跳过剩余字节防止越界AUTO_WRAP决定缓冲区回卷策略W5500/W6100/W6300 由硬件自动回卷直接按逻辑地址读写W5100S 需在软件侧手动拆分为两段读写见 device.rs 的read_bytes与 device.rs 的write_frame收发完成后写入SOCKET_COMMAND寄存器下发Command::Send0x20或Command::Receive0x40。发送路径write_frame会先忙等SOCKET_TX_FREE_SIZE大于等于待发帧长避免覆盖未发送完的缓冲区。后台驱动循环与 embassy-net 集成驱动对外暴露的 API 非常精简lib.rsStateN_RX, N_TX驱动状态泛型参数为接收/发送包队列深度以包为单位而非字节Device交给embassy-net协议栈使用的驱动句柄Runner::run()必须在后台任务中运行的事件循环否则驱动不工作。Runner::run()使用select3并发等待三路事件中断引脚拉低有新帧待收、上层有包待发tx_chan.tx()、以及 500ms 周期的链路状态轮询Ticker::every(Duration::from_millis(500))。收到帧后通过rx_chan.rx(p)送入embassy-net协议栈is_link_up()则读取COMMON_PHY_CFG寄存器最低位判断物理链路状态并同步给embassy-netLinkState::Up/Down。new()函数负责硬件复位拉低RST引脚 1ms 后拉高再等待 100ms 让芯片 PLL 锁定——注释特别说明 W5100S 最慢需要 100ms随后完成初始化并返回(Device, Runner)二元组。实战在 RP2040 上驱动 W5500-EVB-Pico仓库在 examples/rp 中提供了完整的 W5500 示例ethernet_w5500_tcp_server.rs、ethernet_w5500_tcp_client.rs、ethernet_w5500_udp.rs、ethernet_w5500_multisocket.rs、ethernet_w55rp20_tcp_server.rs等依赖声明为embassy-net-wiznet { version 0.3.0, path ../../embassy-net-wiznet, features [defmt] }以 ethernet_w5500_tcp_server.rs 为例集成步骤为配置 SPI 与 GPIO50 MHz 的 SPI0、片选PIN_17、中断输入PIN_21上拉、复位输出PIN_20构造驱动通过embassy_net_wiznet::new(mac_addr, state, spi, int, reset)得到(device, runner)其中State::8, 8::new()表示收发队列各 8 个包mac 地址示例为[0x02, 0x00, 0x00, 0x00, 0x00, 0x00]后台任务运行驱动将Runner传入#[embassy_executor::task]中调用runner.run().await接入协议栈embassy_net::Stack::new创建协议栈stack.add_iface加入接口iface.set_dhcpv4(Some(Default::default()))启用 DHCP随后等待wait_config_up()使用 TCP创建TcpListener监听1234端口循环accept后回显数据。其他示例还展示了 UDPethernet_w5500_udp.rs、多 socket 并发ethernet_w5500_multisocket.rs与 ICMP ping 应答ethernet_w5500_icmp.rs等场景可作为移植到其他芯片W6100/W6300 只需将chip::W5500换为对应类型的参考模板。升级到 0.3.0 的注意事项从 CHANGELOG 与依赖关系可以归纳出升级要点embassy-net-driver-channel 必须升级到 0.4.00.3.0 起embassy-net-wiznet依赖 embassy-net-driver-channel 0.4.0这是 crate 间的硬性版本绑定embassy-net 需配套升级示例中embassy-net使用 0.9.1 且开启了medium-ethernet、tcp、udp、dhcpv4等特性MACRAW 模式需要medium-ethernet特性支持API 层面无破坏性变更new()/Runner/State的调用形式在 0.3.0 中保持不变新增芯片只需替换Chip泛型参数与引脚配置W6100 属实验性支持MAC 过滤被关闭若后续芯片固件或驱动修复了 IP 获取问题可关注 Unreleased 段落的更新。总而言之0.3.0 通过SealedChiptrait 的寄存器抽象与SOCKET_INTR_CLR的引入把驱动从两款老芯片平滑扩展到了 WIZnet 四代 SPI 以太网控制器为低成本的no_std async 嵌入式以太网方案提供了统一而灵活的接入层。赞分享嵌入式物联网异步编程【免费下载链接】embassyModern embedded framework, using Rust and async.项目地址https://gitcode.com/gh_mirrors/em/embassy点击查看免费下载相关推荐HsMod深度解析55项炉石传说增强功能实战指南与专业配置HsMod深度解析55项炉石传说增强功能实战指南与专业配置 HsMod作为基于BepInEx框架开发的炉石传说增强插件为玩家提供了从基础游戏体验到高级功能的嵌入式语言运行时编程语言解释器编译器物联网系统编程Meeting SDK 嵌入网络研讨会Webinar实战从注册令牌、角色管理到 QA、投票与举手Meeting SDK 嵌入网络研讨会Webinar实战从注册令牌、角色管理到 QA、投票与举手 本文基于 knowledge work plugins嵌入式物联网异步编程embassy-net-driver-channel 演进全解用通道化接口驱动 embassy-net 异步网络栈embassy net driver channel 演进全解用通道化接口驱动 embassy net 异步网络栈 导读 embassy net driver嵌入式物联网异步编程上一篇Rnote 开源手写笔记完整指南矢量草图、PDF 批注与批量导出教程下一篇深入 go-fuse v2 的 fs 包剖析一个“正确性优先”的高性能 FUSE 文件系统框架创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表