一、lwip网卡接口ethernetif.c
ethernetif.c是lwip的网卡接口,在该接口中处理网卡的数据接收和发送,rt-thread在该接口文件中抽象了一个eth_device,管理网络数据的收发和向内核的netdev_list添加netdev。
二、网络设备eth_device
eth_device是rt-thread实现的ethernetif。
struct eth_device
{
/* inherit from rt_device /
struct rt_device parent;
/ network interface for lwip */
struct netif netif;
struct rt_semaphore tx_ack;
rt_uint16_t flags;
rt_uint8_t link_changed;
rt_uint8_t link_status;
/ eth device interface /
struct pbuf (*eth_rx)(rt_device_t dev);
rt_err_t (eth_tx)(rt_device_t dev, struct pbuf p);
};
netif:lwip的网络接口。
eth_rx:底层数据接收接口。
eth_tx:底层数据发送接口。
三、网络设备数据的接收和发送
网络设备的接收和发送通过eth_device的eth_rx和eth_tx完成。在系统初始化时内核调用eth_system_device_init创建erx和etx两个线程,用于处理接收和发送。
3.1 数据接收
当erx线程起来后,等待eth_rx_thread_mb,当网卡准备好或者改变网卡状态时,往下执行,进入while(1)处理网卡接收,调用网卡注册的eth_rx接收网卡数据,并传递给协议栈上层。
static void eth_rx_thread_entry(void* parameter)
{
struct eth_device* device;
while (1)
{
if (rt_mb_recv(ð_rx_thread_mb, (rt_ubase_t*)&device, rt_waiting_forever) == rt_eok)
{
struct pbuf p;
/ check link status /
if (device->link_changed)
{
int status;
rt_uint32_t level;
level = rt_hw_interrupt_disable();
status = device->link_status;
device->link_changed = 0x00;
rt_hw_interrupt_enable(level);
if (status)
netifapi_netif_set_link_up(device->netif);
else
netifapi_netif_set_link_down(device->netif);
}
/ receive all of buffer /
while (1)
{
if(device->eth_rx == rt_null) break;
p = device->eth_rx(&(device->parent));
if (p != rt_null)
{
/ notify to upper layer */
if( device->netif->input(p, device->netif) != err_ok )
{
lwip_debugf(netif_debug, (ethernetif_input: input errorn));
pbuf_free(p);
p = null;
}
}
else break;
}
}
else
{
lwip_assert(should not happen!n,0);
}
}
}
3.2 数据发送
当协议栈需要发送数据时,调用netif的linkoutput接口,在linkoutput中,将数据封装成消息发送给etx线程,最终通过eth_device的eth_tx接口将数据发送出去。
static void eth_tx_thread_entry(void* parameter)
{
struct eth_tx_msg* msg;
while (1)
{
if (rt_mb_recv(ð_tx_thread_mb, (rt_ubase_t*)&msg, rt_waiting_forever) == rt_eok)
{
struct eth_device* enetif;
rt_assert(msg->netif != rt_null);
rt_assert(msg->buf != rt_null);
enetif = (struct eth_device*)msg->netif->state;
if (enetif != rt_null)
{
/* call driver's interface /
if (enetif->eth_tx(&(enetif->parent), msg->buf) != rt_eok)
{
/ transmit eth packet failed /
}
}
/ send ack */
rt_sem_release(&(enetif->tx_ack));
}
}
}
四、wlan设备数据的接收和发送
wlan设备的数据接收和发送是通过rt_wlan_prot完成的,rt_wlan_prot是对不同协议簇的抽象,在rt_wlan_set_mode启动wlan设备时,最终会调用rt_wlan_prot_attach将lwip协议簇挂载到wlan设备,在挂载过程中,会根据协议簇的名称匹配注册的rt_wlan_prot,并调用rt_wlan_prot的register将wlan设备注册到内核。
4.1 数据接收
在网卡的接收中断中,调用rt_wlan_dev_transfer_prot将网卡设备接收的数据传递给上层处理。
rt_err_t rt_wlan_dev_transfer_prot(struct rt_wlan_device *wlan, void *buff, int len)
{
struct rt_wlan_prot *prot = wlan->prot;
if (prot != rt_null)
{
return prot->ops->prot_recv(wlan, buff, len);
}
return -rt_error;
}
注册到rt_wlan_prot的接收函数是rt_wlan_lwip_protocol_recv,在rt_wlan_lwip_protocol_recv中,通过lwip_prot_des获取eth_device(netif在eth_device_init_with_flag中被注册到eth_device),接着便可使用其中的netif的input将数据交给上层。
static rt_err_t rt_wlan_lwip_protocol_recv(struct rt_wlan_device *wlan, void *buff, int len)
{
struct eth_device *eth_dev = &((struct lwip_prot_des *)wlan->prot)->eth;//eth在rt_wlan_lwip_protocol_register中注册
struct pbuf *p = rt_null;
//...省略
{
p = buff;
if ((eth_dev->netif->input(p, eth_dev->netif)) != err_ok)
{
return -rt_error;
}
return rt_eok;
}
//...省略
}
4.2 数据发送
当协议栈需要发送数据时,会调用rt_wlan_prot_transfer_dev将数据传递给wlan设备,在rt_wlan_prot_transfer_dev中,会调用wlan设备的发送接口将数据发送出去。
4.3 以w601举例
w601的wlan驱动在driver文件夹下的drv_wifi.c。
4.3.1 数据接收
在内核需要初始化wlan的时候,调用drv_wlan_init,在tls_ethernet_data_rx_callback函数中注册wm_ethernetif_input到wifi接收中断,在wm_ethernetif_input中调用rt_wlan_dev_transfer_prot将接收的数据传给协议栈上层。
4.3.2 数据发送
在drv_wifi.c中,将drv_wlan_send函数注册到发送接口,在协议栈需要发送数据时,通过rt_wlan_prot_transfer_dev调用这个接口完成数据的发送。
static const struct rt_wlan_dev_ops ops =
{
//...省略
.wlan_recv = drv_wlan_recv,
.wlan_send = drv_wlan_send,/ 向内核注册的发送接口 /
};
浅谈板对板连接器故障原因
三星GalaxyNote9评测 值不值得买
日本在电动汽车普及方面将导入AI服务
【回顾往年CES】小米发布行业最薄电视,微鲸不服,也发一款同样薄的电视
等保2.0亮点多多 保障新技术落脚安防
RT-Thread源码分析之网卡数据的接收和发送
信息通信技术促进可持续发展目标实现,爱立信是其业务战略之一
星逻智能荣获“2023年度最具影响力光伏运维企业”称号
如何用C语言开发DSP嵌入式系统?
如何在 Linux 下检测内存泄漏
人工智能ai需要什么专业
如何推广智能计量来实现智慧生活?
Lot number是什么,它在芯片流通过程中的作用
求解三极管电路的输出电位值
Ziitek高导热硅脂在汽车LED头尾灯中的应用
大数据和人工智能共同开启产业发展新时代
调制波、电源纹波、上电时序测量新体验
工信部副司长陈立东对我国加快推进5G商用进程提出了三点建议
中国电信上官亚非:5G高质量发展的四大典型需求探索
SMT集成电路板MES系统解决方案