LwIP 与 ETH外设简介 与 STM32CUBEMX的配置方法

LwIP 介绍

LwIP 全名:Light weight IP,意思是轻量化的 TCP/IP 协议

LwIP 的设计初衷是:用少量的资源消耗实现一个较为完整的 TCP/IP 协议栈,其中“完整”主要指的是 TCP 协议的完整性,实现的重点是在保持 TCP 协议主要功能的基础上减少对 RAM 的占用。此外 LwIP 既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。

LwIP 的代码已经交给 Savannah 托管,LwIP 的项目主页是:http://savannah.nongnu.org/projects/lwip/

LwIP编程接口

LwIP 提供了三种编程接口,分别为 RAW/Callback API、NETCONN API、SOCKET API。它们的易用性从左到右依次提高,而执行效率从左到右依次降低,用户可以根据实 际情况,平衡利弊,选择合适的 API 进行网络应用程序的开发。

  • RAW/Callback API: 使用回调来实现,没有操作系统也能实现
  • NETCONN API : 使用了操作系统的 IPC 机制,对网络连接进行了抽象,用户可以像操 作文件一样操作网络连接(打开/关闭、读/写数据)。但是 NETCONN API 并不如操作文 件的 API 那样简单易用。
  • SOCKET API : Socket,即套接字,它对网络连接进行了高级的抽象,使得用户可以像操作文件一样 操作网络连接。

ETH 介绍

PHY 层

在物理层,由 IEEE 802.3 标准规定了以太网使用的传输介质、传输速度、数据编码方 式和冲突检测机制,物理层一般是通过一个 PHY 芯片实现其功能的。
常用的PHY芯片有LAN8720A。

MAC 子层

它主要负责与物理层进行数据交接,如是否
可以发送数据,发送的数据是否正确,对数据流进行控制等。它自动对来自上层的数据包
加上一些控制信号,交给物理层。接收方得到正常数据时,自动去除 MAC 控制信号,把
该数据包交给上层。

STM32 的ETH外设

STM32 的 ETH 内部自带专用的 DMA 控制器用于 MAC, ETH 支持两个工业标准接口介质独立
接口(MII)和简化介质独立接口(RMII)用于与外部 PHY 芯片连接。

MII 和 RMII 接口

MII 需要 16 根通信线, RMII 只需 7 根通信,在功能上是相同的。

STM32F407ZGT6 CUBEMX ETH与LwIP配置

1、RCC

在这里插入图片描述

2、SYS

在这里插入图片描述

3、ETH

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、RTOS

在这里插入图片描述

在这里插入图片描述

5、LWIP

这里为了方便测试,关闭了DHCP
在这里插入图片描述

6、时钟

在这里插入图片描述

7、堆栈

在这里插入图片描述

8、生成工程后修改代码

a、加入初始化代码
在这里插入图片描述
初始化调用步骤如下:
MX_LWIP_Init 初始化网卡 (IP地址、子网掩码、网关IP)

MX_LWIP_Init 调用netif_add函数,添加带RTOS的网络接口(IPv4/IPv6)

netif_add函数会调用ethernetif_init,ethernetif_init内将调用low_level_init(netif);

low_level_init内会进行eth的初始化(通过初始化heth句柄,与调用HAL_ETH_Init)

HAL_ETH_Init 会调用 HAL_ETH_MspInit (初始化ETH相关的时钟、GPIO与中断)

b、添加复位引脚代码

在调用HAL_ETH_Init 前,应当手动编写代码硬件翻转PHY的RESET引脚来复位PHY,同时加入下面2局代码:

	HAL_ETH_DeInit(&heth);
	ETH->DMABMR |= ETH_DMABMR_SR;

c、修改ETH配置
并将stm32f4xx_hal_conf.h 里面的在这里插入图片描述
从4 改为8 否则HAL_ETH_Init将返回HAL_TIMEOUT,导致初始化失败。

d、修改配置
在low_level_init函数内,还会调用osSemaphoreNew函数,官方的注释解释是:
创建一个用于通知ethernetif帧接收的二进制信号量

默认是s_xSemaphore = osSemaphoreNew(1, 1, NULL);
需要改为s_xSemaphore = osSemaphoreNew(40, 1, NULL);
否则代码完成后无法ping通,原因未知,暂时无法理解。

e、新增ETH句柄的配置
heth.Init.Speed = ETH_SPEED_100M; //speed
heth.Init.DuplexMode = ETH_MODE_FULLDUPLEX;

f、修改中断优先级
在这里插入图片描述
freertos的例程,优先级不能默认为0,否则卡死

测试

ping

插上和电脑同一个路由器测试一下
在这里插入图片描述

联网发送数据测试

设置花生壳内网映射,DEST_IP 与 DEST_PORT 填写未花生壳映射的IP与PORT。

添加代码并放入TASK中运行

#include "opt.h"
#include "sys.h"
#include "api.h"

#define DEST_IP_ADDR0               xxx
#define DEST_IP_ADDR1               xxx
#define DEST_IP_ADDR2               xxx
#define DEST_IP_ADDR3               xxx

#define DEST_PORT                  43457

void App_process(void)
{
	
  struct netconn *conn;
  int ret;
  ip4_addr_t ipaddr;
  
  uint8_t send_buf[]= "This is a TCP Client test...\n";
  
  printf("目地IP地址:%d.%d.%d.%d \t 端口号:%d\n\n",      \
          DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3,DEST_PORT);
  
  while(1)
  {
    conn = netconn_new(NETCONN_TCP);
    if (conn == NULL)
    {
      printf("create conn failed!\n");
      vTaskDelay(10);
      continue;
    }
    
    IP4_ADDR(&ipaddr,DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);

    ret = netconn_connect(conn,&ipaddr,DEST_PORT);
    if (ret == -1)
    {
			  printf("Connect failed!");
      
        netconn_close(conn);
        vTaskDelay(10);
        continue;
    }

    printf("Connect to server successful!\n");
     
    while (1)
    {
      ret = netconn_write(conn,send_buf,sizeof(send_buf),0);
   
      vTaskDelay(1000);
    }
  }
	
	
}

测试结果:
在这里插入图片描述

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用阿里巴巴的 fastjson 库将 "{pro_code='null', saveno='null', status='1', id_status='null', approve='null', preinve='null', jk_preinve='null', isinterview='null', finalinve='null', firstslot='null', asseinfo='23060108585862414660', member_id='null', corpno='null', userno='null', isold='null', card_level='null', card_logo='null', bankno='null',activate='null',first_bind_flag='null',settlement='null',checked ='null'}" 转换为 JSON 格式的字符串。以下是示例代码: ``` import com.alibaba.fastjson.JSONObject; public class JsonUtils { public static String toJsonString(String input) { // 去除大括号和单引号 input = input.replace("{", "").replace("}", "").replace("'", ""); // 按照逗号分割成 key-value 对 String[] keyValuePairs = input.split(","); // 创建 JSON 对象 JSONObject jsonObject = new JSONObject(); // 遍历 key-value 对,添加到 JSON 对象中 for (String pair : keyValuePairs) { String[] keyValue = pair.split("="); jsonObject.put(keyValue[0].trim(), keyValue[1].trim()); } // 返回 JSON 格式的字符串 return jsonObject.toJSONString(); } } ``` 使用示例: ``` String input = "{pro_code='null', saveno='null', status='1', id_status='null', approve='null', preinve='null', jk_preinve='null', isinterview='null', finalinve='null', firstslot='null', asseinfo='23060108585862414660', member_id='null', corpno='null', userno='null', isold='null', card_level='null', card_logo='null', bankno='null',activate='null',first_bind_flag='null',settlement='null',checked ='null'}"; String jsonString = JsonUtils.toJsonString(input); System.out.println(jsonString); ``` 输出结果: ``` {"pro_code":"null","saveno":"null","status":"1","id_status":"null","approve":"null","preinve":"null","jk_preinve":"null","isinterview":"null","finalinve":"null","firstslot":"null","asseinfo":"23060108585862414660","member_id":"null","corpno":"null","userno":"null","isold":"null","card_level":"null","card_logo":"null","bankno":"null","activate":"null","first_bind_flag":"null","settlement":"null","checked ":"null"} ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值