RT-Thread:STM32 PHY 调试,使用软件包 WIZNET 驱动 W5500

news2024/11/16 23:54:19

说明:

1. 本文记录使用 RT-Thread 软件包 WIZNET驱动 W5500 的调试笔记。

2. 采用 RT-Thread Studio 工程 STM32F407VET6 芯片,W5500 PHY芯片,两者之间使用SPI接口链接 。

注意:

1.在按流程建立工程,和移植完 wiznet 软件包后,发现电脑可以 ping 通开发板, 但是开发板不能ping同电脑, 开发板移植的应用代码也连接不上电脑的 tcp 服务端。

调试许久,在网上找到一个帖,提示防火墙问题,发现电脑系统 WIN10 自带的防火墙关闭后就正常了。

链接:https://club.rt-thread.org/ask/question/797654947c126a8a.html

2:通过固定IP ,开发板与电脑直连可以ping通,也可以链接服务发送数据。

3:通过路由器自动获取IP,开发板与电脑直连可以ping通,也可以链接服务发送数据。

1. winnet 软件包应用流程

1.1 创建 RT-Thread Studio 工程

创建一个 STM32F407VET6 的 RT-Thread Studio 工程,系统版本 rt-thread 4.1.0

1.2 开启 SPI 框架,移植STM32CubeMX 生成的 SPI 驱动

打开 board.h 文件,搜索 spi 找到spi框架开启部分的流程介绍

/*-------------------------- SPI CONFIG BEGIN --------------------------*/

/** if you want to use spi bus you can use the following instructions.
 *
 * STEP 1, open spi driver framework support in the RT-Thread Settings file  在RT设置中打开spi驱动程序框架支持
 *
 * STEP 2, define macro related to the spi bus  定义与spi总线相关的宏
 *                 such as     #define BSP_USING_SPI1
 *
 * STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
 *                 such as     void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)  复制 stm32cubemx 生成的spi驱动到   board.c  文件的末尾处
 *
 * STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals
 *                 such as     #define HAL_SPI_MODULE_ENABLED   打开  stm32xxxx_hal_config.h 文件中 spi 相关的宏 #define HAL_SPI_MODULE_ENABLED
 */

#define BSP_USING_SPI1
/*#define BSP_USING_SPI2*/
/*#define BSP_USING_SPI3*/

STEP 1:在RT设置中打开spi驱动程序框架支持

STEP 2: 定义与spi总线相关的宏 #define BSP_USING_SPI1

STEP 3: 复制 stm32cubemx 生成的spi驱动到 board.c 文件的末尾处时钟部分设置

SPI部分设置

输出设置

移植生成代码

如下图路径是生成的工程目录 .

1. 时钟部分:

main.c 文件的 void SystemClock_Config(void) 函数里面相关时钟的配置复制到 RT 工程中的 drv_clk.c 文件的 void system_clock_config(int target_freq_mhz)函数内部,替换原函数中的内容。

2. SPI 部分:

把 spi.c 里面的全部代码(不包含头文件)复制到 board.c 文件的末尾。

STEP 4:打开 stm32xxxx_hal_config.h 文件中 spi 相关的宏 #define HAL_SPI_MODULE_ENABLED

在 drivers 文件夹下的 stm32f4xx_hal_conf.h 文件中

1.3 开启 winnet 软件包,并配置相关参数

1.3.1 添加软件包

添加软件包,添加好后保存工程。

右键点击软件包图标,选择 配置项

1.3.2 配置软件包

注意:

1 :SPI device name 部分,如果选择的是SPI1 那就可以设置 SPI1x (x = 0~9) ,其中 SPI1 的1 表示的是硬件的1通道 SPI 总线。spi10 表示挂在在 spi1 总线上的第 0 个设备。

2:Reset PIN number 和 IRQ PIN number 这两个编号对应的是 rt 系统中 IO 的编号,不是硬件封装的管脚号,可以在 drivers / drv_gpio.c 这个文件中查看 IO 对应的编号。如:

tatic const struct pin_index pins[] = 
{
#if defined(GPIOA)
    __STM32_PIN(0 ,  A, 0 ),
    __STM32_PIN(1 ,  A, 1 ),
    __STM32_PIN(2 ,  A, 2 ),
    __STM32_PIN(3 ,  A, 3 ),

1.3.3 添加 SPI 设备的挂载代码

        以上代码添加好后,winnet 还不能正常启动,因为 上一步设置的 spi10 设备还没挂载到总线上。如下图,这里把代码放到了软件包源码中,也可放到别的地方,但是要保证比 winnet 的初始化代码先运行才行。

rt_hw_spi_device_attach("spi1", "spi10", GPIOA, GPIO_PIN_4);

1.4 测试代码

        如下测试代码是在网上找的,没有被注释掉的两个代码都可以链接电脑的 TCP 服务端,并发送数据。如果一次链接失败可以多尝试几次。测试命令在控制台 MSH ,中发送help 查询如下这两个。

sal_tls_test     - SAL TLS function test
demo_tcp         - nbiot tcp test
#include "user_cfg.h"
#include "sal_tls.h"
//

#include <stdio.h>
#include <string.h>

#include <rtthread.h>
#include <sys/socket.h>
#include <netdb.h>
//
/* RT-Thread 官网,支持 TLS 功能 */
#define SAL_TLS_HOST    "192.168.1.2"
#define SAL_TLS_PORT    4880
#define SAL_TLS_BUFSZ   1024

static const char *send_data = "GET /download/rt-thread.txt HTTP/1.1\r\n"
    "Host: www.rt-thread.org\r\n"
    "User-Agent: rtthread/4.0.1 rtt\r\n\r\n";

void sal_tls_test(void)
{
    int ret, i;
    char *recv_data;
    struct hostent *host;
    int sock = -1, bytes_received;
    struct sockaddr_in server_addr;

    /* 通过函数入口参数url获得host地址(如果是域名,会做域名解析) */
    host = gethostbyname(SAL_TLS_HOST);

    recv_data = rt_calloc(1, SAL_TLS_BUFSZ);
    if (recv_data == RT_NULL)
    {
        rt_kprintf("No memory\n");
        return;
    }

    /* 创建一个socket,类型是SOCKET_STREAM,TCP 协议, TLS 类型 */
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        rt_kprintf("Socket error\n");
        goto __exit;
    }

    /* 初始化预连接的服务端地址 */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SAL_TLS_PORT);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
    {
        rt_kprintf("Connect fail!\n");
        goto __exit;
    }

    /* 发送数据到 socket 连接 */
    ret = send(sock, send_data, strlen(send_data), 0);
    if (ret <= 0)
    {
        rt_kprintf("send error,close the socket.\n");
        goto __exit;
    }

    /* 接收并打印响应的数据,使用加密数据传输 */
    bytes_received = recv(sock, recv_data, SAL_TLS_BUFSZ  - 1, 0);
    if (bytes_received <= 0)
    {
        rt_kprintf("received error,close the socket.\n");
        goto __exit;
    }

    rt_kprintf("recv data:\n");
    for (i = 0; i < bytes_received; i++)
    {
        rt_kprintf("%c", recv_data[i]);
    }

__exit:
    if (recv_data)
        rt_free(recv_data);

    if (sock >= 0)
        closesocket(sock);
}

#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT(sal_tls_test, SAL TLS function test);
#endif /* FINSH_USING_MSH */



//#include "sal_socket.h"
//
//#include <rtthread.h>
//#include <arpa/inet.h>
//#include <netdev.h>
//
//#define SERVER_HOST   "192.168.27.17"
//#define SERVER_PORT   4880
//
//static int bing_test(int argc, char **argv)
//{
//    struct sockaddr_in client_addr;
//    struct sockaddr_in server_addr;
//    struct netdev *netdev = RT_NULL;
//    int sockfd = -1;
//
//    if (argc != 2)
//    {
//        rt_kprintf("bind_test [netdev_name]  --bind network interface device by name.\n");
//        return -RT_ERROR;
//    }
//
//    /* 通过名称获取 netdev 网卡对象 */
//    netdev = netdev_get_by_name(argv[1]);
//    if (netdev == RT_NULL)
//    {
//        rt_kprintf("get network interface device(%s) failed.\n", argv[1]);
//        return -RT_ERROR;
//    }
//
//    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
//    {
//        rt_kprintf("Socket create failed.\n");
//        return -RT_ERROR;
//    }
//
//    /* 初始化需要绑定的客户端地址 */
//    client_addr.sin_family = AF_INET;
//    client_addr.sin_port = htons(8080);
//    /* 获取网卡对象中 IP 地址信息 */
//    client_addr.sin_addr.s_addr = netdev->ip_addr.addr;
//    rt_memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero));
//
//    if (bind(sockfd, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) < 0)
//    {
//        rt_kprintf("socket bind failed.\n");
//        closesocket(sockfd);
//        return -RT_ERROR;
//    }
//    rt_kprintf("socket bind network interface device(%s) success!\n", netdev->name);
//
//    /* 初始化预连接的服务端地址 */
//    server_addr.sin_family = AF_INET;
//    server_addr.sin_port = htons(SERVER_PORT);
//    server_addr.sin_addr.s_addr = inet_addr(SERVER_HOST);
//    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
//
//    /* 连接到服务端 */
//    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
//    {
//        rt_kprintf("socket connect failed!\n");
//        closesocket(sockfd);
//        return -RT_ERROR;
//    }
//    else
//    {
//        rt_kprintf("socket connect success!\n");
//    }
//
//    /* 关闭连接 */
//    closesocket(sockfd);
//    return RT_EOK;
//}
//
//#ifdef FINSH_USING_MSH
//#include <finsh.h>
//MSH_CMD_EXPORT(bing_test, bind network interface device test);
//#endif /* FINSH_USING_MSH */




/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author            Notes
 * 2019-07-09     MurphyZhao        first version
 */

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

#include <rtthread.h>

#ifdef RT_USING_SAL

#include <sys/socket.h>
#include <netdb.h>
#include "sal_tls.h"
#include "sys/time.h"
#else

#include "lwip/sockets.h"
#include "lwip/netdb.h"
#include "lwip/sys.h"
#include "lwip/inet.h"

#endif /* RT_USING_SAL */

#define LOG_TAG              "demo.tcp"
#define LOG_LVL              LOG_LVL_DBG

#define TCP_TEST_HOST    "192.168.1.2"
#define TCP_TEST_PORT    (4880u)

#define TEST_BUFSZ       (1024u)

static const char *req_data = "GET /service/rt-thread.txt HTTP/1.1\r\n"
    "Host: www.rt-thread.com\r\n"
    "User-Agent: rtthread/4.0.1 rtt\r\n\r\n";

static char req_uri[128];
static int  req_port;

static void nb_tcp_demo(int argc, char** argv)
{
    int ret;

    int sock = -1;
    struct hostent *host;
    struct sockaddr_in server_addr;
    int bytes_received;
    char *recv_data;

    char ip_addr_buf[64];

    if ((argc != 1) && (argc != 3))
    {
        LOG_E("In param error");
        LOG_I("cmd: demo_tcp [<host> <port>]");
        LOG_I("eg:  demo_tcp");
        LOG_I("     demo_tcp 127.0.0.1 8080");
        return;
    }

    rt_memset(req_uri, 0x0, sizeof(req_uri));

    if (argc == 3)
    {
        rt_strncpy(req_uri, argv[1], rt_strlen(argv[1]));
        req_port = atoi(argv[2]);
    }
    else
    {
        rt_strncpy(req_uri, TCP_TEST_HOST, rt_strlen(TCP_TEST_HOST));
        req_port = TCP_TEST_PORT;
    }

    LOG_I("TCP demo start");

    LOG_I("Host:%s; Port:%d", req_uri, req_port);

    LOG_D("will gethostbyname...");
    host = gethostbyname(req_uri);
    if (!host)
    {
        LOG_E("gethostbyname failed!");
        return;
    }

    LOG_I("gethostbyname pass. ip addr: %s", inet_ntoa_r(*((struct in_addr *)host->h_addr_list[0]), ip_addr_buf, sizeof(ip_addr_buf)));

    recv_data = rt_calloc(1, TEST_BUFSZ);
    if (recv_data == RT_NULL)
    {
        LOG_E("calloc failed. No memory!");
        return;
    }

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        LOG_E("Create socket failed!");
        goto __exit;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(req_port);
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    if ((ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) < 0)
    {
        LOG_E("Connect <%d> fail! ret:%d", sock, ret);
        goto __exit;
    }
    LOG_I("connect <%s> success", ip_addr_buf);

    ret = send(sock, req_data, strlen(req_data), 0);
    if (ret <= 0)
    {
        LOG_E("send error, will close the socket <%d>.", sock);
        goto __exit;
    }
    LOG_I("send success");

    bytes_received = recv(sock, recv_data, TEST_BUFSZ  - 1, 0);
    if (bytes_received <= 0)
    {
        LOG_E("receive error, will close the socket <%d>.", sock);
        goto __exit;
    }

    LOG_I("received data:\n");
    for (int i = 0; i < bytes_received; i++)
    {
        rt_kprintf("%c", recv_data[i]);
    }
    rt_kprintf("\r\n");

__exit:
    if (recv_data)
        rt_free(recv_data);

    if (sock >= 0)
    {
        closesocket(sock);
        sock = -1;
    }

    LOG_I("TCP demo end");
}
#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT_ALIAS(nb_tcp_demo, demo_tcp, nbiot tcp test);
#endif /* FINSH_USING_MSH */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1377586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ASP.NET摄影展示网站源码

ASP.NET摄影展示网站源码 项目描述 网站利用了ext技术&#xff0c;用户自定义了展示控件 前台展示类别有&#xff1a; 协会动态&#xff0c;摄影理论&#xff0c;影展影赛&#xff0c;采风路线&#xff0c; 影友之窗&#xff0c;佳作欣赏&#xff0c;器材专区&#xff0c;展览信…

「达摩院MindOpt」优化FlowShop流水线作业排班问题

FlowShop流水线作业 在企业在面临大量多样化的生产任务时&#xff0c;如何合理地安排流水线作业以提高生产效率及确保交货期成为了一个重要的问题。 一个典型的问题就是FlowShop流水线作业安排问题,也有称为生产下料问题。它涉及到多台机器、多个工序以及多个作业的调度安排。…

QWebEngineView类方法、属性、信号与槽汇总

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 使用示例📝 方法📝 属性📝 信号(Signals)📝 槽(Slots)⚓️ 相关链接 ⚓️📖 介绍 📖 QWebEngineView 是 Qt 提供的一个用于呈现 Web 内容的类,基于 Google 的 Chromium 浏览器引擎。它提供了对现…

在线直线度测量仪确保了出厂圆棒无不合格品

在线直线度测量仪确保了出厂圆棒无不合格品 随着生产设备的改进&#xff0c;利用基础材料进行生产的厂家对品质要求也越来越高&#xff0c;其中圆形棒管材的直线度尺寸&#xff0c;也是广受关注&#xff0c;对其进行矫直检测&#xff0c;使其出厂无不合格品。 变抽检为全检 以前…

C 语言每日一题——旋转数组的最小数字

一、题目内容 提供一下该OJ题的链接&#xff1a;旋转数组的最小数字_牛客题霸_牛客网 (nowcoder.com) 二、题目分析 通过示例1可知&#xff0c;我们写代码的目的是在数组中找到一个最大值&#xff0c;并且返回来&#xff1b; 我们很容易的会想到创建一个变量&#xff1a;int…

企业培训系统源码:构建智能、可扩展的学习平台

企业培训系统在现代企业中扮演着至关重要的角色。本文将通过深度解析企业培训系统的源码&#xff0c;介绍如何构建一个智能、可扩展的学习平台&#xff0c;涉及关键技术和代码实例。 1. 技术栈选择与项目初始化 在构建企业培训系统之前&#xff0c;选择适当的技术栈是至关重…

先锋WEB燃气收费系统 Upload.aspx 文件上传漏洞复现

0x01 产品简介 先锋WEB燃气收费系统是一种先进的在线燃气收费解决方案,旨在简化和优化燃气收费的流程和管理。该系统基于Web平台,提供了一系列功能和工具,使燃气公司能够高效地进行收费、账单管理和客户服务。 0x02 漏洞概述 先锋WEB燃气收费系统/AjaxService/Upload.asp…

Windows压缩包的MySQL安装方式

1.下载压缩包 https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.35-winx64.zip 2.解压压缩包&#xff08;建议将解压到非C盘&#xff0c;路径不要出现特殊符号&#xff09; 3.在MySQL主目录下&#xff0c;创建my.ini空文件&#xff08;先创建一个txt文件&#xff0c;进…

软件测试|selenium 元素无法选择异常的原因及解决

简介 在进行 Web 自动化测试时&#xff0c;使用 Selenium 可能会遇到各种异常情况。其中之一就是 ElementNotSelectableException 异常&#xff0c;该异常通常意味着在尝试选择一个不可选元素时出现了问题。本文将详细介绍这个异常的原因、可能的解决方法&#xff0c;并提供示…

微信小程序开发学习笔记《10》页面导航

微信小程序开发学习笔记《10》页面导航 博主正在学习微信小程序开发&#xff0c;希望记录自己学习过程同时与广大网友共同学习讨论。导航 官方文档 一、介绍 1. 什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现页面导航的方式有如下两种: …

<蓝桥杯软件赛>零基础备赛20周--第14周--BFS

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

C++I/O流——(2)预定义格式的输入/输出(第一节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

snmp协议配置

引言 SNMP&#xff08;Simple Network Management Protocol&#xff09;是一种网络管理协议&#xff0c;用于管理和监控网络设备、操作系统和应用程序。它提供了一组用于检索和修改网络设备配置、监视设备状态和性能的标准化方法。 SNMP 是一个客户端-服务器协议&#xff0c;…

【Docker】数据管理之数据卷的挂载

一、什么是数据卷 为了很好的实现数据保存和数据共享&#xff0c;Docker提出了Volume这个概念&#xff0c;简单的说就是绕过默认的联合 文件系统&#xff0c;而以正常的文件或者目录的形式存在于宿主机上。又被称作数据卷。数据卷提供了一些有用的特性&#xff1a; 数据卷可以在…

java自定义排序Comparator

&#x1f4d1;前言 本文主要是【java】——java自定义排序Comparator的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每…

《C++ Primer》第14章 重载运算与类型转换(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 14.1 基本概念&#xff08;P490&#xff09; 重载的运算符是具有特殊名字的函数&#xff0c;其名字有 operator 和要定义的运算符组合而成。和其他函数一样&#xff0c;重载运算符也具有返回类型、参数列表…

人工智能推动供应链革命的成功

人工智能推动供应链革命的成功 目录 人工智能推动供应链革命的成功一、供应链管理不断变化的面貌二、拥挤的解决方案景观三、踏上人工智能驱动的转型1. 价值创造识别、战略和路线图2. 目标解决方案设计和供应商选择3. 实施与系统集成4. 变革管理、能力建设和全面价值获取 新技术…

深思这届CES,前沿新物种「辣眼睛」背后

作者 | 陈然 来源 | 洞见新研社 每届CES都会让不少人发出“无趣”的感叹。的确&#xff0c;无论是置身会场还是看网络上的报道&#xff0c;到处都是熙熙攘攘的人群&#xff0c;很难从中发现哪些产品或创意值得把玩一番。 实际上&#xff0c;辣眼睛的新物种常有&#xff0c;制…

发动机装备3d虚拟在线云展馆360度展示每处细节

在当今数字化的时代&#xff0c;消费者对于线上购物的需求与期待日益增长。尤其在购车这一大宗消费行为上&#xff0c;消费者不再满足于传统的图片与文字介绍。为了满足这一市场需求&#xff0c;我们引入了3D线上展示技术。 3D汽车模型实景互动展示是一种通过先进的三维建模技术…

软件测试|selenium 元素无此属性NoSuchAttributeException问题分析与解决

简介 在使用Selenium进行Web自动化测试时&#xff0c;我们可能会遇到NoSuchAttributeException异常。这个异常通常在尝试访问一个元素的属性&#xff08;attribute&#xff09;时抛出&#xff0c;但该属性不存在。本文将介绍NoSuchAttributeException异常的常见原因以及解决方…