当前位置: 首页 > news >正文

LWIP--以太网

一:硬件说明

1、MAC 简介

STM32F407 自带有 10/100Mbit/s 的以太网 MAC 内核,这个以太网 MAC 内核有如下特性:

1、支持外部 PHY 接口实现 10/100Mbit/s 数据传输速率。

2、通过符合 IEEE802.3 的 MII 接口与外接快速以太网 PHY 进行通信

3、支持全双工和半双工操作

4、报头和帧起始数据 (SFD) 在发送路径中插入、在接收路径中删除

5、可逐帧控制 CRC 和 pad 自动生成。

6、可编程帧长度,支持高达 16KB 的巨型帧。

7、可编程帧间隔

8、支持通过 MDIO 接(标注说明:这个意思就是 MDIO 接口)

1.2、SMI 接口

F407 的 MAC 有 3 种接口:SMI、MII 和 RMII。SMI 称为站管理接口,程序中可以通过这个接口来访问 PHY 寄存器,SMI 接口有两条线:数据线 MDIO 和时钟线 MDC,该接口支持访问多达 32 个 PHY。

  • MDC:周期性时钟,提供以最大频率 2.5 MHz 传输数据时的参考时序,在空闲状态下,SMI 管理接口将 MDC 时钟信号驱动为低电平。
  • MDIO:数据输入 / 输出比特流,用于通过 MDC 时钟信号向 / 从 PHY 设备同步传输状态信息。

A.MII 接口

MII 接口:介质独立接口 (MII) 定义了 10 Mbit/s 和 100 Mbit/s 的数据传输速率下 MAC 子层与 PHY 之间的互连。

时钟说明

TX_CLK 和 RX_CLK 为发送和接收连续时钟,当速率为 10Mbit/s 时为 2.5MHZ,速率为 100Mbit/s 时为 25MHZ(标注说明:这个一乘就出来了TX和RX都是4个)。

  • 时钟需求:为生成 MII 接口的 TX_CLK 和 RX_CLK 时钟,需向外部 PHY 提供 25MHz 时钟。
  • 供给方式
    • 方式一:使用 25M 晶振直接提供。
    • 方式二:利用 STM32F4xx 的MCO 引脚(微控制器时钟输出引脚)配置输出 25MHz 时钟。
  • 功能意义:25MHz 时钟是 MII 接口在 100Mbit/s 速率下(或分频到 10Mbit/s)实现 MAC 与 PHY 时序同步的关键,两种供给方式为硬件设计提供了灵活性,开发者可根据电路复杂度、时钟精度需求选择方案。


 

B.精简介质独立接口(RMII)

  • 接口作用:降低 10/100 Mbit/s 下微控制器以太网外设与外部 PHY 间的引脚数。
  • 引脚数对比:根据 IEEE 802.3u 标准,MII 包含 16 个数据和控制信号引脚,RMII 将引脚数减少为 7 个,引脚数减少 62.5%。
  • 时钟要求:RMII 接口的参考时钟必须为 50MHz。
  • 接口信号(STM32 与外部 PHY 之间):TXD [1:0]、TX_EN、RXD [1:0]、CRS_DV、MDC、MDIO、REF_CLK(由时钟源提供)。

RMII 时钟源

  • 驱动方式:通常采用 50MHz 时钟直接驱动 PHY,或借助嵌入式 PLL 将 25MHz 时钟倍频生成 50MHz 频率来驱动 PHY。
  • 功能意义:为 RMII 接口提供 50MHz 参考时钟,确保 10/100 Mbit/s 速率下 STM32 与外部 PHY 的时序同步,是 RMII 接口稳定工作的关键时钟保障,两种方案为硬件时钟源设计提供了灵活选择。

 我们使用的是探索者,使他外部的25MHZ晶振提供给PHY芯片作为时钟。支持2中接口

2、YT8512C 简介

  • 芯片类型:低功耗单端口 10/100Mbps 以太网 PHY 芯片。
  • 物理层功能:通过两条标准双绞线电缆收发器,实现发送和接收数据所需的所有物理层功能。
  • 接口类型:通过标准 MII 和 RMII 接口与 MAC 层进行连接。
  • PHY 地址设置:通过 LED0 和 LED1 引脚的电平进行配置。
  • 时钟来源:PHY 内部时钟由 XTAL 和 Clock 引脚提供。
  • 数据收发接口:TXP、TXN、RXP 和 RXN 引脚连接至 RJ45 网口,实现数据的发送与接收功能。
Pin24(LED0/PHYAD[0])Pin25(LED1/PHYAD[1])PHY 地址
0000000
0100010
1000001
1100011

二:软件

1、以太网 DMA 描述符

4.1、以太网 DMA 描述符

  • DMA 特性:F407 有一个以太网专用的 DMA,可在 CPU 完全不干预的情况下,通过描述符有效将数据从源传送到目标,接收缓冲区和发送缓冲区的数据均可通过以太网 DMA 传送。
  • 描述符数量与结构
    • 共有两个描述符,一个用于接收,一个用于发送。
    • 描述符是一种链表,最后一个描述符会指回第一个描述符构成环形结构。
  • 存储位置:描述符列表位于主机的物理存储空间,两个列表的基址分别写入 ETH_DMARDLAR 寄存器和 ETH_DMATDLAR 寄存器中。
  • 缓冲区指向:每个描述符最多可指向两个缓冲区。
  • 结构类型:描述符共有两种结构,分别是环形结构和链接结构。

在 ST 提供的以太网驱动库 stm32f4x7_eth.c 中使用的是链接结构,链接结构如下:

  • 描述符包含 Control/Status、Buffer Count、Buffer Address、Next Descriptor
  • 1、一个以太网数据包可以跨越一个或多个 DMA 描述符
  • 2、一个 DMA 描述符只能用于一个以太网数据包
  • 3、DMA 描述符列表中的最后一个描述符指向第一个,形成链式结构

描述符不是实际存在的物理结构,而是在程序中通过软件实现的,其实就是一个结构体!在 ST 的以太网驱动库 stm32f4x7_eth.h 中有个结构体 ETH_DMADESCTypeDef,这个结构体就是 DMA 描述符!

typedef struct {__IO uint32_t Status; //状态uint32_t ControlBufferSize; //控制和buffer1,buffer2的长度uint32_t Buffer1Addr; //buffer1地址uint32_t Buffer2NextDescAddr; //buffer2地址或下一个描述符地址
//一下只有增强的以太网DMA描述符含有
#ifdef USE_ENHANCED_DMA_DESCRIPTORSuint32_t ExtendedStatus; //增强描述符状态uint32_t Reserved1; //保留uint32_t TimeStampLow; //时间戳低位uint32_t TimeStampHigh; //时间戳高位
#endif
} ETH_DMADESCTypeDef;

DMA 描述符类型说明

  • 分类:分为增强描述符和常规描述符,本次仅讲解常规描述符(因网络例程仅使用常规描述符)。
  • 结构差异:常规描述符与增强描述符的结构体成员变量不同,常规描述符仅使用前 4 个成员变量。
  • 细分类型:常规描述符和增强描述符又分为发送描述符和接收描述符两种。
  • 常规发送描述符:

2、ST 以太网驱动库简介

  • 驱动库获取:ST 提供的以太网驱动库可从 ST 官网下载,也已放置在 F4 开发板光盘中。
  • 文件组成
    文件名描述
    stm32f4x7_eth.h以太网驱动头文件
    stm32f4x7_eth.c以太网驱动库
    stm32f4x7_eth_conf_template.h以太网驱动配置文件
  • 使用说明:使用时需将stm32f4x7_eth_conf_template.h重命名为stm32f4x7_eth_conf.h

1.1、pbuf 结构

  • 功能背景:LWIP 是 TCP/IP 协议栈的一种具体实现,本质是对数据包的处理,在 LWIP 中使用pbuf结构管理数据包,相关源码文件为pbuf.cpbuf.h
  • pbuf 结构体定义及成员说明

struct pbuf
{struct pbuf    *next;     //构成链表时指向下一个pbufvoid           *payload;  //指向数据缓冲区u16_t          tot_len;   //pbuf链表中所有pbuf的数据长度u16_t          len;       //当前pbuf中的数据长度u8_t           type;      //pbuf类型u8_t           flags;     //状态u16_t          ref;       //记录当前pbuf被引用的次数
};

1.2、pbuf 类型

  • 类型标识:pbuf 结构的type字段用于描述当前 pbuf 类型,在pbuf.h文件中通过枚举类型pbuf_type定义。
  • 枚举类型定义及说明

c

运行

typedef enum
{PBUF_RAM,  //pbuf数据紧跟着pbuf的结构存储,数据存储在ram中PBUF_ROM,  //pbuf数据存储在rom中PBUF_REF,  //pbuf数据存储在ram中,但是与pbuf结构的位置无关PBUF_POOL  //pbuf结构和其数据存储在同一个内存池中
} pbuf_type;///////////////////////////////////////////////////////////////////////////
/*** pbuf数据存储在RAM中,主要用于发送(TX)。struct pbuf及其有效载荷在一块连续的内存中分配(因此可通过struct pbuf计算出第一个有效载荷字节的位置)。* pbuf_alloc() 会将PBUF_RAM类型的pbuf分配为无链式结构的pbuf(不过未来版本可能会变更)。* 所有出站数据包(发送用)都应使用该类型。*/
PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP),/*** pbuf数据存储在ROM中,即struct pbuf与其有效载荷位于完全不同的内存区域。由于其指向ROM,在排队发送时无需复制有效载荷。*/
PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF,/*** pbuf来自pbuf池。与PBUF_ROM类似,但有效载荷可能会改变,因此在排队发送前需根据对其的“引用(ref)”情况进行复制。*/
PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF),/*** pbuf有效载荷指向RAM。该类型来自内存池,应用于接收(RX)。有效载荷可链式存储(分散-聚集式接收),且与PBUF_RAM类似,struct pbuf及其有效载荷在一块连续的内存中分配(因此可通过struct pbuf计算出第一个有效载荷字节的位置)。* 不要将其用于发送(TX),若因TCP排队导致内存池耗尽,将无法接收TCP确认包!*/
PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL)

PBUF_RAM 类型

  • 内存申请来源:PBUF_RAM 类型的 pbuf 空间从 LWIP 的内存堆中申请。
  • 应用场景:协议栈和应用程序中待发送数据采用该类型。
  • 申请方式:在pbuf_alloc()中进行申请,代码如下:

case PBUF_RAM:p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE\(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));if (p == NULL){return NULL;}p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF +  offset));p->len = p->tot_len = length;p->next = NULL;p->type = type;break;

PBUF_POOL 类型

  • 内存申请来源:PBUF_POOL 类型的 pbuf 空间从 LWIP 的内存池中申请。
  • 特性:因从内存池申请,分配时间极短。
  • 应用场景:网卡接收数据包时使用该类型。
  • 申请代码

c

运行

case PBUF_POOL:p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL);if (p == NULL){PBUF_POOL_IS_EMPTY();return NULL;}p->type = type;p->next = NULL;p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset)));break;

PBUF_ROM 和 PBUF_REF 类型

  • 内存申请来源:PBUF_ROM 和 PBUF_REF 类型的 pbuf 空间从 LWIP 的内存池中申请,使用内存池MEMP_PBUF
  • 内存分配特点:仅申请 pbuf 结构体的内存空间,不包含数据空间。
  • 分配代码

c

运行

case PBUF_ROM:
case PBUF_REF:p = (struct pbuf *)memp_malloc(MEMP_PBUF);if (p == NULL){return NULL;}p->payload = NULL;p->len = p->tot_len = length;p->next = NULL;p->type = type;break;

PBUF_ROM 和 PBUF_REF 类型数据空间说明

  • 数据空间特点:PBUF_ROM 和 PBUF_REF 类型未给数据空间申请内存,数据空间来自其他地方的内存。
  • 数据空间差异
    • PBUF_ROM 的数据空间在 ROM 中。
    • PBUF_REF 的数据空间在 RAM 中。

pbuf 的申请、释放与分层

  • 操作函数
    • 申请:pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
    • 释放:pbuf_free(struct pbuf *p)
  • pbuf_alloc参数说明
    • layer:决定协议栈的申请层级,影响 pbuf 的数据区首部预留空间(offset)。
    • type:决定申请的 pbuf 类型。
  • pbuf_layer枚举(定义于pbuf.h

c

运行

typedef enum {PBUF_TRANSPORT, //传输层PBUF_IP,        //IP层PBUF_LINK,      //链路层PBUF_RAW        //原始层
} pbuf_layer;

函数分组API 函数函数功能描述
TCP 连接建立tcp_new()创建一个 TCP 的 PCB 控制块
tcp_bind()为 TCP 的 PCB 控制块绑定一个本地 IP 地址和端口号
tcp_listen()开始 TCP 的 PCB 监听
tcp_accept()控制块 accept 字段注册的回调函数,侦听到连接时被调用
tcp_accented()通知 LWIP 协议栈一个 TCP 连接被接受了(注:原表格可能存在笔误,应为 tcp_accepted ())
tcp_connect()连接远端主机
发送 TCP 数据tcp_write()构造一个报文并放到控制块的发送缓冲队列中
tcp_sent()控制块 sent 字段注册的回调函数,数据发送成功后被回调
tcp_output()将发送缓冲队列中的数据发送出去
接收 TCP 数据tcp_recv()控制块 recv 字段注册的回调函数,当接收到新数据时被调用
tcp_recved()当程序处理完数据后一定要调用这个函数,通知内核更新接收窗口
轮询函数tcp_poll()控制块 poll 字段注册的回调函数,该函数周期性调用
关闭和中止连接tcp_close()关闭一个 TCP 连接
tcp_err()控制块 err 字段注册的回调函数,遇到错误时被调用
tcp_abort()中断 TCP 连接
函数描述
tcp_client_set_remoteip()设置远端 IP 地址,即服务器地址
tcp_client_test()TCP 客户端测试程序
tcp_client_connected()TCP 连接建立后调用的回调函数
tcp_client_recv()接收到数据时的回调函数
tcp_client_error()接收错误时的回调函数
tcp_client_pool()轮询函数
tcp_client_sent()发送回调函数
tcp_client_senddata()发送数据
tcp_client_connection_close()关闭 TCP 连接

具体的请参考正点原子的PDF

http://www.dtcms.com/a/592710.html

相关文章:

  • 3分钟搞定,接口管理工具PostIn安装和配置
  • 【剑斩OFFER】算法的暴力美学——在排序数组中查找元素的第一个和最后一个位置
  • Agentic TASK01
  • 麒麟最新操作系统登录锁定配置
  • RLHF、DPO 算法
  • 网站排名优化课程网站建设公司华网天下官网
  • 营销型企业网站建设教案wordpress中调用文章内容
  • MySQL 错误 1046 (3D000) 是因为在执行 SQL 语句时 没有选择当前数据库
  • Jenkins Jobs 备份与恢复
  • HTTP和HTTPS工作原理、安全漏洞及防护措施全面解析
  • 百度怎样建设网站网站建设风险怎样规避
  • 使用Docker和Selenium构建自动化测试环境
  • 网站建设公司怎么写宣传语阿里云1m服务器可以搭建网站
  • 12.1 Qt 窗口与视口 详解
  • Flink原理与实战(java版)#第1章 Flink快速入门(第一节IDE词频统计)
  • 了解GPTs
  • Biotin-FAPI-4,在化学研究和生物体系实验中主要用途
  • uni-app vue2 在 iOS 退出应用后将 cookie 清空了
  • 有趣的网站网址大学院系网站建设
  • 常见的接口测试工具有哪些?(Postman、JMeter、RestAssured等)
  • NJet event框架性能百倍提升,Why and How
  • 解析请求体内容(如 JSON、表单数据、XML 等) 将原始数据转换为 Python 数据结构 使转换后的数据可在 request. ...
  • 网页素材及网站架构制作用asp做网站优势
  • 网站建设指引快速提高网站排名
  • 未来教育图景:人工智能与培训行业的深度融合
  • java学习--匿名对象
  • 从Windows通过XRDP远程访问和控制银河麒麟 v10服务器
  • 算法31.0
  • 微信小程序端服务器接口:全部服务以及实战
  • C++11实用的“新特性”:列表初始化+右值引用与偷懒艺术——移动语义