一、准备工作
本系列文章只讲如何使用W5500驱动库。
1. 硬件环境
W5500驱动教程请参考:
本系列教程中对W5500模块和开发板之间的连接方式如图:
引脚连接情况为:
W5500引脚 | STM32引脚 |
---|---|
3V3 | 3V3 |
GND | GND |
CS | PA15(SPI3_NSS) |
MISO | PC11(SPI3_MISO) |
MOSI | PB5(SPI3_MISO) |
SCK | PC10(SPI3_SCK) |
nRST | PC0 |
nINT | PB14 |
2. 网络环境
本系列实验需要PC和开发板在同一个网段(在同一个路由器)上,目前我的配置环境为:
- 路由器网关:192.168.10.1
- PC地址:192.168.10.156
所以将开发板地址设置为192.168.10.xxx,这里我设置为192.168.10.6:
使用PC测试是否可以ping通开发板:
如果可以ping通,则网络环境正常,可以进行后续实验。
二、W5500 驱动库提供的Socket API
W5500 驱动库提供的 Socket API 称为 WIZnet socket API,实现在:socket.h
和socket.c
中。
WIZnet socket API 基于Berkeley socket API,所以它具有非常相似的名称和接口,但是也有一些差异。
WIZnet socket API 和 Berkeley socket API 的对比如下:
API | WIZnet | Berkeley |
socket() | O | O |
bind() | X | O |
listen() | O | O |
connect() | O | O |
accept() | X | O |
recv() | O | O |
send() | O | O |
recvfrom() | O | O |
sendto() | O | O |
closesocket() | O close() & disconnect() |
O |
从表里可以看到,WIZnet提供的Socket API没有bind和accept,所以使用 WIZnet API的流程如下:
三、WIZnet socket API说明
1. Socket
功能:使用传递的socket number初始化socekt并且打开socket。
原型:
int8_t socket (uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag);
参数说明:
- Sn:Socket number,应该为0 到 WIZCHIP_SOCK_NUM_
- protoco:协议类型,TCP、UDP、MACRAW
- port:端口号
- flag:见下表。
WIZCHIP_SOCK_NUM_是W5500芯片所能建立的最大独立socket数量,在 wizchip_conf.h 中定义,目前为8。
#if _WIZCHIP_ >= W5200
#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP
#else
#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP
#endif
返回值:
- 成功:返回用户指定的端口号
- 失败:返回错误码
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_SOCKMODE - Not support socket mode as TCP, UDP, and so on.
- SOCKERR_SOCKFLAG - Invaild socket flag.
2. listen
功能:监听来自客户端的连接请求。
原型:
int8_t listen (uint8_t sn);
参数说明:
- Sn:Socket number
返回值:
- 成功:SOCK_OK
- 失败:返回错误码
- SOCKERR_SOCKINIT - Socket is not initialized
- SOCKERR_SOCKCLOSED - Socket closed unexpectedly.
3. connect
功能:连接服务端。
原型:
int8_t connect (uint8_t sn, uint8_t *addr, uint16_t port);
参数说明:
- Sn:Socket number
- addr:目标IP地址指针,4个字节的数组;
- port:目标端口
返回值:
- 成功:SOCK_OK
- 失败:返回错误码
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_SOCKMODE - Invalid socket mode
- SOCKERR_SOCKINIT - Socket is not initialized
- SOCKERR_IPINVALID - Wrong server IP address
- SOCKERR_PORTZERO - Server port zero
- SOCKERR_TIMEOUT - Timeout occurred during request connection
- SOCK_BUSY - In non-block io mode, it returned immediately
4. send
功能:发送TCP数据。
原型:
int32_t send (uint8_t sn, uint8_t *buf, uint16_t len);
参数说明:
- Sn:Socket number
- buf:发送数据缓冲区指针
- len:发送数据的大小
返回值:
- 成功:发送数据的大小
- 失败:返回错误码
- SOCKERR_SOCKSTATUS - Invalid socket status for socket operation
- SOCKERR_TIMEOUT - Timeout occurred
- SOCKERR_SOCKMODE - Invalid operation in the socket
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_DATALEN - zero data length
- SOCK_BUSY - Socket is busy.
5. recv
功能:接收TCP数据。
原型:
int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len);
参数说明:
- Sn:Socket number
- buf:接收数据缓冲区指针
- len:buffer大小(接收数据的最大长度)
返回值:
- 成功:实际接收数据的大小
- 失败:返回错误码
- SOCKERR_SOCKSTATUS - Invalid socket status for socket operation
- SOCKERR_SOCKMODE - Invalid operation in the socket
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_DATALEN - zero data length
- SOCK_BUSY - Socket is busy
6. sendto
功能:发送UDP数据。
原型:
int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);
参数说明:
- Sn:Socket number
- buf:发送数据缓冲区指针
- len:发送数据的大小
- addr:目标地址
- port:目标端口
返回值:
- 成功:发送数据的大小
- 失败:返回错误码
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_SOCKMODE - Invalid operation in the socket
- SOCKERR_SOCKSTATUS - Invalid socket status for socket operation
- SOCKERR_DATALEN - zero data length
- SOCKERR_IPINVALID - Wrong server IP address
- SOCKERR_PORTZERO - Server port zero
- SOCKERR_SOCKCLOSED - Socket unexpectedly closed
- SOCKERR_TIMEOUT - Timeout occurred
- SOCK_BUSY - Socket is busy
7. recvfrom
功能:接收 UDP 数据。
原型:
int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);
参数说明:
- Sn:Socket number
- buf:接收数据缓冲区指针
- len:buffer大小(接收数据的最大长度)
- addr:目标地址
- port:目标ip
返回值:
- 成功:实际接收数据的大小
- 失败:返回错误码
- SOCKERR_SOCKSTATUS - Invalid socket status for socket operation
- SOCKERR_SOCKMODE - Invalid operation in the socket
- SOCKERR_SOCKNUM - Invalid socket number
- SOCKERR_DATALEN - zero data length
- SOCK_BUSY - Socket is busy
8. close
功能:关闭socket。
原型:
int8_t close(uint8_t sn);
参数说明:
- Sn:Socket number
返回值:
- 成功:SOCK_OK
- 失败:返回错误码
- SOCKERR_SOCKNUM - Invalid socket number