开篇介绍

由于项目中需要使用到STM32H7系列的芯片,且该系列无法移植ST的标准库,只能使用ST的HAL库,通过STM32Cube生成HAL库的基本代码。在项目开发中需要使用到STM32板载的ETH口,在简化的四层模型中充当着数据链路层的角色,我们只需添加PHY并配置好IP,即可实现基本的TCP主从机通信、UDP通信等等。

一、激光雷达3i-T1

由于使用了一款只具有网口通信的单线激光雷达,其具有TCP和UDP方式的通信方式,为了避免进行TCP中的socket报文解析和繁琐的通信握手过程,我们首先将雷达配置成UDP通信的模式,也就是网线直连通信,从比特层面进行数据交互。3i-T1激光雷达的OOB协议如下图所示:


3i-T1激光雷达的数据帧解析如下:

接着,在电脑上使用LVS2D上位机对激光雷达进行数据格式的配置,3i-T1激光雷达出厂默认IP是192.168.10.160,端口号为2105,必须配置同一网段(即192.168.10.XXX)后,才能与雷达通信;于是先将PC配置成静态IP——192.168.10.4,子网掩码为255.255.255.0:

然后使用LVS2D上位机将激光雷达设置为UDP通信模式(也即Out of-band模式):

从上位机中查看激光雷达的点云图大致如下:

至此,激光雷达的配置结束,接下来要调试STM32H7的ETH外设与LWIP了。

二、STM32CubeMX之ETH、LWIP配置

跳过STM32CubeMX的设备选型,进入可视化配置界面,首先,打开CORTEX-M7中的CPU ICache和DCache,若不打开此项,中间件Middleware中的LWIP中将无法打开!:

随后,配置系统时钟,PRVS设置为0,先将系统时钟调到最大值480MHz:

然后,使能ETH的RMII功能,将各个IO配置成Speed为High的模式,要注意其中还有三个管脚的重映射要更改,一切遵循着原理图进行!其他按照默认设置,同时使能UART3口作为板载串口调试,波特率115200bps,其他一切默认:

接着,配置Middleware中间件,由于我们使用的是静态IP,无需使用LWIP_DHCP模式,使其失能后,自己手动设置需要的静态IP、掩码和网关,其他一切按照默认配置进行:

最后,选取自己的IDE,点击Generate Code,生成HAL库代码,编译成功:

三、问题出现

在生成代码后,发现HAL库里成功将PHY芯片LAN8720A初始化成功了,但尝试与PC机进行Ping,提示无法访问目标主机。
因此,目前为了逐步查错,先把STM32H7使用静态IP的情况下与PC机Ping成功,再与激光雷达模块进行通信。
(2020-04-12)

重新调整思路以及学习LWIP

一、回顾TCP/IP分层

在计算机网络里,TCP/IP是一个协议族,包含着众多协议,包括ARP、IP、ICMP、UDP、TCP、DNS、HTTP、FTP、MQTT等。这些协议按照功能,可以划分为几个不同的层次:

TCP/IP协议栈各层的报文封装与拆封如下:

在本项目中,
①STM32H7为我们提供了以太口接口,充当于五层模型中的数据链路层,通过STM32Cube配置其物理地址(在Cube上是6个字节),以太口模式 (在嵌入式平台中,一般使用RMII以减少GPIO占用数量)以及收发的缓存区大小和中断相关开启等操作。
注:在一个网络里面,各种设备物理地址都是不同的。

②然后,我们采用PHY芯片LAN8720、网络接口HR911105A(里含变压器电路)以及网线,这些部分共同组成我们的物理层,负责比特字节层面的传输,其中PHY芯片LAN8720可配置10Mbp/s或100Mbp/s的半双工、全双工通信模式。在STM32Cube的HAL库中,由于版本的迭代和更新,最新版本下已采用了LAN8742作为PHY芯片的底层驱动,LAN8742与LAN8720比较看,两者管脚兼容,LAN8742是LAN8720 的升级版,多了一个MCO管脚,其他的芯片特性一样,寄存器配置完全一样。
注:LAN8720物理芯片的配置在STM32Cube中的中间层LWIP中。


③在STM32等中端嵌入式平台中,一般采用的是轻量化的TCP/IP协议——LwIP(Light weight IP),这是瑞典计算机科学院(SICS)的Adam Dunkels开发的一个小型开源的TCP/IP协议栈。其目的是以最低的系统开销实现“完整”的TCP/IP协议栈,减少RAM资源的占用。此外LwIP即可在裸机上移植,亦可在操作系统上移植。
注:截至博客发布时,目前HAL库上采用LwIP的迭代2.12版本。

二、LwIP的网络接口管理

1.网卡抽象层

为了于底层硬件网络接口衔接,LwIP作为轻量级的TCP/IP,为了兼容各种物理层芯片和底层硬件,其对网卡进行了抽象,网卡的抽象层都在netif.c和netif.h中,其中涵盖了许多关于网卡的操作,如网卡的注册和删除、启用与禁用、网卡IP设置等等。
在网卡初始化过程中,通过调用网卡抽象层的函数主要有:

1.netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &ethernet_input);

其中,gnetif是LwIP中定义的网卡抽象的结构体,HAL库在网卡初始化之前先往gnetif结构体填充好数据。ipaddr、netmask和gw分别设置为我们所需的stm32的静态IP、子网掩码和网关,这里我们设置成与雷达IP的同一网段,前三个地址字节是一样的,即可。

2.netif_set_default(&gnetif);

在经过步骤1的网卡抽象结构体填充后,通过步骤2来进行网卡注册,将网卡注册到网卡链表当中。

  3.if (netif_is_link_up(&gnetif)){/* When the netif is fully configured this function must be called */netif_set_up(&gnetif);}else{/* When the netif link is down this function must be called */netif_set_down(&gnetif);}

接着调用netif_is_link_up(&gnetif)检查netif是否配置好,当配置好之后,一切就绪,调用netif_set_up(&gnetif);启动网卡,可以开始数据传输了。

2.网卡驱动层

网卡驱动层作为底层接口,为网卡抽象层提供注册操作,给每个netif接口提供访问硬件的支持。在实际开发移植中,我们往往需要根据自己实际网卡特性去完善修改底层驱动的函数即可。
与网卡驱动密切相关的函数有3个,分别是low_level_init()、low_level_output()和low_level_input()。
1.low_level_init()为网卡初始化函数,主要完成网卡的复位和参数初始化,根据实际的网卡属性配置netif中与网卡相关的字段,如网卡的MAC地址、长度、最大发送单元等等
2.low_level_output()为网卡的发送函数,主要将内核的数据包发送出去,数据包的封装采用pbuf数据结构进行描述,而pbuf数据结构专门用了pbuf.c和pbuf.h进行定义。
3.low_level_input()是网卡的数据接收函数,同样将接收到的数据采取pbuf的形式进行各层之间的递交,保持收发的一致性且方便LwIP内核处理。

三、亲手实践过程

由于采用硬石提供的整套Demo,我们是可以跑通整个过程的,远端设备能够Ping通。因此我把硬石官方代码中的ethernetif.c和ethernetif.h移植到了我自己的CubeMX工程中,把底层网卡驱动部分直接替换掉。在调用新版LwIP的网卡抽象层进行注册和初始化网卡。发现还是存在问题-_-!!(绝望)

底层硬件驱动部分:

结果发现Ping不通,还是显示主机无法访问。直接调用硬石模板能Ping通。

四、最终解决

在开发板Demo移植很多次后,几乎丧失了信心,在同样的代码上,只换了底层驱动,仍然不行。于是在五一期间歇了一下,重新调整,最后尝试着直接用Cube生成的HAL库进行网口开发,因为细想到,STM32是开源的大社区,全球的开发者都在共同维护和做贡献,我能做的也就相信Cube的官方库,具体细节再去微调。
重新配置STM32CubeMX情况如下:
1.配置CPU-Dcache和MPU,这里配置多了一个MPU Region,大小为16KB:

2.采用以太口中断接收数据,通过ethernet_input()接收数据并交给lwip内核处理:

3.其余配置按照之前进行,基本保持不变,生成代码后进行代码修改:
(1)在LAN8742初始化之前,先对其进行硬件复位:

(2)对以太口底层输入,去掉宏定义,令以太口接收缓存Cache失效:

(3)在定时检测ETH是否断线的函数中,在检测到断线时,取消掉HAL_ETH_Stop_IT():

(4)开启SRAM3的时钟,涉及了MPU那边的使用:

(5)在主函数中添加MX_LWIP_Process(),把ethernet_input()去掉,改在ETH_IRQHandler中添加,在中断里将以太数据传给lwip内核处理,同时清楚相关的中断;
其中sys_check_timeouts是lwip内部的超时处理函数,在主函数里面都是必须的;Ethernet_Link_Periodic_Handle是每100ms检测以太口是否断开或者重新连上,使网线热插拔后,网口都能重新自动连接和自动失效:



4.一切就绪后,在Keil5上编译并烧录到板子上,一切运作正常,在使用静态IP的情况下设备两端能正常ping通,说明物理层、数据链路层、网络层一切正常且就绪,接下来可以进行tcp或udp通信。

五、总结

lwip的网卡部分,其实HAL方面移植得已经非常不错,总体过程大致如下:
1.lwip内核初始化,lwip_init();
2.设置静态本地IP、子网掩码和网关或者采用DHCP方法分配本地一个动态IP、子网掩码和网关;
3.分配好IP、子网掩码和网关等本地设置后,调用lwip接口进行网口注册,若注册成功且网线已经接好,启动网卡,若注册失败或网线没接上,关闭网卡。
4.注册断线检测和网线重连函数,在回调函数中进行网线启停处理。

STM32H7+LAN8720A之ETH与LWIP配置问题(End)相关推荐

  1. STM32CubeMX学习笔记(41)——ETH接口+LwIP协议栈使用(DHCP)

    一.ETH简介 STM32F4xx 系列控制器内部集成了一个以太网外设,它实际是一个通过 DMA 控制器进行介质访问控制(MAC),它的功能就是实现 MAC 层的任务.借助以太网外设,STM32F4x ...

  2. 【应用笔记】AN1088_APM32F4xx系列ETH移植LWIP

    1    引言 本应用笔记提供如何在APM32F4xx系列的EVAL Board上配置和应用ETH外设的指南,包括lwip协议栈的移植.代码实现和应用方法. APM32F4xx微控制器提供了可配置.灵 ...

  3. STM32CubeMX+ETH+DP83848+Lwip 成功ping通(基于stm32F107开发板)

    开发环境说明: STM32CubeMX6.2.1 Keil5 本实验基于开发板STM32F107VCTx 目录 一.实验目的 二.实验步骤 1.创建工程 2.在System Core这一项中进行SYS ...

  4. STM32F4+LAN8720A+STM32CubeMX+Lwip 网络通讯(以太网通讯)小实例

    一.目标实现      通过网络通信的方式,当上位机发出对应指令给STM32,STM32根据收到的指令来执行对应的操作(例如:亮灯.灭灯.闪灯等).还有可以将STM32连上路由器,当电脑连上路由器后, ...

  5. 【程序】STM32H743ZI单片机驱动DP83848以太网PHY芯片,移植lwip 2.1.3协议栈,并加入网线热插拔检测的功能

    STM32H7的ETH HAL库封装得比较好,真正做到了完全用HAL API函数操作,不需要再用寄存器操作. 而STM32F1的ETH HAL库就没有完全封装,有些操作必须要用寄存器完成,而且还需要单 ...

  6. 【MCU】STM32F107VC单片机驱动DP83848以太网PHY芯片,移植LWIP 2.1.2协议栈,并加入网线热插拔检测的功能(HAL库)

    开发板: 杜邦线传输高速数字信号容易出错,所以在用面包板搭建开发环境时,最好使用25MHz时钟的MII接口.如果要用50MHz的RMII接口,那么杜邦线必须要非常非常短,否则时钟信号一旦失真,就无法收 ...

  7. STM32CUBEMX生成KEIL工程后使用AC6(V6)编译加快速度

    普通小工程直接选择AC6即可,但这种时候编译速度差距也不大. 当工程内加入ETH.LWIP后编译就会出错 根据错误找到cc.h文件 注释掉 //#define LWIP_TIMEVAL_PRIVATE ...

  8. cubemx 使用 学习跳转链接

    STM32CubeMX学习笔记(1)--搭建环境.编译烧写 https://www.jianshu.com/p/836aadc6e71b STM32CubeMX学习笔记(2)--GPIO接口使用 ht ...

  9. STM32网络数据传输,实际项目中实现,以及网络卡死问题的解决

    文章目录 Keil5软件优化问题 HAL库的UDP初始化ping通 MX_LWIP_Process() 网络接收数据处理 网络长时间收发卡死 Keil5软件优化问题 正式开始前先来一个题外话,程序遇到 ...

  10. STM32F407 DP83848驱动调试过程总结(标准库到HAL库移植避坑指南)

    文章目录 移植到正点原子例程 下载ST最新F4平台例程适配 使用CubeMX从头开始 移植标准库上层函数到CubeMX初始化的HAL库 项目要从之前的STM32F107平台移植到STM32F407平台 ...

最新文章

  1. Android Studio 添加Assets目录
  2. 《实施Cisco统一通信管理器(CIPT2)》一1.6 拨号计划方面面临的挑战
  3. .Net微服务实战之DevOps篇
  4. abp框架mysql连接配置,abp框架连接数据库
  5. Spring中异步注解@Async的使用、原理及使用时可能导致的问题
  6. Android开发笔记(六十八)工程库打包
  7. Linux使用SIGALARM信号的定时器
  8. HTML5给Web带来9大改变
  9. 求不规则立方体表面积java_不规则立方体体积计算
  10. Check Exception or Uncheck Exception
  11. ele-calendar 日历插件使用
  12. WSJ Merkel Top On Forbes' Most Powerful Women List For 4th Year
  13. JavaScript 学习笔记 p61 - 69
  14. 2018永洪科技大数据技术上海峰会-唤醒数据.遇见未来
  15. 我为SEO代言,屌丝为我代言
  16. 金钱数字转换为大写中文
  17. C++:链表(初识链表)
  18. AutoJs学习-实现自动加群成员好友
  19. 从卷积神经网络(CNN)到图卷积神经网络(GCN)详解
  20. ARMv8 A64 汇编中立即数范围问题分析

热门文章

  1. 云信api_服务端API文档
  2. 关于计算机应用技术的创业策划书,计算机创业项目计划书.docx
  3. 程序员应该阅读的一些书籍
  4. [zigbee][z-Stack]协议栈简介及工作流程
  5. 基于snowflake的Id序列号生成器
  6. (转)GB2312简体中文编码表
  7. 计算机flash逐渐淡入,Flash air制作淡入淡出窗体动画效果
  8. 新书出版 |《数据库程序员面试笔试真题库》
  9. weblogic启动项目失败查看_weblogic 部署项目成功,但是再界面上取不到数据
  10. cad 打开硬件加速卡_如何提高CAD运行速度