1. 文档和资料搜集

官方网站:https://www.iwiznet.cn
github:https://github.com/Wiznet

官方网站可以找到所有和w5500相关的资料,包括最新的中英文版datasheet、基于各类常用平台的测试例程、应用指导等。

github上有各类和w5500相关的代码库,包括驱动、socket api封装等。

对我来说,只需要一个中文版的datasheet和一份github上down下来的名为ioLibrary_Driver的代码库即可。
datasheet用中文对w5500的所有寄存器的配置和功能进行了详尽的描述。
ioLibrary_Driver代码库则集成了包含w5500在内的各类wiznet网卡驱动代码。

2. 文档阅读

w5500是一个内置了tcpip协议栈的网卡芯片,即所谓的硬件协议栈。
通过对寄存器的配置,可以控制w5500工作在协议栈的哪个层级。

由于我要将w5500驱动集成进lwip中,只需要让其工作在mac层协议即可。

这显然是对w5500的一种资源浪费。
官方为方便用户设计、节约用户软硬件资源、提高用户处理器的效率,将tcpip协议栈放在了网卡芯片中。
如果能充分利用w5500内置的上层协议(主要指tcp/udp等),cpu可以省下时间做其他更多的活。
这里只用到了mac层协议,将以太网数据提交给了处理器中的tcpip协议栈lwip,将这个可以由w5500来解析处理的工作,交给了lwip。
整体上看,一套系统运行了两份tcpip协议,从提高资源利用率上看,显然是不合理的设计。
但是为了和用户处理器中的socket接口做兼容,唯一合理的方式就是将w5500驱动集成到lwip中,上层socket接口由lwip统一掉。

这里着重描述其MACRAW模式(工作在mac层协议)的配置。


通过对datasheet的阅读,可以对w5500有以下几点了解:

2.1 寄存器和内存的整体布局

w5500硬件上支持8路socket。
在寄存器上分为通用寄存器,和8组相同的socket寄存器和内存空间。

通用寄存器用来配置芯片的通用选项,如模式、IP地址、网关地址、子网掩码、MAC地址、中断管理等等。
socket寄存器和内存空间包括socket-n寄存器、socket-n发送缓存、socket-n接收缓存。

8路socket的所有的发送缓存大小共16KB,所有的接收缓存大小共16KB。
每一路socket的发送或接收缓存大小可以通过寄存器配置,但是总大小不能超过16KB。

需要注意的是,MACRAW模式只能使用socket-0通道,所以充分利用发送和接收的缓存区,即均设置为16KB。

2.2 spi的配置

  • 支持spi 0和3两种模式、时钟频率最大80MHz、MSB first。
  • 支持可变数据长度模式 和 固定数据长度模式
    • 可变数据长度模式:片选引脚cs的选择和释放表示着w5500工作在可变数据长度模式
    • 固定数据长度模式:片选引脚cs由硬件一直拉低,spi数据帧中的数据长度只能是1/2/4字节

2.3 数据帧格式

spi的数据帧由以下3部分组成:

| 字段 | 地址 | 控制段 | 数据段 |
| — — | — | — |
| 长度(字节) | 2 |1 | N |

  • 地址段:为w5500的寄存器或TX/RX缓存区指定了16位的偏移地址
  • 控制段:指定了地址段设定的偏移区域归属、读/写访问模式及SPI工作模式
    • 地址段设定的偏移区域归属:即通过控制段的高5位,即BSB[4:0],来确定当前spi通信访问的是通用寄存器、socket-n寄存器、socket-n发送缓存,还是socket-n接收缓存。(具体参考datasheet)
    • 读/写访问模式:由控制段的位2决定,0为读,1为写。
    • SPI工作模式:由控制段的位1和位0决定,即OM[1:0]
      • 00:可变数据长度模式
      • 01:固定数据长度模式,长度为1
      • 10:固定数据长度模式,长度为2
      • 11:固定数据长度模式,长度为4

3. 驱动代码开发

3.1 bsp初始化

  • spi协议:模式0或3、时钟频率尽量接近80MHz、MSB-first
  • cs输出引脚:输出,初始化为高电平
  • 网卡复位输出引脚:输出,初始化为高电平
  • 中断检测输入引脚:输入,初始化为上拉输入(事件发生时,w5500输出持续的低电平,清除中断标志后可能会拉高)
    • 配置为下降沿触发。但若在当前中断标志清零之前,又来了新的事件,根据INTLEVEL寄存器的配置,为0,中断标志清零后不会再次触发由高到低的跳变;为非0时,根据datasheet的公式,计算一个时间,中断标志清零后先拉到高电平,该时间过后会再次触发一个高到低的跳变。所以当INTLEVEL寄存器值为0时,只靠下降沿触发的中断,会丢失事件。当INTLEVEL寄存器值非0时,即使新事件立即发生了,也需要在上次拉高后再等待一段时间才能触发新的下降沿中断,效率较低。
    • 配置为电平触发。对于支持电平触发外部中断的处理器(比如51单片机)来说,只要触发了中断,一定是有事件还没处理完(前提是每次处理事件时都要清除中断标志)。代码编写简单、工作效率高。

3.2 注册临界区、spi读写、拉cs引脚的回调函数

  • 进入和退出临界区的接口可由开关中断或mutex上锁解锁来实现
  • spi读写需要注册读字节、写字节、读buffer、写buffer的接口(没有注册读写buffer或字节的接口,也是为了编程方便)
    需要注意的是,在我调试的平台上(EC800N),spi的读写接口内部主动做了拉cs引脚的操作,这会导致官方的驱动代码中,在拉低cs引脚后多次调用读写接口进行数据传输,最后再拉高cs引脚的机制失效(因为一次spi通信只能拉低一次cs,而EC800N做了多次片选)。
    解决方案是:增加一个同时具有读写属性的spi收发接口,将需要发送的数据重新打包为一个完整的数据包,拷贝到malloc的一块内存中,将多次读或写接口的调用,替换为一次读写接口的调用(malloc的调用会增加内存碎片化的风险,猜测这就是为何官方会多次调用读或写的接口,分批次发送一包数据的原因)。

3.3 创建信号量和中断处理线程

中断处理线程用来接收中断处理函数发送的信号量。

中断处理线程被触发执行时,说明有相应的事件发生。
读取SIR寄存器的值,获取哪一路socket产生了事件。

读取Sn_IR寄存器的值,获取这一路socket产生了什么事件(本代码中只关心mac层的数据接收事件)。

将SIR和Sn_IR寄存器的值回写入SIR和Sn_IR,即写1清除中断标志。

中断处理线程的流程图如下:

Created with Raphaël 2.3.0 中断处理线程 等待信号量 读取SIR和Sn_IR寄存器 清除中断标志 如果是socket0事件 如果是接收事件 如果接收缓存数据不为0 读取开头两个字节,获取包长度 读取包长度对应的数据 将数据递交给lwip 读取当前中断引脚电平 如果为低电平 发送信号量 yes no yes no yes no yes no

中断处理函数的流程如下:

Created with Raphaël 2.3.0 系统启动 CPU中断检测 外部中断产生 发送信号量

3.4 网卡初始化流程

Created with Raphaël 2.3.0 网卡初始化 bsp回调接口注册 bsp初始化 创建中断处理信号量和线程 网卡芯片硬件复位 读取网卡版本号 如果不等于0x04 重试次数自加1 如果重试次数超过5 返回-1 结束 等待10ms 网卡芯片软件复位 设置socket-0发送接收缓存大小各为16KB 设置INELEVEL寄存器的值为0 设置mac地址 物理层设置(自动协商/100M带宽/全双工) 开启socket-0中断 开启socket-0接收中断 设置为MACRAW协议,并屏蔽目的地非本网卡的mac帧 打开macraw协议 触发接收功能 返回0 yes no yes no

4. lwip网卡注册

按照lwip网卡注册的流程操作即可。

lwip集成w5500驱动,开发调试总结相关推荐

  1. Android GPS中间层驱动开发调试

    ~.Android GPS中间层驱动开发调试小结  // rkeclair_v1.02_sdkdemo , ublox芯片       调通GPS功能,用串口可打印出位置数据,并可在gpslogger ...

  2. WIN10 + VS2015 + WDK10 + SDK10 + VM虚拟机驱动开发调试环境搭建

    为什么80%的码农都做不了架构师?>>>    一.准备工作 1 系统环境:Win10系统 2 开发工具:VS2015 3 驱动开发工具:WDK10 4 Windows SDK:SD ...

  3. Linux驱动开发(外传)---驱动开发调试方法

    前文回顾 <Linux驱动开发(一)-环境搭建与hello world> <Linux驱动开发(二)-驱动与设备的分离设计> <Linux驱动开发(三)-设备树> ...

  4. ADI最新基带处理芯片 ADRV9002特性及 FPGA 驱动开发调试记录分享

    ADI的产品迭代还是非常迅速的,继ADRV9009之后,又相继退出ADRV9026,ADRV9040,射频通道数量都是呈指数倍增加,今天要介绍一款低功耗产品ADRV9002, 数据接口从高速串行口又回 ...

  5. 多种模块拔号上网驱动开发调试

    拔号上网 前后调试了几种上网卡模块,现在把几种模块调试记录下来,并做一下备份. 操作系统:Linux (none) 2.6.30 #112 Thu Sep 7 16:01:33 CST 2017 ar ...

  6. MS5182N(AD7682)驱动开发调试总结(一)

    简介 MS5182N芯片是瑞盟科技的一款4通道的16位SAR ADC芯片,其对标的是ADI的AD7682芯片,或者说基本上两者功能一样,可以作为国产替代.另外其MS5189(8通道的)对标的则是AD7 ...

  7. 图漾科技招聘|机器视觉算法、嵌入式驱动开发高级工程师等岗位

    嵌入式驱动开发高级工程师 工作地点:上海 薪资:20-40K 岗位职责: 1. 负责嵌入式系统(usb\ethernet\spi\Camera sensor等)驱动开发和调试: 2. 负责评估核心系统 ...

  8. 开发调试指令大全--(MTK开发调试命令)

    MTK无线驱动开发调试手册 1.前言 2.MTK Wifi芯片简介 2.1 单频WIFI芯片信息 2.2 WiFi驱动版本 3.MTK 无线驱动开发调试 3.1 常用命令行 3.1.1 设置WLAN驱 ...

  9. windows驱动开发-物理双机调试

    作者 QQ群:852283276 微信:arm80x86 微信公众号:青儿创客基地 B站:主页 https://space.bilibili.com/208826118 参考 VS2012 ddk驱动 ...

最新文章

  1. docker 部署redis
  2. 为何python不好找工作k-Python这么火,为何有人说Python不好找工作?
  3. Java,开源,分享
  4. 10进制颜色 转换成 16进制
  5. 大数据算法:对5亿数据进行排序
  6. 【PyQT5编程】Pycharm结合QtDesigner使用示例:创建登录窗体
  7. 了解Logstash输入插件
  8. 后端返回number类型数据_Javascript基础教程之数据类型 (数值 Number)
  9. 【Flink】Flink 1.12 AbstractRichFunction 源码
  10. Android基础新手教程——3.4 TouchListener PK OnTouchEvent + 多点触碰
  11. HDU1829【种类并查集】
  12. 【3D建模制作技巧分享】Zbrush如何将图片转浮雕模型
  13. 支付宝第三方在线支付接口详解
  14. 有对象的程序猿都是怎么写代码的
  15. 《中国近代史纲要》思维导图复习版
  16. 2020-06-16
  17. java jstl 配置_jstl的tld配置
  18. 人脸识别与美颜算法实战-图像特效
  19. 短视频app搭建的技术难点是什么?
  20. 反余弦函数用途之一:关系距离计算

热门文章

  1. 通用状态机和ROS中的SMACH状态机
  2. linux双系统uefi引导修复,桌面应用|Windows和Ubuntu双系统,修复UEFI引导的两种办法...
  3. Docker Data Volume 之 bind mount
  4. stm32学习笔记(如何新建一个工程)
  5. 汽车电气架构开发流程的一些随想(二)——时间节点之概念开发阶段
  6. USB学习笔记连载(七):CY7C68013A 无法识别的可能原因(usb2.0)
  7. 计算机二级及宝哪个好,计算机等级考试二级哪个好考
  8. iOS NSLog打印使用总结
  9. 【Spring】Spring @Cacheable 官方学习及demo
  10. 使用 satis 搭建一个私有的 Composer 包仓库