使用GPIO判断网线拔插
USB网卡和以太网交换机“常连”后,增加交换机插拔网线判断机制
这个项目已经做了小半年了,客户是一个做智能电话机的。所谓的智能电话就是一台可以插网线、电话线,外观却是座机的手机。
客户的需求特别奇葩,USB网卡和一个内部的交换机直接通过PCB走线相连接。这个设计导致了系统在插入网线并且网卡link up上报后,网卡就一直处于连接状态,无法判断交换机的wan口网线是否拔出。后面经过大家的会议商讨,决定将交换机wan口led接口引出并接到我们的模块上,利用GPIO去判断LED闪烁状态来设置网卡状态。
于是乎,这个问题就首先落到了BSP这边,而后又落到了我这边,简单讲一下思路:DM9601作为USB网卡,driver_info(usbnet.h)中有一个.status的方法,用于轮询网卡状态。
/* for status polling */ void (*status)(struct usbnet *, struct urb *); // 驱动的具体实现 static void dm9601_status(struct usbnet *dev, struct urb *urb) { int link; u8 *buf; /* format: b0: net status b1: tx status 1 b2: tx status 2 b3: rx status b4: rx overflow b5: rx count b6: tx count b7: gpr */ if (urb->actual_length < 8) return; buf = urb->transfer_buffer; link = !!(buf[0] & 0x40); if (netif_carrier_ok(dev->net) != link) { usbnet_link_change(dev, link, 1); netdev_dbg(dev->net, "Link Status is: %d\n", link); } }
通过观察log发现每次插拔网线都会在轮询函数中触发log,再深入分析后发现确实是由该函数来实现网卡link up/down的设置。
于是增加修改如下:
extern struct gpio_desc * eth_switch_gpiod_get(void); static void dm9601_status(struct usbnet *dev, struct urb *urb) { int link; u8 *buf; int cnt; int val; struct gpio_desc * gpiod = NULL; /* format: b0: net status b1: tx status 1 b2: tx status 2 b3: rx status b4: rx overflow b5: rx count b6: tx count b7: gpr */ if (urb->actual_length < 8) return; buf = urb->transfer_buffer; link = !!(buf[0] & 0x40); netdev_info(dev->net, "%s link:%d\n", __func__, link); cnt = 0; gpiod = eth_switch_gpiod_get(); if (!IS_ERR_OR_NULL(gpiod)) { while (link && (val = gpiod_get_value(gpiod))) { netdev_info(dev->net, "gpio%d:%d\n", desc_to_gpio(gpiod), val); if (cnt++ > 5) { netdev_info(dev->net, "%s link down\n", __func__); usbnet_link_change(dev, 0, 1); return; } mdelay(100); } } if (netif_carrier_ok(dev->net) != link) { usbnet_link_change(dev, link, 1); netdev_info(dev->net, "Link Status is: %d\n", link); } }
解决思路:首先判断当前网卡状态,其次通过GPIO判断LED灯状态,为了防止误判增加重试机制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具