news 2026/9/2 5:13:02

STM32H750+LAN8720以太网工程:FreeRTOS与lwip掉线重连机制详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32H750+LAN8720以太网工程:FreeRTOS与lwip掉线重连机制详解

简介:这是一份基于STM32CubeMX构建的STM32H750+LAN8720以太网完整工程,面向使用FreeRTOS与lwIP协议栈做TCP socket开发的工程师。工程已成功实现掉线自动重连与KeepAlive保活机制,适合正在调试网络通信、或基础移植后始终无法稳定维持连接的场景,可对照工程快速定位配置问题。压缩包为RAR格式,大小约2.21MB,共403个文件,以250个.h头文件和137个.c源文件为主,覆盖HAL驱动、lwIP协议栈、FreeRTOS任务调度及socket接口;另有.ioc、json、cfg、ld、makefile等工程文件,便于导入CubeMX重新生成或命令行编译。目前已有5100人学习下载。工程核心价值在于提供一套可直接对照验证的掉线重连与KeepAlive组合配置,并清晰展示任务、socket、网卡中断的协同方式,帮助理顺TCP长连接生命周期;读者可调整参数或直接抽取相关模块集成到自研项目中,显著减少底层排错与方案验证时间。 搞过一阵子嵌入式网络通信的朋友应该都有体会:以太网这东西,硬件只要十几块钱的PHY芯片一焊,理论上就能让板子联网,但真正把协议栈跑稳、跑不丢包、断开还能自己抢回来,才是最磨人的地方。这次要聊的这个工程,正好就是一套完整的参考实现:基于CubeMX生成的STM32H750工程,外接LAN8720做以太网PHY,内部跑FreeRTOS和lwip,并且把掉线检测、重连、TCP KeepAlive这套机制全部移植好了。如果你正准备用H7系列做联网产品,或者刚用CubeMX点开过lwip但面对一堆配置一脸懵,这份工程值得好好拆一拆。

1. 工程是什么:硬件平台与整体架构拆解

1.1 为什么是STM32H750+LAN8720这套组合

STM32H750这颗料很有意思,它是H7里定位比较特殊的一个型号。内核是Cortex-M7,跑满能到480MHz,这个性能对跑lwip + FreeRTOS来说可以说是“杀鸡用牛刀”,协议栈开销根本不需要担心。真正的槽点在于它的内部Flash只有128KB,代码稍大一点就得考虑外部存储。但反过来想,正因为主频高、外设全、Flash小,它反而成了很多网络产品做“小系统+协议处理”的首选,尤其适合把网络协议栈这层活全包下来。

LAN8720则是这颗MCU的好搭档。它是Microchip(原SMSC)出的低功耗10/100M以太网PHY,RMII接口,3.3V供电,引脚少,价格便宜,在很多开发板上都能看到它的身影。和MCU之间就7根信号线,板级设计很省事。H750内部自带了MAC控制器,所以MCU负责跑MAC层和上层协议,LAN8720负责物理层的编码、协商、收发,两个芯片各干各的活,配合起来正好是一套标准“MAC+PHY”架构。

这套组合在国内开发圈出镜率极高,网上能找到的参考工程、原理图、调试笔记都很多,遇到问题也容易搜到答案,对入门和量产来说都是比较稳妥的选择。

1.2 FreeRTOS与lwip各自承担什么

很多新手容易把FreeRTOS和lwip混在一起理解,其实它们完全是两个层面的东西。FreeRTOS是操作系统,干的任务是任务调度、信号量、消息队列、内存管理,它让单片机有了“同时做几件事”的能力。lwip是网络协议栈,负责把TCP/IP的IPv4、UDP、TCP、ICMP这些协议跑起来,它只关心“数据包怎么封装、怎么路由、怎么应答”,不关心跑在什么样的OS上。

这两个东西组合起来,标准的做法是让lwip跑在FreeRTOS之上。具体来说,lwip里有一个“操作系统的抽象层”sys_arch,CubeMX生成代码时会自动对接到FreeRTOS的线程和消息邮箱机制上。这样lwip本身在网络收发的中断里只做最简单的数据搬运,复杂的TCP状态机、重传、分片等逻辑全部交给一个专用的tcpip_thread线程去处理,不会因为网络数据量大而把MCU的中断处理时间拖死。

所以这个工程里,用户应用任务和lwip协议栈任务是分离的。用户的业务逻辑只管调socket或者netconn接口,协议栈内部怎么分包重传,应用层根本不用管,丢包重发这些事情由lwip替我们扛。

1.3 移植工程的目录结构与产出

这个工程的价值在于“开箱即用”,它把CubeMX生成的工程往下推进了很多:不仅仅是跑通ping,而是面对真实网络环境时能保持连接不崩溃。工程内主要包含这几块内容:

  • CubeMX生成的初始化代码:时钟、ETH、FreeRTOS、lwip基础配置;
  • 应用层网络任务:负责主动连接远端服务器;
  • 链路检测逻辑:周期性查询PHY状态,感知网线断开和恢复;
  • TCP KeepAlive配置:让长时间没有数据交互的连接能自动发现对端是否“假死”;
  • 重连状态机:当链路断开、对端异常或连接失败时,自动进入重连流程。

也就是说,这套工程拿去做参考,你看完之后不仅能会配CubeMX,还能把“连接断了怎么自动恢复”这个问题彻底解决掉。

2. CubeMX配置实操:四个关键环节

2.1 时钟树配置:LAN8720的50MHz REF_CLK从哪来

很多人在CubeMX里第一步就翻车往往不是ETH没配好,而是时钟树上根本没有给以太网留出正确的时钟来源。

先说结论:RMII接口的PHY必须要一个50MHz的参考时钟。这个时钟可以由两条路径产生:

第一种,PHY自己产生。原理是在LAN8720的XI和XO引脚之间接一个25MHz的晶振,PHY内部有PLL,会把这个25MHz倍频到50MHz,然后从REF_CLK引脚输出给STM32。这是开发板最常见的做法,CubeMX里ETH的RMII配置中选择“REF_CLK由PHY提供”即可。

第二种,主控产生。如果LAN8720的外部晶振电路省掉了,可以直接用STM32的MCO引脚输出50MHz给PHY的REF_CLK。

这个工程在CubeMX里的标准做法是第一种,外接25MHz晶振,PHY把50MHz时钟源送回给MCU。注意CubeMX中ETH配置的那个“User PHY”选项卡里,需要把PHY的地址和时钟源方向配置正确,否则后面驱动初始化PHY时会一直读不到正确的芯片ID。

提示:如果你用的是自己的板子,先翻原理图确认REF_CLK的方向。方向搞反了,PHY寄存器读不出来,ping也永远不通,这是新手最容易忽视的问题。

2.2 ETH外设与RMII引脚:对照原理图逐个核对

在CubeMX里勾选ETH外设之后,Pinout视图会出现一套默认的RMII引脚配置。H750VBT6这类的封装下,标准的RMII引脚映射是下面这张表:

信号引脚
ETH_RMII_TXD0PB12
ETH_RMII_TXD1PB13
ETH_RMII_TX_ENPB11
ETH_RMII_RXD0PC4
ETH_RMII_RXD1PC5
ETH_RMII_CRS_DVPD8
ETH_RMII_REF_CLKPA1
ETH_RESET(自定义GPIO)一般接PC3或任意空闲引脚

这里要特别提醒几个点。第一,RMII接口没有单独的RX_CLK,它把接收时钟和载波侦听合到一根CRS_DV线上,所以引脚映射要是错了,数据收发就直接废掉。第二,REF_CLK这个引脚在H7上是PA1,如果原理图上LAN8720的50MHz输出没有接到PA1,那就得改CubeMX里的Alternate功能,或者直接改硬件。第三,LAN8720的复位脚不能悬空,复位时序也很讲究,CubeMX里虽然不会自动给PHY复位,但工程初始化代码里专门做了拉低-延时-拉高的复位动作,这块在移植的时候一定不能省。

另外,LAN8720那个PHYAD0引脚的上下拉决定了PHY的I2C/MDIO访问地址。绝大多数模块出厂时把PHY地址配置为0,如果在CubeMX或者驱动代码里填的是1,那MDIO通信会一直失败。这个等到后面章节再展开讲排查方法。

2.3 FreeRTOS参数:任务栈与堆的分配

CubeMX里启用FreeRTOS之后,系统会自动创建一些内部任务,比如定时器任务、空闲任务。我们自己的网络业务任务也需要在这里定义,网络任务主要做三件事:初始化网络连接、周期检测链路状态、在断开后触发重连。

这个任务不能给它太小的栈。lwip的socket接口里面有一些局部缓冲区,如果栈深度不够,很容易在调用send/recv时触发栈溢出。工程里网络任务栈大小我建议配置到1024 words(也就是4KB字节)起步,如果后续业务里还要处理JSON解析、加解密等,再往上加。

同时注意FreeRTOS的堆大小configTOTAL_HEAP_SIZE,CubeMX默认可能只给了4096或者8192字节,这个数值在跑lwip时通常不够。因为lwip内部也会从FreeRTOS的heap里分配内存给PBUF、PCB等数据结构,尤其是开启了DHCP、TCP连接较多的情况下,堆太小会直接导致协议栈初始化失败或者运行一段时间后随机死机。这套工程里建议堆至少给到4万字节以上,网络任务栈维持1024 words,同时留出一定余量。

2.4 lwip参数:协议栈内存与KeepAlive开关

CubeMX在Middleware里选中lwip后,可以配置协议栈的全局参数。这里面有几个关键点,直接影响内存占用和可用性:

  • MEM_SIZE:堆的大小,默认给的1600字节偏小,建议调到几万字节,地址空间便宜,但MCU的RAM要撑得住。H750有512KB以上的RAM,这部分绰绰有余。
  • MEMP_NUM_PBUF和MEMP_NUM_TCP_SEG:控制PBUF和TCP分段缓冲区的数量,任务并发量大时尽量给大。
  • TCP_MSS:默认1460,一次TCP报文携带的最大数据长度,结合网口MTU 1500来理解,不需要改。
  • TCP_WND:接收窗口默认应该够用,太小会限制传输速度。
  • LWIP_TCP_KEEPALIVE:这个宏必须开启,不开的话,即使代码里设置了SO_KEEPALIVE,lwip也不会真正定时发送探测包。
  • TCP_KEEPIDLE_DEFAULT、TCP_KEEPINTVL_DEFAULT、TCP_KEEPCNT_DEFAULT:这三个参数控制KeepAlive探测的具体行为,等下单独讲。

CubeMX图形界面上能改的KeepAlive参数不一定全,很多关键宏要手动去lwipopts.h里改。工程里特意把需要改的宏都标注了注释,方便查阅。

3. lwip与FreeRTOS协同运行的关键细节

3.1 结合模式选择:NO_SYS=0跑在tcpip线程上

lwip有两种运行模式:裸机模式和OS模式。裸机模式(NO_SYS=1)下,协议栈不依赖操作系统,需要在主循环里不断轮询调用lwip的service函数,所有网络逻辑都串行执行,适合简单场景。而这个工程采用的是NO_SYS=0模式,即lwip跑在FreeRTOS的多任务环境下。

NO_SYS=0模式会额外创建两个核心线程。第一个是tcpip_thread,它是协议栈的主线程,负责TCP/IP协议处理、数据包上抛、ARP处理等耗时操作;第二个是eth_rx_thread,负责从以太网DMA接收描述符里把收到的数据包取出来,封装成PBUF后投递给tcpip_thread。这两个线程的优先级很关键:tcpip_thread应该比普通应用任务优先级高一些,否则高优先级应用任务持续占用CPU时,协议栈时钟和处理会被饿死。

CubeMX生成的ETH中断回调里,实际只会发送一个信号量唤醒eth_rx_thread,避免在中断上下文里做大量工作。这种设计是lwip在RTOS环境下的标准做法,好处是中断响应快,不会因为网络流量大导致中断延迟超高。

3.2 数据收发链路:从MAC中断到应用socket

整个数据路径可以这么理解:

网线收到数据帧以后,LAN8720通过RMII接口把数据传进STM32内部的MAC,MAC的DMA控制器自动把数据搬进指定的内存缓冲区(DMA描述符),然后触发ETH中断。中断服务函数里判断一下是不是接收事件,如果是就把一个信号量交给eth_rx_thread。eth_rx_thread被唤醒之后,从DMA接收描述符中取出数据,将数据头封装成lwip的PBUF结构,然后发送到tcpip_thread的mbox中。

tcpip_thread从mbox里取到数据包,根据以太网类型做判断:如果是ARP就进入ARP模块处理,如果是IPv4就进入IP层,再由协议类型分发到TCP或UDP模块。最终应用层通过recv()调用拿到数据。

发送链路则相反:应用层调用send(),把数据放进lwip的内核缓冲,由tcpip_thread根据流控算法决定是否立即发送,需要发的时候把数据交给MAC的DMA发送描述符,MAC自动把数据帧发到PHY,最终送上网线。

这套链路里最需要注意的就是DMA描述符内存的对齐问题。lwip的PBUF分配和DMA描述符如果不对齐,在高优化级别下容易出现数据错乱。CubeMX生成的代码默认会处理好,但如果你自己改了堆配置或者把lwip用的内存区搬了位置,一定要检查描述符是否在32字节对齐的地址上。

3.3 调试小技巧:串口打印与断点定位

跑网络任务时最怕的就是系统在半空中死掉,但连死在哪儿都不知道。这套工程里在三个位置加了串口日志:PHY初始化完成后打印一次芯片ID和连接状态;任务连接服务器成功或失败时打印对应错误码;KeepAlive触发断开时打印一条告警。别小看这三行打印,实际调试重连问题时,90%的定位线索都来自这种关键节点的输出。

如果需要更细的调试,也可以在lwip内部开DEBUG宏。比如LWIP_DEBUGF配合LWIP_TCP_DEBUG、LWIP_ETHARP_DEBUG等开关,可以看到协议栈内部的收发包过程。但注意,在FreeRTOS环境下开这些调试宏会大幅拖慢协议栈性能,不建议长时间开着跑业务,定位完问题就关掉。

4. 掉线重连与KeepAlive:保障长连接稳定

4.1 TCP KeepAlive原理与参数设置

TCP连接建立之后,如果很长一段时间没有实际数据交互,中间链路可能早就断了,但两端的协议栈还傻傻地维护着这个连接。这时候如果应用直接发数据,可能收到超时或RST;如果不发数据,这个连接会一直占着资源,假死一样。

TCP KeepAlive机制就是用来解决这个问题的:协议栈在连接空闲一段时间后,周期性地发送一个长度为0的探测包,对端正常会回复ACK。如果一个或多个探测包都没有得到响应,协议栈就能确认连接已经失效,进而主动关闭socket,返回错误给应用层。

比如在lwip的lwipopts.h里配置:

#define LWIP_TCP_KEEPALIVE 1 #define TCP_KEEPIDLE_DEFAULT 10000 /* 空闲10秒后开始探测 */ #define TCP_KEEPINTVL_DEFAULT 3000 /* 每3秒探测一次 */ #define TCP_KEEPCNT_DEFAULT 3 /* 连续3次没回应则断开 */

这三个参数的意思是:连接空闲满10秒,协议栈发出第一个KeepAlive探测包;之后每隔3秒发一个;连续发出3个都没有得到任何ACK响应,就判定连接已断开。从开始探测到最终判定,大约耗时9秒,也就是说一个假死连接最多让你等待19秒就能被识别出来。

4.2 物理链路检测与状态机设计

TCP层的KeepAlive能发现对端假死,但发现不了“网线拔了又插上”这种物理层的瞬时中断。因为网线断开时,TCP未必能在第一时间收到任何信号,只有等到下次收发数据时才会暴露问题。所以工程里单独加一个链路检测任务,周期性地去读PHY的状态寄存器。

LAN8720的状态寄存器(地址1)的bit2就是Link Status,0表示链路断开,1表示链路已建立。CubeMX的驱动里可以通过HAL_ETH_ReadPHYRegister来读取。启动后每隔500ms读一次,一旦发现链路从1变成0,立刻标记一个“链路丢失”状态。链路恢复后,LAN8720会自动重新协商,等协商完成(link状态再次为1),任务就可以触发重连流程。

如果把整个连接管理改成状态机,会更清晰:

  • IDLE:尚未开始连接。
  • CONNECTING:正在发起TCP连接,等待服务器响应。
  • CONNECTED:连接正常,收发数据都在这里进行。
  • LINK_LOST:物理层断开,停止发送数据,等待链路恢复。
  • RECONNECTING:链路已恢复,但服务器连接还没建立,进入重连循环。

应用代码里用switch就行,每次状态变化时打印一行日志,这样子后期就算业务复杂了也好定位。

4.3 重连步骤与代码流程

重连流程其实不复杂,但有几个细节决定了它能不能稳定工作。

第一步,关闭旧socket再重建。不要拿着旧的fd继续connect,lwip在高负载下容易出现状态残留,必须先close,确保协议栈把那个连接占用的PCB、PBUF等都释放干净。

第二步,connect时不能阻塞等待结果。正常情况下lwip的connect是非阻塞的,基于select或者poll来判断是否连接上,否则连接一个不可达的服务器地址时,应用线程会一直卡死,整个任务就废了。工程里连接超时时间设定在5秒左右,超时没连上就close掉,等待下一轮重试。

第三步,加退避逻辑。假设服务器宕机了,如果应用每500ms就尝试连一次,不仅浪费CPU,还会给对端造成压力。工程里退避策略是:失败后先等3秒,累计失败次数越多,等待时间递增,最多30秒封顶,每成功连接一次就把失败计数清零。

简化后的伪代码如下:

void net_task(void *arg) { while (1) { switch (net_state) { case STATE_IDLE: net_state = STATE_CONNECTING; break; case STATE_CONNECTING: if (tcp_client_connect(server_ip, server_port) == 0) { net_state = STATE_CONNECTED; fail_count = 0; } else { fail_count++; vTaskDelay(pdMS_TO_TICKS(backoff(fail_count))); } break; case STATE_CONNECTED: if (phy_link_detect() == LINK_DOWN) { net_state = STATE_LINK_LOST; } else { /* 收发业务数据 */ tcp_client_poll(); } break; case STATE_LINK_LOST: if (phy_link_detect() == LINK_UP) { tcp_client_close(); net_state = STATE_CONNECTING; } else { vTaskDelay(pdMS_TO_TICKS(500)); } break; } vTaskDelay(pdMS_TO_TICKS(10)); } }

这样设计的好处是:网络任务永远在跑,不会因为某次连接失败而退出或卡死。不管是网线断了、服务器重启、还是长时间无数据导致的假死,最终都能回到CONNECTED状态。

5. 移植过程中踩过的坑

5.1 PHY地址错位导致ping不通

这是最常见的移植问题,没有之一。LAN8720的PHY地址由引脚PHYAD0的上下拉决定,绝大多数模块默认地址是0,但有些开发板为了区分不同PHY,会把地址配置成1。如果你的代码里读PHY寄存器一直读到0xFFFF,或者读出来的芯片ID不对,先确认PHY地址再查其他原因。

CubeMX里可以在ETH配置的“Advanced Parameters”中设置PHY Address,然后在HAL_ETH_Init后的代码里加一行打印,把读到芯片ID打出来。LAN8720的芯片ID一般是0x0007C0F0(含版本字段),看到这个值就说明PHY通信正常了。

5.2 网口协商失败与link灯不亮

如果初始化看起来正常,但网口link灯不亮,第一步检查是不是把网口插到交换机/路由器上了,而不是插到电脑后直连电口都不亮。第二步查硬件:LAN8720的复位脚、时钟源、REF_CLK方向。第三步用万用表量PHY供电,3.3V和1.2V都是必须有的。如果外接的是25MHz晶振却不起振,那问题大概率出在晶振负载电容或焊锡上。

软件层面还有一个原因:ETH外设时钟没有使能。H750的ETH使用的是AHB1上面的时钟,CubeMX里如果外设时钟忘记勾选,PHY寄存器读写虽然不报错,但收发完全不通。

5.3 PBUF和堆栈溢出导致的随机死机

网络任务用着用着就死机,而且死机时机完全没有规律,这通常不是逻辑bug,而是内存问题。排查方法也比较直白:如果开了FreeRTOS的栈溢出检测钩子函数,先加上栈溢出打印;如果lwip还开着串口调试,观察打印有没有MEMP分配失败的告警。这两个方向的概率最大。

实际踩过的场景是:TCP收到大量数据时,lwip一次性需要分配多个PBUF,如果MEMP_NUM_PBUF或MEM_SIZE设置得太小,分配失败后协议栈会丢弃数据包,极端情况下会进入死循环。H750的RAM已经很大了,在这个工程里把MEM_SIZE调到几万字节、MEMP_NUM_TCP_SEG调到16以上,没有再出现过随机死机的问题。

5.4 重连失败或假死问题

重连逻辑写得没问题,但多次重连之后发现连接不上了,而且串口没有任何报错。这种属于比较隐蔽的坑:关闭socket后,lwip的时钟仍被后续的KeepAlive周期事件占用,而新建socket在非阻塞connect时如果没做好超时清理,连接状态就卡在SYN_SENT上。

解决办法有两个:第一,重连前先把旧的PCB释放干净,用lwip自带的stats接口打印创建的TCP PCB数量,确保每次close后数量能降下来;第二,在非阻塞connect之后,必须用select做超时判断,超时后立即close,而不是盲目等待。

这些坑如果不实际踩一轮,很难意识到问题会在哪里。其实做网络这块,环境复杂、场景多种多样,稳定的关键并不是某一行代码写得有多神,而是把边界情况都考虑进去,给每个环节都留好退路。

写在最后

我自己的体会是,这种带网络协议的工程,能“ping通”只是一个起点,真正难的是让它在恶劣网络环境下长期活着。这套工程带来的最大启发就是,把物理链路检测和TCP层的KeepAlive结合起来,再加上重连状态机,基本上能覆盖掉90%的异常场景:网线被踢了、对端服务器重启了、长时间无流量被中间设备超时踢掉,这些都能在几十秒内恢复。如果你后续要用H750做更复杂的业务,比如对接云平台、做OTA升级,这个框架也完全可以直接作为底子继续往上面堆功能。

本文还有配套的精品资源,点击获取

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

学习后端开发,先搞懂这五个核心组件再动手

先别急着装环境、跑Hello World,更别一头扎进框架的英文文档里。后端开发不是搭积木,而是一场对“数据流动”和“系统边界”的掌控。很多人学了很久,能写接口,却说不清请求到达服务器后发生了什么;能连数据库&#xff…

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

电力电子能量回馈装置:从PWM整流原理到STM32G474工程实践

1. 先搞清楚“能量回馈装置”到底要解决什么问题如果你做过电赛电源题,或者接触过电机、逆变器测试,肯定遇到过这个头疼事:给负载(比如电机、电阻箱)供电做实验,电能哗哗地流进去,最后全变成热量…

作者头像 李华
网站建设 2026/9/2 5:10:02

计算机图形学大作业实战指南:OpenGL光照与性能优化从入门到排错

简介:面向计算机图形学课程的综合性大作业资源,适合高校学生、参赛选手与图形学入门开发者对照实践,可作为课程设计或实验参考。资源以经典算法代码实现为主,覆盖直线与圆的Bresenham绘制、Bezier曲线生成、种子填充与扫描线填充、…

作者头像 李华
网站建设 2026/9/2 5:09:15

三端互通知识付费系统架构实战:从数据同步到多端部署

简介:这是一套面向知识付费创业者与小程序开发者的全栈式开源系统,涵盖微信小程序、PC网页及H5三端,实现数据实时互通,解决中小型知识服务团队快速搭建课程销售、资源分发与代理分销体系的核心需求。资源包共2000个文件&#xff0…

作者头像 李华
网站建设 2026/9/2 5:08:33

线路板打样怎么选?工程师揭秘PCB制作全流程

身处于工位之上, 手指轻轻滑过那屏幕里布满密密麻麻线路的图, 又有一个打样的订单安安静静地处在系统之中。 在从事PCB这个行业期间, 目睹过超多的人询问一样的问题, 具体为, 打样的时候该如何去挑选厂家, 出货需要多长的时间完成, 质量究竟要怎样去确保。 如今, 凭借着身为一名…

作者头像 李华
网站建设 2026/9/2 5:07:48

AI Agent 场景选型:四道门与 YAML 边界配置

根据阿里巴巴官方文档,2026 年 8 月 3 日,阿里巴巴宣布推出一站式办公 AI 智能体平台“千问办公”。 我们据此做一个判断:企业接下来关注的不只会是“能不能回答”,还会是“能不能交付一个可检查的结果”。这不是阿里巴巴的原话。…

作者头像 李华