一 LWIP内存管理
lwip初始化 lwip_comm_init() 函数开始进入
ETH_Mem_Malloc() 函数,为ETH底层驱动申请内存,申请的内部SRAM的内存,跟配置了ETH_RXBUFNB、ETH_TXBUFNB、ETH_RX_BUF_SIZE、ETH_TX_BUF_SIZE 有关系
u8 ETH_Mem_Malloc(void)
{
DMARxDscrTab = mymalloc(SRAMIN,ETH_RXBUFNB*sizeof(ETH_DMADESCTypeDef));//申请内存 5 * 32
DMATxDscrTab = mymalloc(SRAMIN,ETH_TXBUFNB*sizeof(ETH_DMADESCTypeDef));//申请内存 5 * 32
Rx_Buff = mymalloc(SRAMIN,ETH_RX_BUF_SIZE*ETH_RXBUFNB); //申请内存 1524 * 5
Tx_Buff = mymalloc(SRAMIN,ETH_TX_BUF_SIZE*ETH_TXBUFNB); //申请内存 1524 * 5
if(!DMARxDscrTab||!DMATxDscrTab||!Rx_Buff||!Tx_Buff)
{
ETH_Mem_Free();
return 1; //申请失败
}
//160 + 160 + 7620 + 7620 = 15560
return 0; //申请成功
}
lwip_comm_mem_malloc() 函数,为lwip 内核部分申请内存, 里面这个函数有点难以理解,大概意思是包括 "memp_std.h"文件申明的大小全加起来再加上MEM_ALIGNMENT-1的长度,就是length。
剩下的也是一些配置影响了申请的内存大小,比如MEM_SIZE,内核任务申请的堆栈TCPIP_THREAD_STACKSIZE,给DHCP任务申请的堆栈 LWIP_DHCP_STK_SIZE
大概长度为 // 19423 + 16028 + 1000*4 + 256*4 = 40475,根据配置不同变化较大
//得到memp_memory数组大小
u32 memp_get_memorysize(void)
{
u32 length=0;
length = (
MEM_ALIGNMENT-1 //全局型数组 为所有POOL分配的内存空间
#define LWIP_MEMPOOL(name,num,size,desc)+((num)*(MEMP_SIZE+MEMP_ALIGN_SIZE(size)))//MEMP_SIZE表示需要在每个POOL头部预留的空间 MEMP_SIZE = 0
#include "lwip/memp_std.h"
);
return length;
}
到这儿,需要的内存申请基本完成,下面是初始化函数 LAN8720_Init() 。
二 实现网口热插拔功能
在内存申请失败,或者LAN8720初始化失败时,需要释放内存
if(ETH_Mem_Malloc()) //15.2K
return 1; //内存申请失败
if(lwip_comm_mem_malloc()) //39.6K
{
ETH_Mem_Free();
return 1; //内存申请失败
}
if(LAN8720_Init())
{
ETH_Mem_Free();
lwip_comm_mem_free();
return 2; //初始化LAN8720失败
}
先定义一个全局变量 EthInitStatus,然后在 LAN8720_Init() ---> ETH_MACDMA_Config() ---> 修改一下配置,主要记录一下初始配置是否成功
EthInitStatus = ETH_Init(Ð_InitStructure,LAN8720_PHY_ADDRESS); //配置ETH
if(EthInitStatus == ETH_SUCCESS)//配置成功
{
ETH_DMAITConfig(ETH_DMA_IT_NIS|ETH_DMA_IT_R,ENABLE); //使能以太网接收中断
}
return EthInitStatus;
然后通过循环读取网线的连接状态和自动协商状态的变化,判断是否网线断连,数据手册上有写这两个状态在哪
先在 lan8720.c底部编写一下如下