---
title: "RT-thread using W5500 notes-step guide"
url: "https://maker.wiznet.io/praveen_k/projects/RTthread-using-W5500-notesstep-guide/"
markdown_url: "https://maker.wiznet.io/praveen_k/projects/RTthread-using-W5500-notesstep-guide/md"
type: "UCC: User Created Content"
author: "praveen_k"
original_author: "praveen_k"
original_url: "https://juejin.cn/post/7074821127830257700"
published: "2022-04-01"
language: "en"
hardware: ["WIZnet W5500", "STM32F407ZG"]
likes: 0
views: 366
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# RT-thread using W5500 notes-step guide

> RT-thread using W5500 notes-step guide

Original author: praveen_k (source: https://juejin.cn/post/7074821127830257700)

## Components

- **WIZnet W5500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5500))
- **STM32F407ZG** x 1
- Software: **STM32CUBEMX**

WIZnet parts: W5500 ([Datasheet](https://docs.wiznet.io/Product/Chip/Ethernet/W5500/datasheet?utm_source=maker&utm_medium=project&utm_campaign=w5500), [product hub](https://maker.wiznet.io/products/w5500/))

## Article

## 1 Preparation

- Hardware preparation: STM32F407ZG, ST-Link, USB to serial port module (there is also an on-board serial communication interface)

- Software preparation: RT-Thread Studio

## 2 Process

![Simple process of the whole project](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1ccf4e63a8b449f3a82f818e964f4497~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ????????The entire project process is completed on RT-Thread Studio. The graphical configuration of RT-Thread Studio is very convenient for users, provided that the project uses RT-Thread Standard Edition or Smart Edition. Nano version, that will not be able to use the component pack.

## 3 Create a project

????????The method of creating a project is very simple. You only need to select the corresponding chip model when creating a new project. I use the STM32F407ZG chip. By default, there is no STM32F4 series chip package support in RT-Thread Studio, so you need to download it manually. .

### 3.1 Download STM32F4 series chip package

????????Step 1: Click "File" in the upper left corner and select "New" --> "RT-Thread Project". ????????Step 2: Find "Series:" in the new window, click the drop-down box behind and select "Add More". ????????Step 3: Next, find the "STM32F4" option, check it and click Install. There is a high probability that the installation is unsuccessful, because when downloading this resource, authentication is required to prevent malicious access (I guess), so we can only use the manual download method. ????????Step 4: Enter the download URL you see below the download window into the browser address bar (you can use the picture-to-text function of QQ screenshots), and follow the steps to download. ????????Step 5: Unzip the downloaded resources, change the name of the unzipped folder to "STM32F4", and then copy the folder to the repoExtractChip_Support_PackagesRealThread directory in the RT-Thread Studio installation directory, such as: D:RT-ThreadStudiorepoExtractChip_Support_PackagesRealThread. (Note: the unzipped folder is the file, not another folder with the same name) ????????Step 6: Done, now the chip package of the STM32F4 series should appear when you create a project in RT-Thread Studio. [Screenshot of Step 1 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121055368.png) [Step 2 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121105183.png) [Step 3 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121203063.png) [Step 4 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121216663.png) [Step 5](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121231571.png)

### 3.2 Create a project

????????Click "File" in the upper left corner, select "New" --> "RT-Thread Project", enter the project name and select the corresponding chip and the debugger to be used, and click Finish. [Screenshot of creating project](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121252188.png)

## 4 Configure SPI

????????Step 1: Double-click to open "RT-Thread Sertting", find the SPI component, click to open and use the `CTRL+S`button save. ????????Step 2: Double-click to open "CubeMX Settings", and configure the clock and pin multiplexing functions. Specifically how to configure, you can search by yourself or refer to the "attachment" at the end of the article. ????????Step 3: After the configuration is complete, click the "Compile" button to compile to ensure the correctness of the current code (the small hammer in the upper left corner is the compile button, which can only be clicked when the project is selected, otherwise the compiler does not know which project to compile). [Screenshot of Step 1 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121321453.png) [Step 2 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121330608.png) [Step 3](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121613452.png)

## 5 Configure the W5500 software package

????????Step 1: Add the W5500 package using RT-Thread Settings. Click "RT-Thread Studio" --> "Add Package", search in the new window `W5500`and click the "Add" button. ????????Step 2: After adding, you can see an additional `WIZnet`icon . ????????Step 3: Right-click the `WIZnet`icon , select "Configure", and then click the "WIZnet device configure" drop-down box to configure the properties of the SPI. After the configuration is complete, press the `CTRL+S`button to save. If you compile at this time, there will be many warnings.

> When configuring here, the main configuration is the SPI device name and pin number under the `WIZnet device configure`option .  The pin numbers can be viewed in the drivers/drv_gpio.c file.

????????Step 4: Mount the SPI device (the SPI configuration done before is only to register the SPI bus with the kernel, and the device needs to be manually mounted, the device here is W5500). Because of `WIZnet`the configuration, RT-Thread Studio will generate a **packages** directory in the project directory. Open the packages/src/wiz.c file, find the `int wiz_init(void)`function there is a comment in the function "/* I think you can attach w5500 into spi bus at here. You can use this function to realize.*/", cancel Comment the next line of the comment about the code and follow this function declaration to mount the SPI device. ????????Step 5: Add to the top of the packagew/src/wiz.c file `#include <board.h>`to increase the definition of the GPIO_Typedef type, otherwise the definition of GPIO_Typedef will not be found during compilation. Finally, you can compile the download program to see if the device is successfully mounted. [Screenshot of Step 1 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121620751.png) [Step 2 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121640883.png) [Step 3 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203121701189.png) [Step 4 Screenshot of](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203130105711.png) [Step 5](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203130110930.png)

## 6 Testing the W5500

????????After downloading, you can test whether the W5500 driver can be used normally through the finish shell. Use the `ifconfig`command to check whether the IP address is obtained (test whether DHCP works), and use the `ping`command to test whether the network can be connected normally. ![Test the W5500 driver](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/40d2617610584cda91e7ad40df1f0631~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp)

> The MAC address at this time is the default "00-E0-81-DC-53-1A". If you want to modify it, you can call the "int wiz_set_mac(const char *mac);" function to modify it.

## 7 Official use

????????Client, HTTP client, client implemented by select, TCP server, UDP server, these have corresponding routines in the official API reference manual, which are better than what I wrote, you can refer to: [here](https://link.juejin.cn?target=https%3A%2F%2Fwww.rt-thread.org%2Fdocument%2Fapi%2Fgroup__tcpclient__sample.html) . ????????The following routines are written based on my own understanding and are only for reference. The official ones shall prevail.

### 7.1 Implementing a Simple TCP Client

????????I simply drew a process for establishing communication between a TCP client and a server. Based on this process, a simple refinement can easily establish TCP communication. ![Simple process of TCP client](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/36869acfbf5d411f90e913cd217dfece~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp)

> Waiting for DHCP to obtain an IP address at first is the simplest but also the easiest place to ignore. If the socket is created before the IP address is obtained, the creation will inevitably fail.

1. Waiting for DHCP to get IP

????????The problem of waiting for DHCP to obtain the IP is how to know whether the IP address has been obtained. A simple and efficient method is to read the IP of the network card repeatedly. If the IP can be read, it is considered that the DHCP has been obtained successfully. However, before using this method, we need to obtain the object of the network card device, so that we can read the IP of the network card. The object `struct netdev *net_dev = netdev_get_by_name("W5500");`to . After obtaining the network card object, you can use it to read every 1s `net_dev->ip_addr.addr`. If it is not obtained, the value is 0, and if it is read, the value is not 0.

1. create socket socket

????????The way to create a socket is simple, use `int socketfd = socket(AF_INET, SOCK_STREAM, 0);`to create a socket.

1. Client binds socket socket

????????If the client wants to bind the socket, it first needs to decide which protocol (IPV4/IPV6), which network card (IP address) and which port to use for communication, assign these data to the `sockaddr_in`structure , and then call `bind(socketfd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr));`this function to bind fixed socket.

1. Client connects to server

????????Similar to the client binding socket, you need to know the specific information of the server you want to connect to, and then you can connect to the server through the `connect(socketfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))`function .

1. Client sends data to server

????????Sending data `int send_size = send(socketfd, msg, strlen(msg), 0);`can be , the parameters are: socket descriptor, head pointer of sending string, string length, 0.

1. Waiting to receive server data

????????It is also relatively simple to wait to receive server data. `recv_size = recv(socketfd, recv_buffer, 1024, 0);`Use to wait for a piece of data from the server in a blocking manner. The parameters are: socket descriptor, array of received data, maximum length of received data, 0. The specific code is as follows: (If you don’t see it directly, you can see the picture: [code](https://link.juejin.cn?target=https%3A%2F%2Fxjc-1305133669.cos.ap-nanjing.myqcloud.com%2Ftypora%2F202203140058483.png) )

```c
/*
 * Date           Author            Notes
 * 2022-03-13     徐浚策                  ??的 Socket 使用 Demo
 */
#include <stdio.h>      // 在??示例中?用到
#include <string.h>     // 提供 strlen() 函?

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>      // 提供 LOG_D() 等函?，?用到

#include <board.h>      // 提供一些??的定?，?用到
#include <sys/socket.h> // 提供 socket 的?准函?，如：bind()、connect()等
#include <netdb.h>      // 提供了?取 host 的方法，?有到
#include <netdev.h>     // 提供了??相?的定?和函?

#define SERVER_HOST "192.168.31.36"         // 服?器 IP 地址
#define SERVER_PORT   15370                 // 服?器使用的端口

int main(void)
{

    struct sockaddr_in client_addr;         // 客?端套接字地址
    struct sockaddr_in server_addr;         // 服?端套接字地址
    struct netdev *net_dev = RT_NULL;        // netdev ????
    int socketfd = -1;                      // 套接字文件描述符


    /* 通???名??取 netdev ???象 */
    net_dev = netdev_get_by_name("W5500");
    if (net_dev == RT_NULL){
        rt_kprintf("get network interface device(%s) failed!n", "W5500");
        return -RT_ERROR;
    }rt_kprintf("get network interface device(%s) success!n", "W5500");

    /* 等待 DHCP ?取 IP 地址成功，超??? 20s。如果?有 IP 地址，Socket 无法?建。 */
    int count = 20;
    while(count-- && !(net_dev->ip_addr.addr)){
        rt_thread_mdelay(1000);
    }
    if(!count){
        rt_kprintf("get ip failed!n");
        return -RT_ERROR;
    }

    /* ?建一?套接字 */
    if((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        rt_kprintf("create socket failed!n");
        return -RT_ERROR;
    }rt_kprintf("create socket success!n");

    /* 初始化需要?定的客?端地址 */
    client_addr.sin_family = AF_INET;                                       // IPV4
    client_addr.sin_port = htons(8080);                                     // 客?端使用的端口
    client_addr.sin_addr.s_addr = net_dev->ip_addr.addr;                    // ?取???象中的 IP 地址，??地址是由 DHCP ?取的，?有地址?? 0
    rt_memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));    // ??字段只起?充作用，使得 sockaddr_in ? sockaddr ?度一?

    /* 客?端?定套接字 */
    if (bind(socketfd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) < 0){
        rt_kprintf("socket bind failed!n");
        closesocket(socketfd);
        return -RT_ERROR;
    }rt_kprintf("socket bind network interface device(%s) success!n", net_dev->name);

    /* 初始化??接的服?端地址（配置服?端地址） */
    server_addr.sin_family = AF_INET;                                      // IPV4
    server_addr.sin_port = htons(SERVER_PORT);                             // 服?端使用的端口
    server_addr.sin_addr.s_addr = inet_addr(SERVER_HOST);                  // 服?器的 IP 地址
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));   // 无??作用，?充?度

    /* ?接到服?端 */
    if (connect(socketfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0){
        rt_kprintf("socket connect failed!n");
        closesocket(socketfd);
        return -RT_ERROR;
    }rt_kprintf("socket connect success!n");


    /* 向服?端?送?据  */
    int send_size = 0;                                         // ?送的?据?度
    static const char *msg = "Hello, i am stm32f407zg.n";     // 准?向服?端?送的?据
    if ((send_size = send(socketfd, msg, strlen(msg), 0)) <= 0) {
        rt_kprintf("send msg failed!n", send_size);
    }rt_kprintf("send msg success, send_size:%d.n", send_size);

    /* 接收服?器?送的?据，阻塞等待服?端?据，如果想要持?通信，使用 while 循??可 */
    int recv_size = -1;                     // 接收到的?据?度
    char *recv_buffer = rt_calloc(1, 1024);  // 接收?据的??
    if((recv_size = recv(socketfd, recv_buffer, 1024, 0)) < 0){
        rt_kprintf("receive data failed!n");
    }rt_kprintf("receive data success, recv_size:%d.n", recv_size);
    rt_kprintf("the data is:%sn", recv_buffer);

    return RT_EOK;
}

?制代?
```

### 7.2 To be updated... ?

## attached

### CubeMX Settings configure SPI

![Set the RCC clock](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fb0d5ff7cf24440dab370aec7bdfa208~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![enable SPI](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d9dcd26daa704006be75300d8c505580~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Enable USART1](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/50ba5f04c42645afa5f0382781ff483f~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Configure pin function](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4228bd3928cd41cb904858f8837d14a3~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Configure pin function](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f826cbcd371546bab7ddc2bffe4e2452~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Configuring the Clock Tree Feature](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e66ad201c33e4107bd26b3f800c3e502~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Clock tree configuration](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c1482b38e404b2d84e4120ac48e1430~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![generate code](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6c30011244704bc69c675ddd98b3fd35~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp) ![Finish](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/964cf904cc9b4b309e612dfa798013ce~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp)

> At this point the SPI has been configured, but not added to the device list (the device has not been registered with the device manager), you can open `#define BSP_USING_SPI2`a , which will register the SPI bus with the kernel.  If you want to know if it has been registered, you can check it through the list_device command of the finsh shell.

作者：吃菜要? ?接：https://juejin.cn/post/7074821127830257700 ?源：稀土掘金 著作??作者所有。商?????系作者?得授?，非商????注明出?。

---

Source: https://maker.wiznet.io/praveen_k/projects/RTthread-using-W5500-notesstep-guide/
