Files
ETH_TCP_Demo/lwip/port/drv_eth.c
2026-03-09 15:34:18 +08:00

145 lines
3.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "drv_eth.h"
#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/timeouts.h"
#include "netif/etharp.h"
#include "lwip/ethip6.h"
#include "osal.h"
#include "hal.h"
#include <string.h>
/* 硬件抽象层操作结构体 */
static const hal_ops_t *hal_ops = NULL;
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
(void)netif;
err_t errval;
uint8_t *buffer = NULL;
uint32_t len = p->tot_len;
/* 分配缓冲区 */
buffer = (uint8_t *)mem_malloc(len);
if (buffer == NULL) {
return ERR_MEM;
}
/* 复制数据到缓冲区 */
pbuf_copy_partial(p, buffer, len, 0);
/* 使用硬件抽象层发送数据 */
if (hal_ops && hal_ops->eth && hal_ops->eth->send(buffer, len) == HAL_STATUS_OK) {
errval = ERR_OK;
} else {
errval = ERR_IF;
}
/* 释放缓冲区 */
mem_free(buffer);
return errval;
}
static struct pbuf * low_level_input(struct netif *netif)
{
(void)netif;
struct pbuf *p = NULL;
uint8_t *buffer = NULL;
uint32_t rxLength = 0;
/* 分配缓冲区 */
buffer = (uint8_t *)mem_malloc(ETH_RX_BUF_SIZE);
if (buffer == NULL) {
return NULL;
}
/* 使用硬件抽象层接收数据 */
if (hal_ops && hal_ops->eth && hal_ops->eth->recv(buffer, &rxLength, 100) == HAL_STATUS_OK)
{
if (rxLength > 0 && buffer != NULL) {
/* 尝试使用 PBUF_REF 模式创建 pbuf实现零拷贝 */
p = pbuf_alloc(PBUF_RAW, rxLength, PBUF_POOL);
if (p != NULL) {
pbuf_take(p, buffer, rxLength);
} else {
osal_log_e("pbuf_alloc failed");
}
}
} else {
/* ReadData failed, maybe no data available */
}
/* 释放缓冲区 */
mem_free(buffer);
return p;
}
void ethernetif_input(struct netif *netif)
{
struct pbuf *p;
do {
p = low_level_input(netif);
if (p != NULL)
{
// osal_log_i("Rx: len=%d", p->tot_len); // Debug print
if (netif->input(p, netif) != ERR_OK)
{
pbuf_free(p);
}
}
} while(p != NULL);
}
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
netif->hostname = "lwip";
#endif
netif->name[0] = 'e';
netif->name[1] = 't';
netif->output = etharp_output;
netif->linkoutput = low_level_output;
/* 获取硬件抽象层操作结构体 */
hal_ops = hal_get_ops();
if (hal_ops == NULL) {
osal_log_e("Failed to get HAL ops");
return ERR_IF;
}
/* 配置网络接口 */
netif->hwaddr_len = 6;
/* MAC地址由硬件抽象层初始化 */
netif->mtu = 1500;
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
#if LWIP_IPV6
netif->flags |= NETIF_FLAG_IGMP;
#endif
return ERR_OK;
}
void ethernet_link_check_state(struct netif *netif)
{
if (hal_ops && hal_ops->eth) {
if (hal_ops->eth->get_link_status() == HAL_STATUS_OK) {
if (!netif_is_link_up(netif)) {
netif_set_link_up(netif);
osal_log_i("Ethernet Link Up");
}
} else {
if (netif_is_link_up(netif)) {
netif_set_link_down(netif);
osal_log_i("Ethernet Link Down");
}
}
}
}