花了快一周,执迷于用AC6和H7,想先顺手配好个可ping的CubeMX模板,然后就正常学习lwip,结果一直ping不通,看了基本全网的资料,很少有看到全面的,最后是参考基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
把DP83848的驱动改好了,然后先把AC5的ping通了,后面重新搞AC6版的,一下子就想通了!!后面会全部补齐,劳烦点赞与关注~
目录
本文基于CubeMX生成的PHY驱动文件、ETH、LWIP来改。
3.1.3. 配置ETH:以太网 DMA 描述符地址、缓冲区地址/大小
3.1.4.2. PHY 芯片的复位 GPIO:(有些 PHY 芯片不一定要)
3.3.3. 在 low_level_init 函数中添加 PHY 复位代码:
3.3.4. 添加MX_LWIP_Process():此时下载即可 ping
4.3.1. DP83848_Init(&LAN8742)替换ethernetif.c文件中的LAN8742_Init(&LAN8742)
4.3.2. DP83848_GetLinkState(&LAN8742)替换ethernetif.c文件中的LAN8742_GetLinkState(&LAN8742)
5.3. ethernetif.c 中修改:这里仅改了 MDK 环境下(H7 必须改)
我的原文链接(更新较快)
《【开发】2.1、H7/H743/H750 - lwIP移植(裸机/操作系统)》
开发环境:
- CubeMX:6.12.x
- 芯片:H743/H750
- H7-HAL库:FW_H7 V1.11.2
- PHY模块:LAN8720/8742,DP83848
本文基于CubeMX生成的PHY驱动文件、ETH、LWIP来改。
后面有时间会弄,纯自己移植(非生成)/MDK RTE生成的模板
注意事项:
- 芯片:大部分H7照着做即可,H723有区别
- 待补充
一、裸机工程开发:AC5+LAN8742
参考资料:
STM32H723+Lwip+ETH+CUBE 完整配置(排了巨多坑!)_stm32h723 iwip +tcpcilent-CSDN博客
STM32H7+CUBE+ETH+LWIP配置及设置_stm32h7 lwip-CSDN博客
STM32H7+LAN8720A之ETH与LWIP配置问题(End)_stm32h7 lan8720a-CSDN博客
【LWIP】(补充)STM32H743(M7内核)CubeMX配置LWIP并ping通_h743 lwip-CSDN博客
终于搞定STM32H743网络了,分享调试经验及注意事项 - STM32 - 论坛-意法半导体STM32/STM8技术社区
这个可能详细一点
手把手教你用STM32cube调通STM32H743以太网通信并实现TCP客户端_stm32h723 tcp客户端-CSDN博客
以上还没有可以直接用的
STM32H743(M7内核)CubeMX配置LWIP并ping通」2024年9月10日_stm32h743 lwip-CSDN博客
最新的,可用的资料,实测H743没什么用
STM32H743ZIT6+LWIP+MPU+CUBEMX,通过stm32cubemx完成初始化,ping包亲测没问题,带解释!!_stm32h7 lwip-CSDN博客
STM32H723ZGT6+LWIP+CUBEMX完成初始化,ping包亲测没问题_h723 ram加载-CSDN博客
11月22日
stm32cubemx版本升级后导致stm32h743芯片LWIP无法Ping通_stm32h743 eth 8720 cubemx-CSDN博客
STM32H7LWIP,过滤,配置opt,调整rxbuffer大小等_lwip+stm32h7怎么提高发送速度-CSDN博客
STM32H743(同样适用于H745)LWIP配置-裸机+FreeRtos V2--笔记_stm32h743 lwip-CSDN博客
STM32H743使用CubeMX配置LWIP+FreeRTOS记录_stm32h743阿波罗lwip-CSDN博客
STM32H750+LAN8720无操作系统移植lwip_stm32h750 lan8720-CSDN博客
非H7:
基于正点原子探索者使用STM32CubeMX+FreeRTOS+LWIP_探索者开发板使用cobemx跑freertos-CSDN博客
11月25日
CUBE配置STM32H750、Lan8720、FreeRTOS、lwip、掉线重连、KeepAlive移植_stm32h750 lan8720-CSDN博客
STM32H750+LAN8720无操作系统移植lwip_stm32h750 lan8720-CSDN博客
STM32CubeIED+H743+DP83848+RTOS+LWIP通信_stm32h743 lwip-CSDN博客
基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
这个里面有DP83848代码
问问为什么ping不通,请求超时 - TCP/IP - 硬汉嵌入式论坛 - Powered by Discuz!
不是
关于Lwip移植-测试ping显示超时_单片机移植lwip ping大包时提示校验和不正确-CSDN博客
不是
搞定了!!基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
主要是看这篇,文章最后有附件:可以比对
3.1. CubeMX配置:
3.1.1. 常规配置(RCC、时钟树、晶振):



3.1.2. 调试串口:

3.1.3. 配置ETH:以太网 DMA 描述符地址、缓冲区地址/大小


3.1.4. GPIO配置:
3.1.4.1. ETH 的 GPIO:配置高速

3.1.4.2. PHY 芯片的复位 GPIO:(有些 PHY 芯片不一定要)
如:微雪 LAN8720,他是靠上电复位,如果要改也可以改,需要动手,在调试部分说
随便找一个 IO 接上即可

3.1.5. 配置LwIP:(很重要)
没写的默认即可,有问题评论区说
General Settings:常规设置
接入路由器才能使用DHCP协议(动态IP),一般用静态IP

Key Options:系统项设置
LWIP堆栈和内存池设置:(重要)
H723:
H723系列不同于H7系列,官方库默认配置是0x30044000,H723的内存不同于其他H7系列。
H723的RAM_D2的地址范围是0x30000000~0x30008000,而其他的H7空间比这个大得多。
H743/常规H7系列 的 RAM_D2:0x30000000~0x30048000,注意SRAM3

注意勾选


网卡设置:
注意LWIP_NETIF_LINK_CALLBACK(检测网线插拔的)要使能就行,其他配置默认

选择PHY芯片:
这里只有LAN8742可选,后期可改

3.1.6. 配置MPU(Cache):(很重要)
配置MPU是H7需要注意的
因为以太网DMA的内存需要配置好,否则问题很多


3.2. 工程配置:选择程序主 SRAM

还有微库记得勾选
3.3. 工程编写:
检查一下生成的代码,串口初始化是否在 LWIP 初始化之前(否则 DEBUG 未显示)

3.3.1. 串口调试:

/* 重定义fputc函数 */
int fputc(int ch, FILE *f)
{
if(USART1 != NULL)
{
//循环发送,直到发送完毕
while((USART1->ISR&0X40)==0)
{
}
USART1->TDR=(uint8_t)ch;
}
return ch;
}
3.3.2. 使能 D2SRAM3 时钟:

/* Enable D2 domain SRAM3 Clock (0x30040000 AXI)*/
__HAL_RCC_D2SRAM3_CLK_ENABLE();
使能时钟,使能的是 TX/RX地址描述符的时钟。
3.3.3. 在 low_level_init 函数中添加 PHY 复位代码:

HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_SET);
HAL_Delay(50);
HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_RESET);
HAL_Delay(50);
HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_SET);
HAL_Delay(50);
3.3.4. 添加MX_LWIP_Process():此时下载即可 ping
该函数的作用是从以太网缓冲区读取接收到的数据包, 将其发送到 lwIP 堆栈进行处理

MX_LWIP_Process();
二、裸机工程开发:PHY 芯片改成 LAN8720
4.1. LAN8720 此时可能还 ping 不通
通过调试检查 LAN8720 的寄存器,看一下是否正常,发现第一个寄存器就不对了
stm32cubemx版本升级后导致stm32h743芯片LWIP无法Ping通_stm32 lwip ping不通-CSDN博客

调试:



4.2. 添加 LAN8720 的 初始化函数、补充宏定义
stm32cubemx版本升级后导致stm32h743芯片LWIP无法Ping通_stm32h743 eth 8720 cubemx-CSDN博客
发现和上面链接中的问题差不多,可能是 lan8742_init 对 8720 不适用
4.2.1. 在 lan8742.c 中,将 LAN8742_Init 函数改为:
/**
* @brief Initialize the lan8742 and configure the needed hardware resources
* @param pObj: device object LAN8742_Object_t.
* @retval LAN8742_STATUS_OK if OK
* LAN8742_STATUS_ADDRESS_ERROR if cannot find device address
* LAN8742_STATUS_READ_ERROR if connot read register
* LAN8742_STATUS_WRITE_ERROR if connot write to register
* LAN8742_STATUS_RESET_TIMEOUT if cannot perform a software reset
*/
int32_t LAN8742_Init(lan8742_Object_t *pObj)
{
uint32_t tickstart = 0, regvalue = 0, addr = 0;
int32_t status = LAN8742_STATUS_OK;
if(pObj->Is_Initialized == 0)
{
if(pObj->IO.Init != 0)
{
/* GPIO and Clocks initialization */
pObj->IO.Init();
}
/* for later check */
pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1;
/* Get the device address from special mode register */
for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++)
{
if(pObj->IO.ReadReg(addr, LAN8742_SMR, ®value) < 0)
{
status = LAN8742_STATUS_READ_ERROR;
/* Can't read from this device address
continue with next address */
continue;
}
if((regvalue & LAN8742_SMR_PHY_ADDR) == addr)
{
pObj->DevAddr = addr;
status = LAN8742_STATUS_OK;
break;
}
}
if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR)
{
status = LAN8742_STATUS_ADDRESS_ERROR;
}
/* if device address is matched */
if(status == LAN8742_STATUS_OK)
{
/* set a software reset */
if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0)
{
/* get software reset status */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) >= 0)
{
tickstart = pObj->IO.GetTick();
printf("\r\nLAN8742_BCR:0x%2x",regvalue);
/* wait until software reset is done or timeout occured */
while(regvalue & LAN8742_BCR_SOFT_RESET)
{
if((pObj->IO.GetTick() - tickstart) <= LAN8742_SW_RESET_TO)
{
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) < 0)
{
status = LAN8742_STATUS_READ_ERROR;
break;
}
}
else
{
status = LAN8742_STATUS_RESET_TIMEOUT;
break;
}
}
}
else
{
status = LAN8742_STATUS_READ_ERROR;
}
}
else
{
status = LAN8742_STATUS_WRITE_ERROR;
}
}
}
if(status == LAN8742_STATUS_OK)
{
tickstart = pObj->IO.GetTick();
/* Wait for 2s to perform initialization */
while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO)
{
}
pObj->Is_Initialized = 1;
}
return status;
}
4.2.2. 在 lan8742.c 中,补充宏定义:

/** @defgroup LAN8742_Private_Defines LAN8742 Private Defines
* @{
*/
#define LAN8742_SW_RESET_TO ((uint32_t)500U)
#define LAN8742_INIT_TO ((uint32_t)2000U)
#define LAN8742_MAX_DEV_ADDR ((uint32_t)31U)
4.2.3. 这里改完,有些 LAN8720 还是初始化失败,继续查:个别模块存在电路问题:
lan8720A驱动异常 - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!
已定位到问题,LED2引脚未接下拉电阻导致(刚好极客是有下拉的)
这里看一下电路图
- 微雪 LAN8720(我改了电路,NC 为 RST 引脚,但是 LED2 没接地):寄存器有时候读取总失败(显示全 ffff)

- 极客 LAN8720:寄存器成功,部分有点奇怪

调试:




还有一些寄存器未成功:
这里去查一下手册

LAN8742[5] = 41e1,参考:cde1
41e1 = 0100000111100001

LAN8742[6] = 3,参考:b
0000000000000011

这里补充一下特殊功能寄存器:

可以利用特殊功能寄存器查地址
突然发现,有时候 lan8720 初始化卡住:杜邦线松了…
4.2.4. 单片机无法接收到 ARP 申请(ping 不显示)(LWIP DEBUG):
11月26日没搞出来,应该是杜邦线松了
二、裸机工程开发:PHY 芯片改成 DP83848
4.1. DP83848 宏定义
借鉴的基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
#include "lan8742.h"
#define DP83848_BMCR_RW ((uint16_t)0x0000U)
#define DP83848_BMSR_RO ((uint16_t)0x0001U)
#define DP83848_PHYSTS_RO ((uint16_t)0x0010U)
#define DP83848_PHYCR_RW ((uint16_t)0x0019U)
#define DP83848_BMSR_LINK_STATUS ((uint16_t)0x0004U)
#define DP83848_BMCR_SOFT_RESET ((uint16_t)0x8000U)
#define DP83848_BMCR_LOOPBACK ((uint16_t)0x4000U)
#define DP83848_BMCR_SPEED_SELECT ((uint16_t)0x2000U)
#define DP83848_BMCR_AUTONEGO_EN ((uint16_t)0x1000U)
#define DP83848_BMCR_POWER_DOWN ((uint16_t)0x0800U)
#define DP83848_BMCR_ISOLATE ((uint16_t)0x0400U)
#define DP83848_BMCR_RESTART_AUTONEGO ((uint16_t)0x0200U)
#define DP83848_BMCR_DUPLEX_MODE ((uint16_t)0x0100U)
#define DP83848_STATUS_READ_ERROR ((int32_t)-5)
#define DP83848_STATUS_WRITE_ERROR ((int32_t)-4)
#define DP83848_STATUS_ADDRESS_ERROR ((int32_t)-3)
#define DP83848_STATUS_RESET_TIMEOUT ((int32_t)-2)
#define DP83848_STATUS_ERROR ((int32_t)-1)
#define DP83848_STATUS_OK ((int32_t) 0)
#define DP83848_STATUS_LINK_DOWN ((int32_t) 1)
#define DP83848_STATUS_100MBITS_FULLDUPLEX ((int32_t) 2)
#define DP83848_STATUS_100MBITS_HALFDUPLEX ((int32_t) 3)
#define DP83848_STATUS_10MBITS_FULLDUPLEX ((int32_t) 4)
#define DP83848_STATUS_10MBITS_HALFDUPLEX ((int32_t) 5)
#define DP83848_STATUS_AUTONEGO_NOTDONE ((int32_t) 6)
#define DP83848_PHYSTS_AUTONEGO_DONE ((uint16_t)0x0010U)
#define DP83848_PHYSTS_HCDSPEEDMASK ((uint16_t)0x0006U)
#define DP83848_PHYSTS_10BT_HD ((uint16_t)0x0002U)
#define DP83848_PHYSTS_10BT_FD ((uint16_t)0x0006U)
#define DP83848_PHYSTS_100BTX_HD ((uint16_t)0x0000U)
#define DP83848_PHYSTS_100BTX_FD ((uint16_t)0x0004U)
#define DP83848_INIT_TO ((uint32_t)2000U)
#define DP83848_MAX_DEV_ADDR ((uint32_t)31U)
#define bit(n) (1 << n)
#define bit_false(x,mask) (x) &= ~(mask)
int32_t DP83848_Init(lan8742_Object_t *pObj);
int32_t DP83848_GetLinkState(lan8742_Object_t *pObj);
4.2. DP83848 相关函数:
借鉴的基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
//DP83848的初始化函数
int32_t DP83848_Init(lan8742_Object_t *pObj)
{
uint32_t tickstart = 0, regvalue = 0, addr = 0;
int32_t status = DP83848_STATUS_OK;
if(pObj->Is_Initialized == 0)
{
if(pObj->IO.Init != 0)
{
/* GPIO and Clocks initialization */
pObj->IO.Init();
}
/* Get the device address from special mode register */
for(addr = 0; addr <= DP83848_MAX_DEV_ADDR; addr ++)
{
printf("\r\n扫描地址:0x%02x",addr);
if(pObj->IO.ReadReg(addr, DP83848_PHYCR_RW, ®value) < 0)
{
status = DP83848_STATUS_READ_ERROR;
/* Can't read from this device address
continue with next address */
printf(",失败");
continue;
}
printf(",返回值:0x%02x",regvalue);
if((regvalue & 0x001F) == addr)
{
//存储地址值
pObj->DevAddr = addr;
status = DP83848_STATUS_OK;
printf(",获取PHY地址成功");
break;
}
}
if(pObj->DevAddr > DP83848_MAX_DEV_ADDR)
{
status = DP83848_STATUS_ADDRESS_ERROR;
}
if(pObj->IO.ReadReg(addr, DP83848_BMCR_RW, ®value) < 0)
{
//读取失败
printf("\r\nDP83848_BMCR_RW read fail");
}
else
{
//读取成功
printf("\r\nDP83848_BMCR_RW read ok (0x%X)",regvalue);
}
//SOFT_RESET
regvalue = regvalue|DP83848_BMCR_SOFT_RESET;
if(pObj->IO.WriteReg(addr, DP83848_BMCR_RW, regvalue) < 0)
{
//写入失败
printf("\r\nDP83848_BMCR_RW write fail");
}
else
{
//写入成功
printf("\r\nDP83848_BMCR_RW write ok (0x%X)",regvalue);
}
HAL_Delay(5);
//先读取该寄存器的数据
if(pObj->IO.ReadReg(addr, DP83848_PHYCR_RW, ®value) < 0)
{
//读取失败
printf("\r\nDP83848_PHYCR_RW read fail");
}
else
{
//读取成功
printf("\r\nDP83848_PHYCR_RW read ok (0x%X)",regvalue);
}
//bit5 是LED寄存器,配置成有数据传输的时候就闪烁 2019/06/03
bit_false(regvalue,bit(5));
if(pObj->IO.WriteReg(addr, DP83848_PHYCR_RW, regvalue) < 0)
{
//写入失败
printf("\r\nDP83848_PHYCR_RW write fail");
}
else
{
//写入成功
printf("\r\nDP83848_PHYCR_RW write ok (0x%X)",regvalue);
}
HAL_Delay(5);
//再读取该寄存器的数据,看之前的设置有没有生效
if(pObj->IO.ReadReg(addr, DP83848_PHYCR_RW, ®value) < 0)
{
//读取失败
printf("\r\nDP83848_PHYCR_RW read fail");
}
else
{
//读取成功
printf("\r\nDP83848_PHYCR_RW read ok (0x%X)",regvalue);
}
DP83848_RESET:
if(pObj->IO.ReadReg(addr, DP83848_PHYSTS_RO, ®value) >= 0)
{
printf("PHY状态寄存器:PHYSTS status=0x%x\n", regvalue);
if( (regvalue&0x0011) != 0x0011)
{
printf("\r\nDP83848初始化还未完成,等待中...\r\n");
HAL_Delay(200);
goto DP83848_RESET;
}
else
{
printf("\r\nDP83848初始化成功!\r\n");
}
}
}
if(status == DP83848_STATUS_OK)
{
tickstart = pObj->IO.GetTick();
/* Wait for 2s to perform initialization */
while((pObj->IO.GetTick() - tickstart) <= DP83848_INIT_TO)
{
}
pObj->Is_Initialized = 1;
}
return status;
}
//DP83848网络连接状态检测函数
int32_t DP83848_GetLinkState(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
/* Read Status register */
if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BMSR_RO, &readval) < 0)
{
return DP83848_STATUS_READ_ERROR;
}
/* Read Status register again */
if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BMSR_RO, &readval) < 0)
{
return DP83848_STATUS_READ_ERROR;
}
if((readval & DP83848_BMSR_LINK_STATUS) == 0)
{
/* Return Link Down status */
return DP83848_STATUS_LINK_DOWN;
}
/* Check Auto negotiaition */
if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_BMCR_RW, &readval) < 0)
{
return DP83848_STATUS_READ_ERROR;
}
if((readval & DP83848_BMCR_AUTONEGO_EN) != DP83848_BMCR_AUTONEGO_EN)
{
if(((readval & DP83848_BMCR_SPEED_SELECT) == DP83848_BMCR_SPEED_SELECT) && ((readval & DP83848_BMCR_DUPLEX_MODE) == DP83848_BMCR_DUPLEX_MODE))
{
return DP83848_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & DP83848_BMCR_SPEED_SELECT) == DP83848_BMCR_SPEED_SELECT)
{
return DP83848_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & DP83848_BMCR_DUPLEX_MODE) == DP83848_BMCR_DUPLEX_MODE)
{
return DP83848_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return DP83848_STATUS_10MBITS_HALFDUPLEX;
}
}
else /* Auto Nego enabled */
{
if(pObj->IO.ReadReg(pObj->DevAddr, DP83848_PHYSTS_RO, &readval) < 0)
{
return DP83848_STATUS_READ_ERROR;
}
/* Check if auto nego not done */
if((readval & DP83848_STATUS_AUTONEGO_NOTDONE) == 0)
{
return DP83848_STATUS_READ_ERROR;
}
if((readval & DP83848_PHYSTS_HCDSPEEDMASK) == DP83848_PHYSTS_100BTX_FD)
{
return DP83848_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & DP83848_PHYSTS_HCDSPEEDMASK) == DP83848_PHYSTS_100BTX_HD)
{
return DP83848_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & DP83848_PHYSTS_HCDSPEEDMASK) == DP83848_PHYSTS_10BT_FD)
{
return DP83848_STATUS_10MBITS_FULLDUPLEX;
}
else if ((readval & DP83848_PHYSTS_HCDSPEEDMASK) == DP83848_PHYSTS_10BT_HD)
{
return DP83848_STATUS_10MBITS_HALFDUPLEX;
}
}
}
4.3. 修改位置:
具体可以看原文,这里拷贝过来,特此谢谢稿主
基于STM32CubeMX创建的STM32H743+DP83848+LWIP网络通信程序调试_20221127算是胎教级教程了_h743 cubemx lwip-CSDN博客
将代码放置在合适的位置,我直接放在main函数下面了。
添加两个函数后,
4.3.1. DP83848_Init(&LAN8742)替换ethernetif.c文件中的LAN8742_Init(&LAN8742)
看划线部分

static void low_level_init(struct netif *netif)
{
省略……
/* USER CODE BEGIN PHY_PRE_CONFIG */
HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_SET);
HAL_Delay(50);
HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_RESET);
HAL_Delay(50);
HAL_GPIO_WritePin(ETH_RST_GPIO_Port,ETH_RST_Pin,GPIO_PIN_SET);
HAL_Delay(50);
#if 0
/* USER CODE END PHY_PRE_CONFIG */
/* Set PHY IO functions */
LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
/* Initialize the LAN8742 ETH PHY */
if(LAN8742_Init(&LAN8742) != LAN8742_STATUS_OK)
{
netif_set_link_down(netif);
netif_set_down(netif);
return;
}
if (hal_eth_init_status == HAL_OK)
{
/* Get link state */
ethernet_link_check_state(netif);
}
else
{
Error_Handler();
}
#endif /* LWIP_ARP || LWIP_ETHERNET */
/* USER CODE BEGIN LOW_LEVEL_INIT */
#endif
/* DP83484 INIT */
/* Set PHY IO functions */
LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx);
/* Initialize the LAN8742 ETH PHY */
if(DP83848_Init(&LAN8742) != LAN8742_STATUS_OK)
{
netif_set_link_down(netif);
netif_set_down(netif);
return;
}
if (hal_eth_init_status == HAL_OK)
{
/* Get link state */
ethernet_link_check_state(netif);
}
else
{
Error_Handler();
}
/* USER CODE END LOW_LEVEL_INIT */
}
4.3.2. DP83848_GetLinkState(&LAN8742)替换ethernetif.c文件中的LAN8742_GetLinkState(&LAN8742)
各一处,替换完成后,记得确认相应头文件是否包含。
第二处比较麻烦,每次生成后都要修改!

void ethernet_link_check_state(struct netif *netif)
{
ETH_MACConfigTypeDef MACConf = {0};
int32_t PHYLinkState = 0;
uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;
PHYLinkState = DP83848_GetLinkState(&LAN8742);
省略……
}
三、裸机工程开发:转由AC6 编译
记得在MDK中修改

5.1. cc.h 中修改:

5.2. lwip.h 中添加:

#define __CC_ARM
5.3. ethernetif.c 中修改:这里仅改了 MDK 环境下(H7 必须改)
对于 H7 来说不止要改两个接口文件(之前参考一篇配置 F4 的文章),这里 H7 因为以太网 DMA 描述符的地址问题,涉及到了数组定义指定 SRAM 问题,用到了汇编,但是又因为 AC5/6 的汇编改变问题,所以要多改一个地方!

#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location=0x30040000
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
#pragma location=0x30040060
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
__attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
#elif defined ( __GNUC__ ) /* GNU Compiler */
#if !(__ARMCC_VERSION >= 6010050) /* 不是AC6编译器,即使用AC5编译器时 */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
#else /* 使用AC6编译器时 */
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".bss.ARM.__at_0x30040000"))); /* Ethernet Rx DMA Descriptors */
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".bss.ARM.__at_0x30040060"))); /* Ethernet Tx DMA Descriptors */
#endif
#endif
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma location = 0x30040200
extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#elif defined ( __GNUC__ ) /* GNU */
#if !(__ARMCC_VERSION >= 6010050) /* 不是AC6编译器,即使用AC5编译器时 */
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
#else /* 使用AC6编译器时 */
extern u8_t memp_memory_RX_POOL_base[] __attribute__((section(".bss.ARM.__at_0x30040200")));
#endif
#endif
四、FreeRTOS - 开发部分
待更新


368

被折叠的 条评论
为什么被折叠?



