要将 IS32CG5317 PHY 芯片驱动融入 RT-Thread 网络体系并支持自定义 HPGP 报文(0x88E1),需完成以下关键步骤:
创建 struct netdev 的子类,实现底层操作:
#include
static const struct rt_eth_phy_ops phy_ops = {
.init = phy_init,
.read = phy_reg_read,
.write = phy_reg_write,
};
static rt_err_t eth_tx(rt_device_t dev, struct pbuf* p) {
// 将 pbuf 数据通过 SPI 发送到 PHY
spi_send(p->payload, p->len);
return RT_EOK;
}
static struct pbuf* eth_rx(rt_device_t dev) {
// 从 SPI 读取以太网帧并返回 pbuf
struct pbuf* p = pbuf_alloc(PBUF_RAW, FRAME_SIZE, PBUF_POOL);
spi_receive(p->payload, &p->len);
return p;
}
static const struct rt_eth_dev_ops eth_ops = {
.eth_tx = eth_tx,
.eth_rx = eth_rx,
};
int phy_driver_register(void) {
struct eth_device* eth_dev = rt_malloc(sizeof(struct eth_device));
eth_dev->phy_ops = &phy_ops;
eth_dev->parent.ops = ð_ops;
rt_eth_device_init(eth_dev, "spi0");
return 0;
}
INIT_DEVICE_EXPORT(phy_driver_register);修改 ethernetif.c 中的底层收发函数:
err_t ethernetif_input(struct netif *netif) {
struct pbuf *p;
while ((p = eth_rx(netif)) != NULL) {
if (p->len > 0) {
// 识别 VLAN 标签(可选)
struct eth_hdr* ethhdr = (struct eth_hdr*)p->payload;
if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
// 处理 VLAN 标签
struct eth_vlan_hdr* vlan = (struct eth_vlan_hdr*)(ethhdr + 1);
ethhdr->type = vlan->tpid;
}
// 传递到上层
netif->input(p, netif);
}
}
return ERR_OK;
}在 lwipopts.h 中启用原始链路层访问:
#define LWIP_RAW 1 // 启用 RAW API
#define ETH_PAD_SIZE 0 // 禁用填充注册自定义协议处理回调:
// 定义 HPGP 类型 (0x88E1)
#define ETHTYPE_HPGP 0x88E1
static struct raw_pcb *hpgp_pcb = NULL;
void hpgp_input(struct raw_pcb *pcb, struct pbuf *p, struct netif *inp) {
// 应用层处理 HPGP 报文
rt_kprintf("Received HPGP frame, len: %dn", p->tot_len);
pbuf_free(p);
}
void hpgp_init(void) {
hpgp_pcb = raw_new(PP_NTOHS(ETHTYPE_HPGP)); // 绑定到 0x88E1
if (hpgp_pcb) {
raw_recv(hpgp_pcb, hpgp_input, NULL);
}
}
INIT_COMPONENT_EXPORT(hpgp_init);发送 HPGP 报文:
void send_hpgp_frame(void) {
struct pbuf* p = pbuf_alloc(PBUF_RAW, HPGP_SIZE, PBUF_RAM);
struct eth_hdr* ethhdr = (struct eth_hdr*)p->payload;
// 填充目标 MAC、源 MAC 和 HPGP 类型
memcpy(ethhdr->dest, dest_mac, 6);
memcpy(ethhdr->src, src_mac, 6);
ethhdr->type = PP_HTONS(ETHTYPE_HPGP);
// 填充 HPGP 数据
memcpy((char*)ethhdr + sizeof(struct eth_hdr), hpgp_data, data_len);
// 通过网卡发送
netif->linkoutput(netif, p);
pbuf_free(p);
}接收 HPGP 报文(通过 RAW Socket):
int hpgp_sock = socket(PF_PACKET, SOCK_RAW, htons(ETHTYPE_HPGP));
struct sockaddr_ll sll;
memset(&sll, 0, sizeof(sll));
sll.sll_ifindex = netif_get_index(netif); // 绑定到网卡
bind(hpgp_sock, (struct sockaddr*)&sll, sizeof(sll));
// 接收线程
void hpgp_recv_thread(void) {
while(1) {
char buf[1500];
recv(hpgp_sock, buf, sizeof(buf), 0);
// 处理 HPGP 数据...
}
}AF_INET + SOCK_STREAM/SOCK_DGRAM)PF_PACKET + SOCK_RAW)sys_mutex)保护协议栈资源struct eth_hdr 包含 VLAN 字段:struct eth_vlan_hdr {
u16_t tpid; // 0x8100
u16_t tci; // Priority + VLAN ID
u16_t proto; // 上层协议 (HPGP/TCP/UDP)
};phy_ops 和 eth_ops 完成 SPI-PHY 通信// lwipopts.h
#define LWIP_RAW 1 // 启用 RAW Socket
#define LWIP_NETIF_LOOPBACK 1 PF_PACKET + SOCK_RAW 收发通过以上步骤,您的 PHY 驱动将无缝集成到 RT-Thread 网络栈,同时支持 TCP/UDP 和自定义 HPGP 报文的多协议并行处理。
举报
更多回帖