news 2026/10/5 5:24:53

STM32以太网ETH外设详解:从MII/RMII到lwIP调试实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32以太网ETH外设详解:从MII/RMII到lwIP调试实战

板子上电,网线插进RJ45座,电脑右下角的网络图标转了好几圈,最后跳出来一个黄色感叹号。这个画面我太熟悉了——几乎所有第一次调STM32以太网的人都会在这一步卡住。串口打印一切正常,GPIO翻转也能看到波形,但网口就是死活ping不通。

问题往往不在你写的代码,而在STM32内置的以太网外设(ETH)本身。这颗外设并没有把整个以太网方案包圆,它只负责数据链路层的MAC部分,物理层还得外挂一颗PHY芯片。很多人第一次打开STM32参考手册,看到ETH那一章密密麻麻的寄存器就头大,其实它的工作机制并不复杂。

这篇文章我打算把STM32的ETH外设从头到尾拆一遍,从它内部的MAC、DMA、MII/RMII接口这些基本结构讲起,再结合CubeMX的配置流程、常用PHY芯片的搭配、以及我实际调试中踩过的坑,把整个通信链路讲透。不管你是准备做板载以太网通信、接入lwIP跑TCP/IP协议栈,还是仅仅想把ETH外设跑通,这篇都值得认真看一遍。

1. 先搞清楚分工:STM32的ETH外设到底管到哪一层

1.1 为什么STM32不把PHY也集成进去

很多初学者有个疑问:STM32既然叫“以太网外设”,为什么还需要外接PHY芯片,不能一颗芯片全包?

这个问题的答案藏在芯片制造工艺里。MAC层是纯数字逻辑,负责组帧、拆帧、地址过滤、CRC校验这些活,用CMOS数字工艺做起来非常便宜。但PHY不一样,它要把数字信号变成能在网线上跑的电平,涉及数模混合电路、模拟信号调理、编码解码——MAC侧的数据是并行的、电平为3.3V的逻辑信号,到了网线上要变成100BASE-TX的差分信号,走MLT-3编码,电平幅度只有正负1V左右。这种模拟电路对工艺要求完全不同。

我打个比方:MAC相当于快递分拣中心,负责打包、贴单、按地址分类;PHY相当于运输车队,负责把包裹实实在在送到路上。分拣中心可以建在写字楼里,但车队必须有车库和修车厂——芯片厂商不会为了一个车队去建修车厂,直接找运输公司外包更划算。

所以你在几乎所有MCU上看到的以太网方案都是这个格局:MCU内部集成MAC,外部接一颗PHY芯片,两者之间通过MII或RMII接口连接。STM32的ETH外设,本质上就是这颗MAC加上配套的DMA控制器和接口逻辑。

1.2 一份数据从应用层到网线的完整旅程

要理解ETH外设的职责边界,最好跟一包数据走一遍完整旅程。

假设你写了一个TCP客户端程序,要往服务器发送“Hello”这几个字节。数据先进入lwIP协议栈,依次加上TCP头、IP头、以太网头,变成了一个完整的以太网帧。这个帧此刻还只是放在内存里的一段数据,它的目的地是网线。

这时ETH外设开始介入。首先是DMA控制器把帧数据搬运到ETH外设内部的发送FIFO,然后MAC内核从FIFO取出数据,做这么几件事:补上前导码和帧起始定界符(SFD),补上CRC校验字段,加上帧间隙(IFG),然后按照MII/RMII接口的时序,把数据一位一组地送给PHY芯片。

PHY收到后,再把MII接口传来的4位并行数据做并串转换,经过扰码、MLT-3编码,变成差分信号送上网线。接收路径正好反过来:PHY从网线上收模拟信号,解码后变成MII接口的数字信号送给MAC,MAC做CRC校验、地址过滤,DMA再把数据搬回内存,最后lwIP协议栈从内存里把数据取出来解析。

这份数据流就是整个以太网通信的主线。ETH外设的位置非常清晰:它在内存和PHY之间做搬运工和质检员。搞清楚这条主线,后面看任何以太网相关代码都不会犯迷糊。

2. MII、RMII与PHY芯片选型:接口选择是个连锁反应

2.1 MII和RMII在引脚和时钟上的本质差异

STM32的ETH外设支持两种MAC与PHY之间的接口:MII和RMII。它们的差别不光是引脚数量,还牵扯到时钟方案的根本不同。

MII(Media Independent Interface)是经典接口,总共需要16根信号线:

信号类型信号名称方向说明
发送数据TXD[3:0]MAC→PHY4位并行发送数据
发送使能TX_ENMAC→PHY发送有效指示
发送时钟TX_CLKPHY→MAC100M时25MHz,10M时2.5MHz
接收数据RXD[3:0]PHY→MAC4位并行接收数据
接收有效RX_DVPHY→MAC接收有效指示
接收时钟RX_CLKPHY→MAC100M时25MHz,10M时2.5MHz
载波侦听CRSPHY→MAC载波侦听状态
冲突检测COLPHY→MAC冲突检测
管理接口MDC/MDIOMAC↔PHY寄存器读写管理通道

RMII(Reduced Media Independent Interface)是精简版,把数据线从4位砍到2位,整体只需要7根信号线:

信号类型信号名称方向说明
发送数据TXD[1:0]MAC→PHY2位并行发送数据
发送使能TX_ENMAC→PHY发送有效指示
接收数据RXD[1:0]PHY→MAC2位并行接收数据
载波侦听/接收有效CRS_DVPHY→MAC合并了CRS和RX_DV
参考时钟REF_CLK双向/外部固定50MHz
管理接口MDC/MDIOMAC↔PHY寄存器读写管理通道

RMII能用一半的线干同样的活,核心秘诀是把时钟从跟随速率变化改成固定50MHz。因为数据位宽减半,为了在同样的100Mbps速率下传完数据,时钟必须翻倍到50MHz。但注意,这个50MHz是双方向共用的参考时钟,谁产生它成了一个大问题。

2.2 REF_CLK 50MHz从哪来:三种方案各有坑

我在调试RMII时被REF_CLK折腾过一整个晚上。STM32和PHY都需要这个50MHz参考时钟,但谁输出、谁输入,不同PHY芯片的接法完全不同。

方案一:外部有源晶振直接产生50MHz,同时送给STM32的ETH_REF_CLK引脚和PHY的REF_CLK引脚。这个方案最干净,两边都不用配置时钟输出功能,但需要一颗50MHz有源晶振,成本略高,PCB上还要多占一块地方。

方案二:STM32的MCO引脚输出50MHz给PHY。以STM32F407为例,MCO1(PA8)可以输出PLL48CLK分频后的时钟,配置成50MHz送给LAN8720的REF_CLK。这个方案要求MCU的时钟树正确生成PLL48CLK,后面第3节我会详细讲这个坑。

方案三:PHY自己输出50MHz给STM32。像DP83848这类PHY,内部带时钟源或能从25MHz晶振倍频出50MHz,通过CLK_OUT引脚反送给STM32。

选哪个方案不是拍脑袋决定的,要看你选的PHY支持哪种模式。LAN8720的REF_CLK既可以做输入也可以做输出,具体靠引脚配置和寄存器设置,所以开发板十有八九用MCU输出50MHz的方案。DP83848则常用25MHz晶振配合CLK_OUT输出50MHz,也有外部50MHz有源晶振的接法。

2.3 网络变压器和RJ45不是随便选的

PHY芯片和RJ45之间,还隔着一个网络变压器。这东西看着不起眼,作用却很大:隔离PHY和外部网线的直流电平、抑制共模干扰、提供阻抗匹配。RJ45座子有两种,一种自带变压器,一种不带。很多开发板用的是带变压器的HR911105A这类网口,PCB设计更省事。

有一件事必须提醒:不同PHY的变压器中心抽头接法不一样,有的接电源,有的接地,具体要看PHY数据手册里的参考电路。我之前换了一款PHY,没注意中心抽头差异,结果10Mbps勉强能通,100Mbps完全不行,查了几天才发现是这里的问题。

3. 时钟树与引脚规划:ETH初始化的两个隐形门槛

3.1 ETH外设的时钟来源与系统时钟的联动

STM32F4系列里,ETH外设的时钟挂在AHB总线上,但它的参考时钟来源很特殊——来自PLL48CLK。这意味着ETH的正常工作高度依赖系统时钟树配置正确。

我把F407的时钟树简化说明一下:外部晶振HSE进入PLL,PLL输出经过分频得到PLL48CLK(48MHz),这个48MHz时钟一路给USB、SDIO用,另一路经过二分频得到24MHz,就是ETH外设的MAC内核时钟。RMII接口那个50MHz的REF_CLK则不是这个来源,它来自MCO输出或其他时钟源,前面已经讲过。

这就导致了一个隐蔽的问题:如果外部晶振选的是8MHz,但CubeMX里系统时钟配置没正确生成PLL48CLK,USB和ETH都会异常。反过来,很多以太网开发板板载晶振是25MHz,因为25MHz经过PLL后更容易配置出各种时钟,同时还能兼顾以太网RMII参考时钟的生成。

所以你在做硬件设计时就要想清楚:如果板子上ETH和USB、SDIO共存,晶振频率的选择不是随便定的。以STM32F407为例,25MHz晶振几乎是标配,原因之一就是为了同时满足以太网和USB对时钟的要求。

3.2 RMII模式下的引脚占用与冲突排查

RMII虽然比MII少了一半引脚,但占用数仍然不少。以最常见的RMII配置为例:

引脚功能说明
PA1ETH_REF_CLKRMII参考时钟
PA2ETH_MDIO管理数据
PA7ETH_CRS_DV载波/接收有效
PC1ETH_MDC管理时钟
PC4ETH_RXD0接收数据0
PC5ETH_RXD1接收数据1
PB11ETH_TX_EN发送使能
PB12ETH_TXD0发送数据0
PB13ETH_TXD1发送数据1

一共9个引脚。看起来不多,但仔细一看就会发现,这些引脚经常和别的功能打架。我举几个真实例子。

PA2和PA3是USART2的TX/RX,如果你用了串口2做调试,就得牺牲其中一个功能。PC4、PC5在某些型号上可能复用为ADC或定时器输入。PB12是SPI2的NSS,PB13是SPI2的SCK——如果板子上还有一个SPI接口的Flash或其它外设,冲突几乎不可避免。

我建议你在画PCB之前,先拿CubeMX把所有用到的外设都配置一遍,看引脚冲突在哪里,有问题趁早调整,别等板子打回来再改。另外,ETH的引脚没有重映射选项,它的复用是固定的,只有部分型号支持通过AFIO在有限范围内切换,绝大多数情况你只能围着这9个引脚做文章。

3.3 PHY地址和MDIO时序:怎么确认PHY在跟你说话

PHY芯片和MAC之间有一条管理通道MDIO,MAC通过它读写PHY内部的寄存器。MDIO协议里每个PHY有一个地址,总线上可以挂多个PHY,靠地址区分。

LAN8720的PHY地址由芯片的PHYAD0引脚决定:接地为0,接高电平为1。DP83848可以配置成多种地址。如果你用的是CubeMX默认配置,它默认PHY地址是0,但你的板子如果恰好用的PHY地址是1,MAC根本访问不到PHY,通信自然失败。

怎么验证MAC和PHY之间通信正常?最直接的办法是读PHY的ID寄存器。LAN8720的PHYIDR1(寄存器2)值为0x0007,PHYIDR2(寄存器3)的值为0x0200。用HAL库可以这样读:

uint32_t idr1 = 0, idr2 = 0; HAL_ETH_ReadPHYRegister(&heth, PHY_ADDRESS, PHY_ISFR, &idr1); // 寄存器2 HAL_ETH_ReadPHYRegister(&heth, PHY_ADDRESS, PHY_ISFR + 1, &idr2); // 寄存器3 printf("PHY ID: 0x%04X 0x%04X\r\n", idr1, idr2);

如果读出来全是0xFFFF或者0x0000,说明MDIO通信有问题,先查PHY地址对不对、MDC/MDIO引脚是否接反、PHY供电是否正常。如果读出来是对的ID,恭喜,MAC和PHY之间的物理通道已经通了,接下来才能谈协议栈的事。

4. CubeMX里的ETH配置:从图形界面到能跑通的细节

4.1 参数面板里那些默认值背后的含义

CubeMX里配置ETH,第一步是在Connectivity里找到ETH,勾选RMII或MII。这里有个重要前提:引脚必须在CubeMX里先分配好,如果选RMII但引脚没配对,它会直接报错。

参数面板里有一堆配置项,我挑关键的说。

PHY Address,默认是0,必须改成你板上PHY的实际地址。LAN8720地址为0,DP83848在不少板子上是1,改错了连PHY都访问不了。

MAC Address,默认是一组随机地址。理论上随便填,只要不与局域网内其他设备冲突,但如果你要跑工业以太网协议,这里必须按厂商分配的地址段填。

Ethernet Speed、Duplex Mode这些参数,CubeMX默认是自动协商。如果你确定对端设备不支持自动协商,需要手动指定速率和双工模式,但绝大多数场景保持默认就好。

还有一组高级参数:DMA描述符数量、发送/接收FIFO阈值、PBL等。这些参数HAL库会给你一个默认值,一般情况下不用动。但如果你发现大数据吞吐时丢包,DMA描述符数量是最值得调高的参数之一。默认4个RX描述符做大数据接收时确实偏少,我后来改成8个才稳。

4.2 DMA描述符:lwIP能干活的前提

ETH外设里的DMA控制器的设计有点特殊:它不靠传统的中断寄存器列表来管理数据包,而是用一套称为“描述符”的内存结构。

每个以太网DMA描述符对应一个缓冲区,描述符里存放着缓冲区的地址、长度、状态标志。DMA从第一个描述符开始,循环处理完一个再处理下一个,全部用完后又回到第一个,形成一个环。这就是所谓的“描述符环”。

这段描述符数组放在哪里,直接影响系统稳定性。F4系列里有一块CCM内存,只能CPU直接访问,DMA访问不了,描述符绝对不能放那里。H7系列还有D2域SRAM,只有ETH的DMA能访问,放描述符倒是对了。F4没有这么讲究,你只要保证描述符放在普通SRAM区域就可以,CubeMX生成的代码会自动分配好。

一个常见的坑是:你在链接脚本或启动文件里改了内存布局,把描述符数组挤到了错误的位置,结果DMA读写异常,ETH收发数据时好时坏。排查这个问题最直接的手段是检查描述符地址是否在DMA可访问的区域内,以及是否4字节对齐。

4.3 lwIP的堆与内存池:参数调不好,ping都不通

CubeMX里勾选LWIP后,会生成一套默认配置。很多人直接编译下载,发现能初始化但ping不通,然后就开始怀疑ETH硬件有问题。其实很多时候是lwIP内存配置不合格。

lwIP有两种内存管理方式:内存堆(heap)和内存池(pool)。TCP/UDP报文的数据缓冲使用PBUF,每种PBUF的数量和大小在lwipopts.h里配置。CubeMX生成的配置默认偏保守,如果你开了TCP服务器,一上来开了好几个连接,PBUF不够分配,协议栈直接收包失败。

我的建议参数如下(在内存充足的STM32F407上):

#define MEM_SIZE (10 * 1024) // 内存堆大小,10KB起步 #define PBUF_POOL_SIZE 16 // PBUF池数量 #define PBUF_POOL_BUFSIZE 1518 // 单个PBUF大小,一个以太网帧 #define TCP_MSS 1460 // 最大分段大小 #define TCP_WND (4 * TCP_MSS) // TCP接收窗口 #define TCP_SND_BUF (4 * TCP_MSS) // TCP发送缓冲

这几个参数是联动的,不是随便填。PBUF_POOL_BUFSIZE必须能容纳一个完整以太网帧(1518字节),否则大的数据包会被截断。TCP_WND和TCP_SND_BUF决定单条TCP连接的吞吐量,如果做文件传输这类大流量应用,它们应该设得更大一些。

我见过太多人在协议栈参数上被坑:调大MEM_SIZE就以为万事大吉,实际跑起来发现内存碎片严重,长时间运行后连接越来越不稳定。lwIP的参数调优是个系统工程,建议先用默认配置跑通,再根据实际业务流量逐步调整。

5. 实战排查:ping不通时我按这个顺序定位

5.1 物理层先过:PHY的link状态是第一个信号

当ping不通的时候,我从不先在协议栈里瞎翻。第一步永远是验证PHY有没有建立物理链路。

以太网的物理层连接建立有一个分工:PHY芯片通过自动协商与对端设备达成速率和双工模式的一致,然后由MAC配置PHY,最后链路才进入up状态。判断这个状态最简单的方法是读PHY的基本状态寄存器(BSR)。以LAN8720为例,寄存器1的bit2是Link Status,为1表示链路已建立。

uint32_t bsr = 0; HAL_ETH_ReadPHYRegister(&heth, PHY_ADDRESS, PHY_BSR, &bsr); if (bsr & (1 << 2)) { printf("Link UP\r\n"); } else { printf("Link DOWN\r\n"); }

如果Link DOWN,先别碰代码。查网线是否插好、对端设备是否开机电口指示灯亮没亮、网口座的指示灯状态。然后查PHY供电电压对不对——LAN8720是3.3V供电,但它的I/O耐压有的版本支持2.5V,接线方式差别很大。再查网络变压器的中心抽头接法是否和数据手册一致。之前我碰到过一个板子,LAN8720的供电滤波电容没放对位置,PHY工作不稳定,link时好时坏,最后在靠近电源引脚的地方补了一颗电容才解决。

Link UP了还是ping不通,那就往下看MAC层。

5.2 从Link UP到能收发,中间差了一个DMA

Link UP只说明PHY和网线没问题,但数据能不能从PHY传到MAC、再从MAC传到内存,是另一回事。

验证MAC和DMA这一层有个好办法:直接看ETH的中断和DMA状态寄存器。HAL库里ETH的接收中断触发时,会调用HAL_ETH_RxCpltCallback。在这里加一个计数变量,如果收包计数不增长,说明DMA根本没把数据搬进来,问题在MAC层配置或DMA描述符。

另一个快速方法是用Wireshark抓包。把板子接在交换机上,电脑也接在同一个交换机,然后往板子的IP发ARP和ICMP请求。如果在Wireshark里看不到板子的响应包,说明问题在MAC或协议栈;如果看得到响应包但ping还是不通,问题可能在上层路由或防火墙。

实际调试中,我发现最常见的DMA层问题是描述符数量不够导致的丢包。高速接收时,RX描述符被占满,新的数据包无处存放,直接被DMA丢弃。我建议把RX描述符从默认的4个改成8个,同时保证接收中断优先级够高,别被其他中断饿死。

5.3 网段、网关和ARP表:协议栈层面的三个低级错误

物理层和MAC层都正常,ping还是不通,大概率是lwIP配置出问题。这里我列三个最常见的低级错误。

第一是IP网段不一致。板子IP是192.168.1.10,电脑IP是192.168.2.5,两者不在一个网段,路由器没有转发,当然不通。这个错误几乎每个人都会犯一次,检查方法很简单,ifconfig看一下双方IP,或者用ARP命令查一下ARP表里有没有对方。

第二是MAC地址冲突。有些开发板出厂固件烧了一样的MAC地址,两台设备同时上网直接冲突。局域网设备里有一台和你相同MAC地址的设备时,交换机转发数据会乱,表现就是时通时断。这个问题的排查很隐蔽,最好在初始化时强制修改MAC地址,确保每个板子都不同。

第三是没有配置默认网关或网关配置错误。如果你要访问的不是同一网段的地址,必须配置网关。lwIP里netif->gw字段不能填错,否则跨网段通信完全不可用。

之前有次我在客户现场排查问题,板子和电脑明明都在同一个局域网里,ARP也能互相看到,但UDP数据总是发不出去。折腾了半天,最后发现lwIP的netif还没有被设置为up状态,netif_set_up函数根本没调。这个错误低级得很,但现场一着急,注意力全放在上层协议上,反而忽略了基本状态。

6. 性能与稳定性:从能ping通到能长期跑业务

6.1 中断模式还是轮询模式:看你的业务类型

ETH的HAL库提供了两种工作模式:中断和轮询。CubeMX默认生成的是中断模式,ETH的DMA收到数据后触发中断,在回调函数里处理数据。轮询模式则是主循环里不断调用HAL_ETH_GetRxDataBuffer检查有没有新数据。

这两种模式没有绝对的优劣,取决于业务场景。如果MCU同时跑着多个任务,主循环被其他任务占用的时间不确定,就应该用中断模式,保证以太网数据不丢。如果以太网只是其中一个功能,数据量不大,轮询模式反而更简单——代码好写、调试方便,还不容易踩中断优先级和重入的坑。

我自己的习惯是:裸机程序里用轮询模式跑小数据量业务,RTOS里用中断模式配合信号量唤醒协议栈处理任务。注意,中断回调里千万别做耗时操作,就塞一个二进制信号量或置一个标志位,真正的数据处理放到主循环或专用任务里。

6.2 实测数据:不同工作状态下的性能表现

我手头一块F407+LAN8720的板子,跑lwIP,做了一套简单的UDP回环测试。在轮询模式下,UDP小包(64字节)来回耗时大概0.3ms,吞吐量约2Mbps;大包(1400字节)吞吐能到7Mbps左右,基本已经接近裸机轮询的上限。

换成中断模式并把RX描述符调到8个以后,小包来回耗时降到0.2ms以下,大包吞吐能到9.5Mbps左右。这个性能跑常规的传感器数据采集、设备状态上报完全够用,但如果你要拿它做视频流或者文件大传输,F407的M4内核会先成为瓶颈。

长时间运行稳定性方面,我踩过一个典型坑:UDP收发连续跑48小时以后,内存占用稳步上升,最后协议栈直接卡死。排查下来发现,不是ETH外设的问题,是代码里一个缓冲区分配了没释放,产生了内存泄漏。lwIP的PBUF分配是动态的,用完了必须调用pbuf_free归还,不是RTOS的free,是lwIP自己的内存管理函数。写网络代码前一定要把PBUF的生命周期管理搞清楚。

6.3 几个让我少加班的经验

调试ETH和lwIP的过程中,有几个经验是文档里不会写但特别有用的。

网口变压器的中心抽头电容取值会影响信号质量。PHY工作时推荐在差分线对上并联一颗小电容,具体值参考PHY数据手册,不是所有PHY都一样。我换过一颗PHY后一开始没注意这一点,100Mbps模式下丢包很严重,加了对电容以后才恢复正常。

调试中多用Wireshark,不要光盯着串口打印。串口打印只能看到本端状态,抓包能同时看到双方报文交互的全过程。比如ARP请求有没有收到、应答有没有发出、TCP握手卡在哪个阶段,在抓包里一目了然。

最后是printf的安全问题。在中断回调里用printf打印调试信息,如果调用链过长,可能导致重入冲突。我在RTOS里遇到过printf死锁,进调试器看了半天才发现是中断里调printf触发了堆分配锁。调试阶段可以在特定标志位控制下打印,生产代码把打印全部关掉。

如果你正在调STM32以太网,链路不通时不要死盯着协议栈代码,按物理层、MAC层、协议栈这个顺序逐层排查,少走弯路。希望这篇内容能帮你早点把网口点亮。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 5:24:42

家庭场景19类家具全景分割数据集:从txt标签到训练实战

简介&#xff1a;面向家庭场景中家具识别的图像分割任务&#xff0c;该全景分割数据集提供640640分辨率的家庭室内图像&#xff0c;覆盖床、椅子、橱柜、门、灯、地毯、桌子、窗户等19类常见家具&#xff0c;可用于细粒度分割、实例分割或全景分割模型的训练与精度验证&#xf…

作者头像 李华
网站建设 2026/10/5 5:24:15

汽车ECU Bootloader开发全流程解析:从启动到量产刷写

1. 汽车Bootloader到底是什么&#xff1a;它解决的不只是"刷软件"这一个问题聊汽车Bootloader之前&#xff0c;先想一个场景&#xff1a;一辆量产车交付给用户之后&#xff0c;ECU&#xff08;电子控制单元&#xff09;里跑的软件出了bug&#xff0c;或者需要新增一个…

作者头像 李华
网站建设 2026/10/5 5:23:14

SAR图像低秩重建中的结构稀疏先验与ADMM求解详解

简介&#xff1a;基于结构稀疏的SAR图像低秩重建MATLAB代码包&#xff0c;面向合成孔径雷达图像处理、压缩感知与稀疏表示方向的科研人员和工程师。压缩包共40个文件&#xff0c;其中27个.m源码实现核心算法、7个.bmp图像作为测试样本、4个.txt文件提供说明指导&#xff0c;另有…

作者头像 李华
网站建设 2026/10/5 5:22:55

TensorFlow.js端侧推理实战:WebGPU加速与性能优化指南

1. 端侧机器学习到底在解决什么问题1.1 从“把数据送上去”到“把模型送下去”过去几年我做机器学习相关的项目&#xff0c;绝大多数架构都是同一个套路&#xff1a;前端采集数据&#xff0c;打包发到服务端&#xff0c;服务端跑推理&#xff0c;结果再回传。这个模式在实验室里…

作者头像 李华
网站建设 2026/10/5 5:22:52

KLayout形状编辑详解:Box、Polygon、Path与布尔运算实践

KLayout这个开源版图工具&#xff0c;我在上一篇教程里带大家把主界面、图层面板和单元导航的基本操作过了一遍。这一篇是系列教程的第二篇&#xff0c;专门把“编辑不同的形状”这件事讲透。你要在KLayout里画版图&#xff0c;无论是画一条金属连线、抠一个焊盘开窗&#xff0…

作者头像 李华
网站建设 2026/10/5 5:22:22

802.1Qbv时间感知整形器实战:门控列表计算与TSN交换机部署避坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华