【STM32】 TCP/IP通信协议(3)--LwIP网络接口
LwIP协议栈支持多种不同的网络接口(网卡),由于网卡是直接跟硬件平台打交道,硬件不同则处理也是不同。那Iwip如何兼容这些不同的网卡呢?
LwIP提供统一的接口,底层函数需要用户自行完成,例如网卡的初始化、接收和发送数据等。当LwIP底层接收到网络数据时,需要经过层层递交才会传入内核处理;相反,LwIP发送数据时也会调用网卡的发送数据。对于没有接触过LwIP的人新手来说,我们如何编写这个底层代码呢?不用担心,LwIP提供了一个ethernetif.c 文件作为底层接口的驱动模版。用户只根据自己的网络设备进行参照修改即可。
在LwIP中,netif数据结构用于描述一个网络接口的特性。这个结构体是在netif.h文件中定义的
struct netif {/* 指向下一个 netif 结构的指针 */struct netif *next;/* IP 地址相关配置 */ip_addr_t ip_addr; /* 网络接口的 IP 地址 */ip_addr_t netmask; /* 子网掩码 */ip_addr_t gw; /* 网关地址 *//* 该函数向 IP 层输入数据包 */netif_input_fn input;/* 该函数发送 IP 包 */netif_output_fn output;/* 该函数实现底层数据包发送 */netif_linkoutput_fn linkoutput;/* 该字段用户可以自由设置,例如用于指向一些底层设备相关的信息 */void *state;
void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX +
LWIP_NUM_NETIF_CLIENT_DATA];
/* 该接口允许的最大数据包长度 */u16_t mtu;/* 该接口物理地址长度 */u8_t hwaddr_len;/* 该接口的物理地址 */u8_t hwaddr[NETIF_MAX_HWADDR_LEN];/* 该接口的状态、属性字段 */u8_t flags;/* 该接口的名字 */char name[2];/* 接口的编号 */u8_t num;/* 需要发送的路由器请求消息的数量 */u8_t rs_count;
};
这些字段用于描述各个网卡的差异,每个网卡都通过一个 netif 结构体进行抽象表示。多 个网卡对应多个 netif,这些 netif 以链表的形式链接起来,形成一个单向链表。
这个链表的首个节点由 netif_list 指针指向,lwIP 内核使用该指针遍历和查询 netif 链表。
struct netif *netif_list; /* 网络接口链表指针 */
struct netif *netif_default; /* 哪个网络接口(多网口时候) */
static u8_t netif_num; /* 为网口分配唯一标识 */
在 lwIP 中,netif.c 文件包含了管理网络接口的核心函数。其中,netif_default 指针指向默 认的网络接口,当网络层需要发送数据包时,系统优先选择该指针所指向的网卡进行数据发送。 如果该网卡没有响应,则会选择其他网卡进行发送
1.netif_add 函数
该函数用于将新创建的 netif 插入到 netiflist 队列中,以表示添加了一个网络接口。
struct netif *
netif_add( struct netif *netif,const ip4_addr_t *ipaddr, const ip4_addr_t *netmask,
const ip4_addr_t *gw,void *state, netif_init_fn init, netif_input_fn input)
{/* 清空主机 IP 地址、子网掩码、网关等信息。 */ip_addr_set_zero_ip4(&netif->ip_addr);ip_addr_set_zero_ip4(&netif->netmask);ip_addr_set_zero_ip4(&netif->gw);netif->output = netif_null_output_ip4;/* 传输的最大数据长度 */netif->mtu = 0;/* 网络的接口状态 */netif->flags = 0;memset(netif->client_data, 0, sizeof(netif->client_data));/* 传递进来的参数填写网卡 state、input 等字段的相关信息 */netif->state = state;/* 并为当前网卡 分配唯一标识 num */netif->num = netif_num;/* 网卡输入 */netif->input = input;/* 调用网卡设置函数 netif_set_addr()设置网卡 IP 地址、子网掩码、网关 */netif_set_addr(netif, ipaddr, netmask, gw);/* 为 netif 调用用户指定的初始化函数 */if (init(netif) != ERR_OK) {return NULL;}/* 将这个 netif 添加到列表中 */netif->next = netif_list;netif_list = netif;mib2_netif_added(netif);netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);return netif;
}
每一个 netif 结构体是对一个网卡进行抽象,包含了该网 卡的收发函数、状态等信息。
注:新插入的 netif 结构体是在 netiflist 队列的首部插入
2.netif_set_default 函数
该函数用于将指定的 netif 结构体设置为默认网卡,使 lwIP 内核优先对该网卡进行操作。
void
netif_set_default(struct netif *netif)
{if (netif == NULL){/* 删除默认路由 */mib2_remove_route_ip4(1, netif);}else{/* 添加默认路由 */mib2_add_route_ip4(1, netif);}netif_default = netif; /* 选择那个网络接口 */
}/*********************怎么使用函数 netif_set_default()*********************/
/* 通过该函数,将网络接口添加到链表中 */
netif_add(&xnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init,&tcpip_input);/* 注册默认的网络接口 */
netif_set_default(&xnetif);
调用该函数,可以设置指定的网络接口为默认网卡。在函数内部,会更新相应的默认 网卡指针,并确保后续的网络操作优先使用该网卡进行数据传输。
相关文章:

【STM32】 TCP/IP通信协议(3)--LwIP网络接口
LwIP协议栈支持多种不同的网络接口(网卡),由于网卡是直接跟硬件平台打交道,硬件不同则处理也是不同。那Iwip如何兼容这些不同的网卡呢? LwIP提供统一的接口,底层函数需要用户自行完成,例如网卡的…...

15分钟学 Python 第39天:Python 爬虫入门(五)
Day 39:Python 爬虫入门数据存储概述 在进行网页爬虫时,抓取到的数据需要存储以供后续分析和使用。常见的存储方式包括但不限于: 文件存储(如文本文件、CSV、JSON)数据库存储(如SQLite、MySQL、MongoDB&a…...

使用Pytorch构建自定义层并在模型中使用
使用Pytorch构建自定义层并在模型中使用 继承自nn.Module类,自定义名称为NoisyLinear的线性层,并在新模型定义过程中使用该自定义层。完整代码可以在jupyter nbviewer中在线访问。 import torch import torch.nn as nn from torch.utils.data import T…...
学习记录:js算法(五十六):从前序与中序遍历序列构造二叉树
文章目录 从前序与中序遍历序列构造二叉树我的思路网上思路 总结 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示…...

qt使用QDomDocument读写xml文件
在使用QDomDocument读写xml之前需要在工程文件添加: QT xml 1.生成xml文件 void createXml(QString xmlName) {QFile file(xmlName);if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate |QIODevice::Text))return false;QDomDocument doc;QDomProcessin…...

Oracle架构之表空间详解
文章目录 1 表空间介绍1.1 简介1.2 表空间分类1.2.1 SYSTEM 表空间1.2.2 SYSAUX 表空间1.2.3 UNDO 表空间1.2.4 USERS 表空间 1.3 表空间字典与本地管理1.3.1 字典管理表空间(Dictionary Management Tablespace,DMT)1.3.2 本地管理方式的表空…...

springboot整合seata
一、准备 docker部署seata-server 1.5.2参考:docker安装各个组件的命令 二、springboot集成seata 2.1 引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>&…...
鸿蒙开发(NEXT/API 12)【二次向用户申请授权】程序访问控制
当应用通过[requestPermissionsFromUser()]拉起弹框[请求用户授权]时,用户拒绝授权。应用将无法再次通过requestPermissionsFromUser拉起弹框,需要用户在系统应用“设置”的界面中,手动授予权限。 在“设置”应用中的路径: 路径…...
docker export/import 和 docker save/load 的区别
Docker export/import 和 docker save/load 都是用于容器和镜像的备份和迁移,但它们有一些关键的区别: docker export/import: export 作用于容器,import 创建镜像导出的是容器的文件系统,不包含镜像的元数据丢失了镜像的层级结构…...
明星周边销售网站开发:SpringBoot技术全解析
1系统概述 1.1 研究背景 如今互联网高速发展,网络遍布全球,通过互联网发布的消息能快而方便的传播到世界每个角落,并且互联网上能传播的信息也很广,比如文字、图片、声音、视频等。从而,这种种好处使得互联网成了信息传…...

STM32+ADC+扫描模式
1 ADC简介 1 ADC(模拟到数字量的桥梁) 2 DAC(数字量到模拟的桥梁),例如:PWM(只有完全导通和断开的状态,无功率损耗的状态) DAC主要用于波形生成(信号发生器和音频解码器) 3 模拟看门狗自动监…...

R语言绘制散点图
散点图是一种在直角坐标系中用数据点直观呈现两个变量之间关系、可检测异常值并探索数据分布的可视化图表。它是一种常用的数据可视化工具,我们通过不同的参数调整和包的使用,可以创建出满足各种需求的散点图。 常用绘制散点图的函数有plot()函数和ggpl…...

安装最新 MySQL 8.0 数据库(教学用)
安装 MySQL 8.0 数据库(教学用) 文章目录 安装 MySQL 8.0 数据库(教学用)前言MySQL历史一、第一步二、下载三、安装四、使用五、语法总结 前言 根据 DB-Engines 网站的数据库流行度排名(2024年)࿰…...

微信小程序开发-配置文件详解
文章目录 一,小程序创建的配置文件介绍二,配置文件-全局配置-pages 配置作用:注意事项:示例: 三,配置文件-全局配置-window 配置示例: 四,配置文件-全局配置-tabbar 配置核心作用&am…...

TCP/UDP初识
TCP是面向连接的、可靠的、基于字节流的传输层协议。 面向连接:一定是一对一连接,不能像 UDP 协议可以一个主机同时向多个主机发送消息 可靠的:无论的网络链路中出现了怎样的链路变化,TCP 都可以保证一个报文一定能够到达接收端…...
【大数据】在线分析、近线分析与离线分析
文章目录 1. 在线分析(Online Analytics)定义特点应用场景技术栈 2. 近线分析(Nearline Analytics)定义特点应用场景技术栈 3. 离线分析(Offline Analytics)定义特点应用场景技术栈 总结 在线分析ÿ…...

【unity进阶知识9】序列化字典,场景,vector,color,Quaternion
文章目录 前言一、可序列化字典类普通字典简单的使用可序列化字典简单的使用 二、序列化场景三、序列化vector四、序列化color五、序列化旋转Quaternion完结 前言 自定义序列化的主要原因: 可读性:使数据结构更清晰,便于理解和维护。优化 I…...

传奇GOM引擎架设好进游戏后提示请关闭非法外挂,重新登录,如何处理?
今天在架设一个GOM引擎的版本时,进游戏之后刚开始是弹出一个对话框,提示请关闭非法外挂,重新登录,我用的是绿盟登陆器,同时用的也是绿盟插件,刚开始我以为是绿盟登录器的问题,于是就换成原版gom…...
OpenCV视频I/O(15)视频写入类VideoWriter之标识视频编解码器函数fourcc()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将 4 个字符拼接成一个 FourCC 代码。 在 OpenCV 中,fourcc() 函数用于生成 FourCC 代码,这是一种用于标识视频编解码器的…...
rust log选型
考察了最火的tracing。但是该模块不支持compact,仅支持根据时间进行rotate。 daily Creates a daily-rotating file appender. hourly Creates an hourly-rotating file appender. minutely Creates a minutely-rotating file appender. This will rotate the log…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...