S32K3+lwip裸机(四)Lwip2.1.2接口说明
主要接口说明
“u32_t sysnow(void)”
这是一个已经在lwip内部调用的函数,由lwip调用,其返回的值赋值给now变量,其返回的值为“ms变量”,所谓的ms变量为定义一个全局变量(g_i_tick_cnt),每1ms其值增加1,将这个值返回给与lwip用以精确确定时间的变化。当全局变量(g_i_tick_cnt)达到一定值归零后lwip会主动计算最大值到最小值的一个跳跃。矫正其时间的计算累计。
“sys_check_timeouts()”
这是一个在while循环调用的执行函数。
**"netif_output(struct netif netif, struct pbuf p)"
这个为网卡数据输出函数由lwip调用,在这个函数里面调用网卡输出驱动函数,将数据发送出去,其中数据在struct netif结构体中。
“lwip_INIT()”
这是一个自建私有函数,其目的是将lwip内的一些数据神奇空间,函数指针实例化。其中主要包括lwip_init()函数,netif_add(&netif, &ipaddr, &netmask, &gw, NULL, &Mynetif_init, &netif_input)注册input 函数,netif_set_status_callback(&netif, netif_status_callback) 注册状态函数 ,netif_set_default(&netif)设置初始化状态。
*"Mynetif_init(struct netif netif)"
这是一个自建函数,放在初始化中主要包含对netif->linkoutpu的初始化(函数指针赋值),netif->output的初始化(函数指针赋值)。netif->mut初始化,netif->flags初始化。
netif.input(&RecivePbuf, &netif)
这个是一个往lwip输入的数据的接口,通过中断将数填入RecivePbuf将数据传入lwip进行处理。
这里记得要netif_set_up(&netif),将lwip内的网卡状态设置为链接状态,否则网卡状态不对则不能恢复将数据包丢弃。
下面为我所用的一些接口代码
/*
* HWGMAC_Port.c
*
* Created on:
* Author:
*/
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "netif/ethernet.h"
#include "lwip/ip4_addr.h"
#include "lwip/etharp.h"
#include "Gmac_Ip.h"
#include <string.h>
#define EthInstance 0U
#define EthTimeoutMs 100U
#define ETHERNET_MTU 1050U
boolean Result = TRUE;
struct netif netif;
struct pbuf RecivePbuf;
uint32 g_i_tick_cnt;
uint8_t MyTemRxbuffer[1536];
Gmac_Ip_TxOptionsType TxOptions = {TRUE, GMAC_CRC_AND_PAD_INSERTION, GMAC_CHECKSUM_INSERTION_DISABLE};
Gmac_Ip_BufferType TxBuffer = {0};
Gmac_Ip_BufferType RxBuffer = {0};
Gmac_Ip_TxInfoType TxInfo = {0};
Gmac_Ip_RxInfoType RxInfo = {0};
Gmac_Ip_StatusType Status;
uint8 MacAddr[6U] = {0U};
ip4_addr_t ipaddr;
ip4_addr_t netmask;
ip4_addr_t gw;
/*******************while()************/
void LoopShedule(void)
{
sys_check_timeouts();
}
/*******************LWI回调************/
u32_t sys_now(void)
{
return g_i_tick_cnt;
}
/*********************1ms中断************/
void GMACShedule_1ms(void)
{
struct pbuf ARPBoradPbuf;
g_i_tick_cnt ++;
if(g_i_tick_cnt >1000)
{
g_i_tick_cnt =0;
}
}
/*********************打印************************/
static void netif_status_callback(struct netif *netif)
{
// printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif)));
}
uint8_t mac_send_buffer[1053]={0};
/***********************网卡输出********************/
static err_t netif_output(struct netif *netif, struct pbuf *p)
{
TxBuffer.Data =NULL;
LINK_STATS_INC(link.xmit);
pbuf_copy_partial(p, mac_send_buffer, p->len, 0);
/* Start MAC transmit here */
Gmac_Ip_GetMacAddr(INST_GMAC_0, MacAddr); //网卡函数
if((mac_send_buffer[12]==0x08)&&(mac_send_buffer[12]==0x06))
{
for (uint8 i = 6U; i < 12U; i++)
{
mac_send_buffer[i] = MacAddr[i-6];
mac_send_buffer[i+22-6] = MacAddr[i-6];
}
}
if(p->len <64-4)
{
TxBuffer.Length =64U-4U;
}
else
{
TxBuffer.Length=p->len;
}
if ((GMAC_STATUS_SUCCESS != Gmac_Ip_GetTxBuff(INST_GMAC_0, 0U, &TxBuffer, NULL_PTR)) || (TxBuffer.Length < 64-4U))
{
Result = FALSE;
}
/* Send the ETH frame */
/* Don't count FCS, because it is automatically inserted by the controller in this example */
if(p->len <64-4)
{
TxBuffer.Length = 64U - 4U;
}
else
{
TxBuffer.Length=p->len;
}
TxBuffer.Data=mac_send_buffer;
/* Payload = Frame - (DstAddr + SrcAddr + EtherType/Length + FCS) */
if (GMAC_STATUS_SUCCESS != Gmac_Ip_SendFrame(INST_GMAC_0, 0U, &TxBuffer, &TxOptions)) //网卡函数
{
Result = FALSE;
}
}
/***********************lwip初始化中的lwip_add的函数指针实例化*****************************/
static err_t Mynetif_init(struct netif *netif)
{
netif->linkoutput = netif_output;
netif->output = etharp_output;
netif->mtu = ETHERNET_MTU;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
return ERR_OK;
}
/**************************lwip初始化****************************/
void GMAC_LibInit(void)
{
/* IP addresses initialization */
/* USER CODE BEGIN 0 */
#ifdef USE_DHCP
ip_addr_set_zero_ip4(&ipaddr);
ip_addr_set_zero_ip4(&netmask);
ip_addr_set_zero_ip4(&gw);
#else
IP4_ADDR(&ipaddr,192,168,0,11);
IP4_ADDR(&netmask,255,255,255,0);
IP4_ADDR(&gw,192,169,0,1);
#endif /* USE_DHCP */
/* USER CODE END 0 */
lwip_init();
/* add the network interface (IPv4/IPv6) without RTOS */
netif_add(&netif, &ipaddr, &netmask, &gw, NULL, &Mynetif_init, &netif_input); //注册input回调函数来接收网卡数据
netif.name[0] = 'e';
netif.name[1] = '0';
netif_set_status_callback(&netif, netif_status_callback);
netif_set_default(&netif);
}
void GMAC_Tx_IrqHander(uint8 instance, uint8 channel)
{
}
void GMAC_Rx_IrqHander(uint8 instance, uint8 channel)
{
if(instance !=INST_GMAC_0 || channel !=0)
return ;
uint8_t Result=TRUE;
RxBuffer.Length =0;
RxBuffer.Data = NULL;
memset(MyTemRxbuffer,0,sizeof(MyTemRxbuffer));
/* Wait for the frame to be received */
do {
Status = Gmac_Ip_ReadFrame(INST_GMAC_0, 0U, &RxBuffer, &RxInfo);//网卡函数
} while (Status == GMAC_STATUS_RX_QUEUE_EMPTY);
Gmac_Ip_ProvideRxBuff(INST_GMAC_0, 0U, &RxBuffer);
/* Check the frame status */
if ((GMAC_STATUS_SUCCESS != Status) || (0U != RxInfo.ErrMask))
{
Result = FALSE;
}
if( Result != FALSE)
{
memcpy(MyTemRxbuffer,RxBuffer.Data,RxBuffer.Length);
RecivePbuf.payload =RxBuffer.Data;
RecivePbuf.tot_len =RxBuffer.Length;
RecivePbuf.len =RxBuffer.Length;
netif.num =instance;
netif_set_up(&netif);
netif.input(&RecivePbuf, &netif);/* 接收数据传入Lwip */
}
}