📄 ethernetif.c
字号:
#include <rtthread.h>
#include "lwip/debug.h"
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "netif/etharp.h"
#include "netif/ethernetif.h"
/* the interface provided to LwIP */
err_t eth_init(struct netif *netif)
{
return ERR_OK;
}
err_t eth_input(struct pbuf *p, struct netif *inp)
{
struct eth_hdr *ethhdr;
if(p != RT_NULL)
{
#ifdef LINK_STATS
LINK_STATS_INC(link.recv);
#endif /* LINK_STATS */
ethhdr = p->payload;
switch(htons(ethhdr->type))
{
case ETHTYPE_IP:
etharp_ip_input(inp, p);
pbuf_header(p, -14);
tcpip_input(p, inp);
break;
case ETHTYPE_ARP:
etharp_arp_input(inp, (struct eth_addr *)inp->hwaddr, p);
break;
default:
pbuf_free(p);
p = RT_NULL;
break;
}
}
return ERR_OK;
}
err_t ethernetif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
{
return etharp_output(netif, p, ipaddr);
}
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
struct pbuf *q;
struct eth_device* enetif;
enetif = (struct eth_device*)netif->state;
if (enetif == RT_NULL) return -ERR_VAL;
/* call driver's interface */
if (enetif->eth_tx(&(enetif->parent), p) == RT_EOK) return ERR_OK;
return ERR_OK;
}
/* ethernetif APIs */
rt_err_t eth_device_init(struct eth_device* dev, const char* name)
{
struct netif* netif;
netif = (struct netif*) rt_malloc (sizeof(struct netif));
if (netif == RT_NULL)
{
rt_kprintf("malloc netif failed\n");
return -RT_ERROR;
}
rt_memset(netif, 0, sizeof(struct netif));
/* set netif */
dev->netif = netif;
/* register to rt-thread device manager */
rt_device_register(&(dev->parent), name, RT_DEVICE_FLAG_RDWR);
dev->parent.type = RT_Device_Class_NetIf;
/* set name */
netif->name[0] = name[0];
netif->name[1] = name[1];
/* set hw address to 6 */
netif->hwaddr_len = 6;
/* maximum transfer unit */
netif->mtu = ETHERNET_MTU;
/* broadcast capability */
netif->flags = NETIF_FLAG_BROADCAST;
/* get hardware address */
rt_device_control(&(dev->parent), NIOCTL_GADDR, netif->hwaddr);
/* set output */
netif->output = ethernetif_output;
netif->linkoutput = ethernetif_linkoutput;
/* add netif to lwip */
if (netif_add(netif, IP_ADDR_ANY, IP_ADDR_BROADCAST, IP_ADDR_ANY, dev,
eth_init, eth_input) == RT_NULL)
{
/* failed, unregister device and free netif */
rt_device_unregister(&(dev->parent));
rt_free(netif);
return -RT_ERROR;
}
netif_set_default(netif);
return RT_EOK;
}
/* eth thread */
#define RT_ETHERNETIF_THREAD_PREORITY 16
static struct rt_mailbox eth_thread_mb;
static char eth_thread_mb_pool[8 * 4];
char eth_thread_stack[1024];
struct rt_thread eth_thread;
/* ethernet buffer */
void eth_thread_entry(void* parameter)
{
struct eth_device* device;
while (1)
{
if (rt_mb_recv(ð_thread_mb, (rt_uint32_t*)&device, RT_WAITING_FOREVER) == RT_EOK)
{
struct pbuf *p;
/* receive all of buffer */
while (1)
{
p = device->eth_rx(&(device->parent));
if (p != RT_NULL)
{
/* notify to upper layer */
eth_input(p, device->netif);
}
else break;
}
}
}
}
rt_err_t eth_device_ready(struct eth_device* dev)
{
/* post message to ethernet thread */
return rt_mb_send(ð_thread_mb, (rt_uint32_t)dev);
}
rt_err_t eth_system_device_init()
{
rt_err_t result = RT_EOK;
/* init mailbox and create ethernet thread */
result = rt_mb_init(ð_thread_mb, "ethmb", ð_thread_mb_pool[0], 8, RT_IPC_FLAG_FIFO);
RT_ASSERT(result != RT_EOK);
result = rt_thread_init(ð_thread, "eth", eth_thread_entry, RT_NULL,
ð_thread_stack[0], sizeof(eth_thread_stack),
RT_ETHERNETIF_THREAD_PREORITY, 20);
RT_ASSERT(result != RT_EOK);
result = rt_thread_startup(ð_thread);
RT_ASSERT(result != RT_EOK);
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -