本文应用主要是使用SPI驱动wiznet的网络接口芯片W5xxx,根据wiznet提供的ioLibrary_Driver库支持W5100、W5100S、W5200、W5300、W5500。主要从以下几点进行说明:
使用hpm_sdk的cmake框架对接wiznet的ioLibrary_Driver。
ioLibrary_Driver的底层读写相关操作接口注册对接。
以ioLibrary_Driver库测试wiznet的速率性能。
本文不做wiznet芯片相关寄存器阐述,只简单阐述W5xxx的通信机制。
本文以W5500作为本文测试芯片。
本文例子仓库分支地址:
https://github.com/RCSN/hpm_sdk_extra/tree/feature/add_spi_drive_wizchip_w5xxx_sample/spi_drive_wizchip_w5xxx
二、流程
(一)使用hpm_sdk的cmake框架对接wiznet的ioLibrary_Driver
在一些开源项目上,可能并没有使用cmake来进行搭建,而hpm_sdk基于cmake构建,所以在移植的过程中,建议使用cmake框架加入开源项目。本文以对接wiznet的ioLibrary_Driver作为例子供开发者相关参考。
wiznet的ioLibrary_Driver仓库地址:
https://github.com/Wiznet/ioLibrary_Driver
里面包含了w5xxx的驱动程序以及应用程序协议,使用该库基本可以很快能对接好相应的功能实现。
需要关心的是Ethernet文件夹,里面包含了如W5500,W5300,W5200,W5100,W5100S的读写相关中间层,还提供了socket应用层操作接口。
1、芯片读写操作层加入
在此库中,仅支持一款w5xxx,所以添加到工程,也只能是一个芯片读写操作的文件夹。在每个芯片上加入cmakelists文件,把对应的头文件包含以及添加对应的C文件。
如以下:比如W5100文件夹,使用sdk_inc和sdk_src命令,把该文件下的所需的文件进行添加以及包含该文件夹的头文件。
2、Ethernet文件加入
外层想使用文件夹的时候,可以通过set一个参数来判断对应的芯片操作选择,然后再添加ethernet内部的socket.c和config.c文件。
通过CONFIG_WIZNET参数来进行对不同芯片加入筛选,以及加入两个宏定义,一个是给config表示目前使用的是哪个芯片,一个是让app知道引用的是哪个头文件。
3、APP加入ioLibrary_Driver相关文件。
在本文中,使用的芯片是W5500,需要用到DHCP和ioLibrary_Driver里面application的loopback的tcp client接口,那么在app的camkelist可以做以下操作:
(1)set(CONFIG_WIZNET "w5500") 设置CONFIG_WIZNET为w5500,这样cmake到ioLibrary_Driver索引时候只添加w5500这个文件夹。
(2)add_subdirectory(ioLibrary_Driver) 加入ioLibrary_Driver文件目录
(3)sdk_app_src sdk_inc 加入ioLibrary_Driver需要的相关文件和头文件
4、使用sdk_env的start_gui生成工程或者使用命令行生成都可以。这里使用start_gui
可以看到ioLibrary_Drivers对应的目录和文件都已经添加到SES。
如此编译也Ok
(二)ioLibrary_Driver的底层读写相关操作接口注册对接
在ioLibrary_Drivers的config上,需要接口注册的主要是临界区、CS片选操作、单字节收发、块收发传输接口。在该库中也有对应的注册接口wizchip_conf.h中。
1、临界区注册
这里临界主要做全局中断的使能和禁止,可根据自身应用添加
2、CS片选信号操作注册
在这里为了避免CS拉低后存在较高的间隔,实际的拉低在actual_cs_sel API操作,就是在开启SPI传输的时候调用,具体请详见 玩转先楫SPI外设系列 文章,这里不做阐述说明。
cs操作接口使用sdk对应的board的cs操作API,可自行根据应用更改。
3、读写单字节操作注册
需要注意的是,这里为了方便快速操作,比如在读接口SPI设置为只读,然后设置传输长度,复位FIFO,开启传输,等待数据接收完成后读取数据。写接口也是如此。具体请详见 玩转先楫SPI外设系列 文章,这里同样不做阐述说明。
4、块读写传输操作注册
DMA相关的操作请详见 玩转先楫SPI外设系列 文章,这里同样不做阐述说明。
5、注册相关操作接口
(三)以ioLibrary_Driver库测试wiznet的速率性能。
W5500官方手册中,虽然可以支持到80M的SPI SCLK,但官方的建议是33.3M推荐频率,再高的频率会出现些许采样问题,在实际测试的过程中也是如此,hpm_sdk的Board.h默认为20M,本文SLCK的频率调整为30M左右测试。
在性能上,wiznet官方也出了W5500对应的MAX速率为15Mbps。如果需要更高的可以选择W5100/s
在本文所实现的例子实现中,可通过cmakelists开启或者关闭DHCP,或者开启和关闭tcp iperf测试。默认都是开启。
如果想静态IP分配,那么直接在main.c中更改load_net_parameters API里面的ip值即可。
iperf测试软件链接:
https://cloud.firebbs.cn/forum/201903/14/141408i20v8ny2i8tckkzy.zip?OSSAccessKeyId=LTAI4GJiLU8j9rPvpTDpqQKC&Expires=1698567700&Signature=JPFda8WE9%2BSZpIcf8JY8xOHd4xo%3D
这里iperf测试主要测试W5500作为Tcp client的发送性能。在SPI SCLK 30M下,可以达到17Mbps速度性能,与wiznet官方提供的15Mbsps速率相当,满足性能需求。
目前ioLibrary_Driver库性能还能继续提升,比如修改socket的send和recv实现逻辑,减少查询和等待;中间层少数据收发再次封装等等。
在逻辑分析仪下,socket的发送接口send,在实际发送前,会查询以及等待相关网络状态寄存器,占用了不少时间。wiznet提供的15mbps只有理论的一半性能也是这个时间所消耗引起。
三、总结
在ioLibrary_Driver库下,hpm的SPI驱动W5500的网络性能可以达到17Mbps,与wiznet官方的15Mbps保持一致。
如果需要提高性能,可以选择wetne其他芯片。或者自身优化wiznet的ioLibrary_Driver库。比如socket的发送send逻辑。
对于HPM6200,HPM5300等先楫通用MCU没有以太网接口,但是有实际以太网需求或者方案平替,可以选择SPI驱动相关的芯片网络接口。