恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

STM32F407 上 FreeRTOS 与 LwIP 以太网稳定联调与排错

  • 首页
  • 资讯中心
  • /
  • STM32F407 上 FreeRTOS 与 LwIP 以太网稳定联调与排错

相关资讯

Buzz:把录音变成文字,在本地就能跑通的保姆级教程 2026/9/18 5:16:07
用Milvus给大模型建座图书馆:从零搭建AI长期记忆与RAG系统 2026/9/18 5:11:07
非程序员如何参与开源:first-contributions 项目的 16 条零代码贡献路径 2026/9/18 5:11:07

最新资讯

ascend-transformer-boost 中 SortOperation 深度解析:TopK 降序排序与索引输出的双 Runner 实现
MIMO系统中ZF与MMSE检测算法性能对比与实现
Ralph for Claude Code 使用教程:让 AI 自主开发循环不跑偏的 3 个关键机制
用苏宁开放平台API获取北京时间:HTTP时间源方案与工程实践
使用 aws-sdk-java-v2 的 archetype-lambda 模板快速构建 AWS Lambda Java 函数项目
管桁架制作与安装一体化工艺设计:从相贯线切割到焊接防偏

今日推荐

2026年AI设计工具在PPT制作中的核心应用与评测
Matlab手写逻辑回归:从数学原理到多变量概率预测模型实现
高值医用耗材研报PDF:用Python完成字段抽取、清洗与趋势预测

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

STM32F407 上 FreeRTOS 与 LwIP 以太网稳定联调与排错

发布时间:2026/9/18 5:16:07
STM32F407 上 FreeRTOS 与 LwIP 以太网稳定联调与排错 板子刚焊好、网口灯也亮着裸机程序里ping一下就通结果一把 FreeRTOS 挂上去网口直接哑火甚至开机就跳 HardFault——这个场景我在 F407 上遇到过不止一次。STM32F407 这颗 Cortex-M4F 芯片本身条件不错168MHz 主频、带硬件浮点、192KB SRAM、1MB Flash片内还集成了以太网 MAC 和专用 DMA理论上跑实时操作系统加 LwIP 协议栈完全够用。但够用和跑得稳之间隔着一整套中断优先级、堆内存、DMA 描述符对齐和 PHY 时序的坑任何一个没对齐现象都可能是灯亮但 ping 不通这种最磨人的状态。这篇内容就是把这套组合拳从头到尾捋一遍FreeRTOS 的 port 层到底改哪几个文件、FreeRTOSConfig.h里哪些宏是生死线、LwIP 的lwipopts.h怎么配才不至于收发几个包就卡死、PHY 芯片地址和 RMII 时钟怎么确认、以及联调阶段用什么样的排查顺序能最快定位问题。适合已经能点亮 LED、写过串口收发准备把网络和 RTOS 一起用起来的人也适合已经在跑但稳定性不理想、想搞清楚底层到底发生了什么的人。下面所有配置我都以 STM32F407 RMII 接口 PHYDP83848 或 LAN8720 这类常见型号 Keil/IAR 为主线来讲其他 PHY 只需替换时序细节。1. F407 上加 FreeRTOS 与 LwIP真正难的地方在哪1.1 先看清 F407 的硬件底子与资源天花板很多人移植失败根源不在代码而在于一开始对芯片资源的估算就是错的。STM32F407 的 192KB SRAM 并不是一整块连续空间它由 112KB 16KB 的 SRAM1、64KB 的 SRAM2 组成地址上 SRAM1 从 0x20000000 开始SRAM2 在 0x2001C000 附近中间还夹着一段保留区。这意味着如果你指望把一个大数组或者一块巨型堆直接放在SRAM 里编译器很可能会因为跨越不连续区域而报错或者悄悄截断。以太网部分F407 的 MAC 控制器支持 MII 和 RMII 两种接口。引脚数量上 RMII 只需要 7 根信号线加一根参考时钟比 MII 省一半引脚所以实际项目里绝大多数选 RMII。RMII 的参考时钟必须是 50MHz这个时钟有两个来源一是外部 PHY 提供、从 PA1 引脚输入二是由 MCU 的 MCO1 引脚输出 50MHz 送给 PHY。两种方案各有代价前者要求 PHY 侧有 50MHz 晶振或者能分频输出后者占用一个引脚并且对 MCO 的时钟源配置有要求。资源分配这块我一般按这个比例切FreeRTOS 堆configTOTAL_HEAP_SIZE给 32KBLwIP 自己的MEM_SIZE给 16KBpbuf 池给 16KB 左右其余留给各个任务栈和全局缓冲。注意 FreeRTOS 堆和 LwIP 内存池是两套完全独立的分配器一个用pvPortMalloc一个用mem_malloc两者不能互相释放这一点在排查内存相关故障时非常关键。1.2 双栈协同的第一次冲突中断优先级分组FreeRTOS 在 Cortex-M 上实现临界区的方式是通过写BASEPRI寄存器屏蔽掉低于某个优先级的中断。具体来说configMAX_SYSCALL_INTERRUPT_PRIORITY决定了一个阈值所有优先级数值大于等于这个阈值的中断都会被BASEPRI挡住而优先级数值小于它的中断可以照常打断内核。这套机制要求所有会调用 FreeRTOS API 的中断其优先级数值都必须在阈值之内。问题就出在这里STM32 的 NVIC 支持优先级分组默认复位后是分组 0也就是高 4 位全做抢占优先级低 4 位做子优先级实际 STM32 只实现了 4 位优先级。如果你在别处调用了HAL_NVIC_SetPriorityGrouping设成别的分组那么优先级数值的含义就变了FreeRTOS 的屏蔽逻辑会直接失效典型现象是内核调度时随机死机或者进 HardFault。我个人的做法是工程初始化最开头就固定调用NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4)让 4 位全部作为抢占优先级不做子优先级。这样优先级数值和 FreeRTOS 的判断逻辑就是一一对应的不会出现歧义。1.3 以太网中断优先级为什么必须低于内核阈值以太网接收中断会调用xSemaphoreGiveFromISR或者 LwIP 的收发函数这就属于会调用内核 API 的中断它的优先级数值必须大于等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY。假设阈值设为 5那么 ETH 中断的抢占优先级只能设成 5 到 15 之间的值。反过来如果你把 ETH 中断优先级设成 2看起来响应更快实际上它不受BASEPRI屏蔽一旦在 FreeRTOS 操作链表的过程中打断内核链表指针就可能被改坏表现就是偶发的、极难复现的死机。这类问题用调试器很难抓因为断点一停下来时序就变了只能靠日志和逻辑推理。2. 工程目录与文件分组把地基铺平再动手2.1 FreeRTOS、LwIP、BSP 三个目录的边界怎么划我见过太多工程把 FreeRTOS 官方源码、LwIP 官方源码和 HAL 库全部塞在一个Src文件夹里编译一次几百个源文件出问题根本不知道是谁的问题。比较合理的做法是分成三类目录各自职责清楚第三方源码目录FreeRTOS/Source含portable和lwip/src这部分尽量保持官方原样只动portable和include/lwipopts.h方便以后升级版本时对比差异。适配层目录放ethernetif.c、sys_arch.c、arch/下的cc.h和sys_arch.h。这是移植时改动最多的地方也是唯一需要你深度定制的地方。业务与驱动目录BSP 层的 PHY 驱动、LED、串口以及你的应用任务。这样分的好处是当你怀疑是协议栈自身问题时可以快速把适配层单独拉出来做裸机验证而不至于在一片文件里翻找。另外lwipopts.h建议放在工程自己的 include 路径里而不是直接改官方lwip/src/include/lwip/lwipopts.h避免升级时覆盖。2.2 Keil 和 IAR 下添加文件的方式差异Keil 用 Manage Project Items 建 Group把文件按目录加进去注意portable目录下只需要选RVDS对应 ARM Compiler或者GCC里的一个不要全加否则会出现重复定义的vPortSVCHandler之类的符号冲突。头文件路径要在 C/C 的 Include Paths 里逐个加FreeRTOS/include、FreeRTOS/portable/RVDS/ARM_CM4F、lwip/src/include、lwip/arch这几个是必须的。IAR 是在 Project 的 Add Group 里操作原理类似但要注意 IAR 对头文件路径大小写敏感度在某些版本上不一样路径写错会报找不到FreeRTOS.h。另外 IAR 的 ARM 编译器对某些 GCC 扩展语法支持不同比如__attribute__((packed))在 IAR 里要换成#pragma pack或者 IAR 自己的__packed关键字ethernetif.c里定义描述符结构时要留意。有个细节我踩过Keil 默认的 ARM Compiler 5 和 ARM Compiler 6 对 FreeRTOS port 的选择不一样AC5 用RVDS/ARM_CM4FAC6 用GCC/ARM_CM4F因为 AC6 基于 Clang。选错了会在链接阶段报一堆__use_no_semihosting或者内联汇编语法错误。3. FreeRTOS 这层port 文件到底动了什么3.1 port.c 与 portmacro.h 里真正需要改的只有几处Cortex-M4F 的移植文件 FreeRTOS 官方已经写好正常情况下你一行都不用改。真正需要你处理的只有三件事第一是中断向量表的归属。FreeRTOS 的port.c里定义了vPortSVCHandler、xPortPendSVHandler、xPortSysTickHandler三个函数而 STM32 的启动文件里默认有SVC_Handler、PendSV_Handler、SysTick_Handler。你需要在stm32f4xx_it.c里把这三个 ISR 改成调用 FreeRTOS 的对应函数比如void SVC_Handler(void) { vPortSVCHandler(); } void PendSV_Handler(void) { xPortPendSVHandler(); } void SysTick_Handler(void) { xPortSysTickHandler(); }第二是FreeRTOSConfig.h里的宏下一节细说。第三是 FPU 相关写在 3.3 节。portmacro.h里一般不需要改但如果你用了不常见的内核版本要确认portSTACK_TYPE和portBASE_TYPE的定义和编译器宽度一致。在 32 位 ARM 上都是 32 位通常没问题。3.2 FreeRTOSConfig.h 里最要命的几个宏这个文件是整个移植的中枢配错一个就可能是看起来能跑跑一会儿就崩。下面这张表是我实际项目里反复验证过的取值仅供参考具体数值要按你的时钟和需求调宏名建议取值作用与坑点configCPU_CLOCK_HZ168000000必须是内核实际跑的主频不是晶振频率configTICK_RATE_HZ10001ms 一个 tick配合 SysTick 中断configMAX_PRIORITIES8 或以上数值太小会导致 LwIP 任务优先级不够用configMINIMAL_STACK_SIZE128单位是字不是字节换算是 512 字节configTOTAL_HEAP_SIZE32*1024单位字节需与 SRAM 分配一起规划configMAX_SYSCALL_INTERRUPT_PRIORITY5 (8-4)即 0x50配合 4 位优先级实现configKERNEL_INTERRUPT_PRIORITY15 (8-4)即 0xF0内核最低优先级configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY5逻辑优先级给用户代码用configPRIO_BITS4STM32 只实现了 4 位优先级configUSE_PREEMPTION1抢占式调度LwIP 场景建议开configUSE_TIME_SLICING1同优先级时间片轮转这里要特别说configPRIO_BITS。很多人写 8因为看到configMAX_SYSCALL_INTERRUPT_PRIORITY是 8 位寄存器。但 STM32 的 NVIC 实际只实现了高 4 位低 4 位读回来是 0如果写成 8左移计算出来的值就会错位屏蔽阈值直接失效。判断方法很简单写一个值进去再读出来看低 4 位是不是被硬件忽略了。3.3 开启 FPU 之后的 lazy stacking 与寄存器保存F407 带单精度硬件浮点只要在工程里定义了__FPU_PRESENT和__FPU_USED并且在FreeRTOSConfig.h里配置好port.c 的vPortEnableVFP就会把 CPACR 寄存器的 CP10/CP11 位打开。这一步不做的话任务里用float运算就会触发 UsageFault。真正容易被忽略的是懒加载lazy stacking。Cortex-M4 在异常进入时并不是立刻把 FPU 寄存器组压栈而是先标记状态等到任务真的用到浮点指令时才补压栈。这个机制本身没问题但如果你在中断里也用了浮点运算而中断优先级设置又和系统不匹配就可能出现 FPU 上下文丢失表现为浮点结果莫名奇妙变成随机值。我的经验是中断服务函数里尽量不要做浮点运算需要的话把原始数据丢给任务去算。如果非要在 ISR 里算请确认该中断的优先级在 FreeRTOS 屏蔽阈值之内否则异常嵌套时 FPU 状态会乱。另外configUSE_TASK_FPU_SUPPORT这个宏只在部分版本存在如果你的内核版本没有不用管port.c 的默认行为就够用。3.4 heap_4 与那 192KB SRAM 的分配账FreeRTOS 提供了五种堆方案从纯静态到可合并空闲块。网络场景我强烈建议用heap_4因为它支持相邻空闲内存块合并能显著降低长时间运行后的碎片化。heap_1不能释放LwIP 场景下任务创建销毁肯定会用到释放heap_2支持释放但不合并跑几小时后碎片化严重heap_5适合多块不连续 RAMF407 如果要把 SRAM1 和 SRAM2 合并管理才需要它。分配账这样算configTOTAL_HEAP_SIZE设成 32KB意味着链接器必须在 SRAM 里预留这 32KB 的ucHeap数组。加上 LwIP 的MEM_SIZE16KB、pbuf 池 16KB、以太网 DMA 收发缓冲各 4KB 左右再算上主任务栈、TCPIP 任务栈2KB、空闲任务栈512B基本就把 112KB 的 SRAM1 用掉大半。剩下的 SRAM2 可以留给大数据缓冲。还有个坑以太网 DMA 描述符和收发缓冲对地址对齐有要求描述符需要 4 字节对齐缓冲推荐 32 字节对齐。如果这些数组分散在堆里编译器可能会把它们放到不对齐的位置导致 DMA 数据错位。稳妥的做法是显式指定段或者用__attribute__((aligned(32)))。4. LwIP 这块从 lwipopts.h 到 PHY 链路4.1 lwipopts.h 里决定收发成败的参数LwIP 有几百个配置项大部分用默认值就行但有几个必须按你的场景改改错就是收发几个包之后就卡住NO_SYS要配合 FreeRTOS 用必须设成 0。LWIP_NETCONN和LWIP_SOCKET想用 socket 风格 API 就都开成 1只想用 raw API 可以关掉省内存。MEM_SIZELwIP 自己堆的大小网络吞吐大时给 16KB 起步数据量大的应用要往上加。PBUF_POOL_SIZE和PBUF_POOL_BUFSIZE每个 pbuf 一个条目缓冲大小要能装下最大帧长。以太网 MTU 1500 加各种头部设成 1524 比较稳。PBUF_LINK_ENCAPSULATION_HLEN如果用了带 VLAN 或特殊封装的链路要留出头部空间否则pbuf_alloc时空间不够会失败。TCP_MSS、TCP_SND_BUF、TCP_WND这三个决定 TCP 吞吐。MSS 一般 1460SND_BUF 和 WND 给4 * TCP_MSS是比较通用的起点。TCPIP_THREAD_STACKSIZEtcpip 线程栈1024 字4KB是常用值开了 socket 后建议 2048。CHECKSUM_BY_HARDWAREF407 的 MAC 支持硬件校验和开了能省 CPU但要确认收包侧也正确处理。我之前遇到过一种情况PBUF_POOL_SIZE设成 8短连接小数据量完全没问题一旦做连续大包传输就断流。原因就是 pbuf 池被耗尽收包时分配不到缓冲包直接被丢TCP 层触发重传看起来就像网络时通时断。把池子加到 16 再测就正常了。4.2 ethernetif.c 的中断收包链路怎么搭ethernetif.c是 LwIP 和网卡驱动之间的桥。它要实现四个函数low_level_init初始化 MAC 和 PHY启动 DMA 接收、low_level_output把 pbuf 链拷进发送缓冲并触发发送、low_level_input从接收缓冲拼出 pbuf 链、ethernetif_input把 pbuf 交给netif-input处理。中断收包的具体流程是ETH 接收中断进来调用HAL_ETH_RxCpltCallback或者你自己的回调在回调里xSemaphoreGiveFromISR释放一个信号量同时有一个专门的ethernetif_input任务阻塞在这个信号量上被唤醒后调用low_level_input把数据搬出来再通过netif-input送进 LwIP 的tcpip_thread。这里有个细节特别容易出错low_level_input里分配 pbuf 用的是pbuf_alloc如果返回 NULL不能直接返回否则信号量已经消耗掉但数据没取走会导致后续包全部堵住。正确做法是循环取包直到取不到为止或者在失败时把中断重新挂上让下次中断再取。另一个坑是发送侧。low_level_output在 pbuf 释放和 DMA 发送完成之间有个时间差如果你在 pbuf 里直接让 DMA 去读数据然后立即释放 pbufDMA 读到的可能是被复用的内存。稳妥的做法是先拷到自己管理的发送缓冲等 DMA 发送完成中断后再标记缓冲可用。4.3 PHY 地址、自协商和 RMII 时钟的排查顺序PHY 层是最容易出现灯亮但不通的地方。排查顺序我一般按这个走确认 RMII 参考时钟。用示波器量 PA1 上是否有稳定的 50MHz。没有的话要么 PHY 侧没供时钟要么 MCO1 配置错了。这个不对后面全部免谈。确认 MDIO/MDC 通信。读 PHY 的 ID 寄存器寄存器 2 和 3读到的值应该和 PHY 型号对应。读不到就是硬件连接或者时钟问题。确认 PHY 地址。DP83848 的地址由 PHYAD 引脚决定常见是 0x01LAN8720 常见是 0x00 或 0x01。地址写错读写全是 0 或者超时。确认自协商结果。读基本状态寄存器寄存器 1看链路是否 up、速率是 100M 还是 10M、双工模式是什么。如果协商成 10M 半双工而 MAC 侧配的是 100M 全双工就会大量丢包。检查复位时序。PHY 复位后需要等一段时间才能访问寄存器太早读写会失败。这几步都过了MAC 和 PHY 的链路基本就通了接下来才是协议栈层面的问题。5. 中断优先级分组与 sys_arch 的对接5.1 从逻辑优先级到寄存器数值的换算FreeRTOS 里配置的configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY是一个逻辑上的优先级数值范围是 0 到 15因为 4 位优先级。而写进BASEPRI寄存器的值需要左移到高 4 位也就是值 (8 - 4)。这就是为什么宏定义要写成5 (8-4)。在代码里给中断设优先级用的还是逻辑值HAL_NVIC_SetPriority(ETH_IRQn, 5, 0);这里的 5 必须大于等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY。如果设成 3那么这个中断不受 FreeRTOS 屏蔽保护但它又会调用xSemaphoreGiveFromISR结果就是内核数据被破坏。一个实用的自检方法在初始化结束后打印所有会调用内核 API 的中断的优先级逐个对照阈值检查一遍。我在一个项目里就是因为漏了一个串口 DMA 中断设成了默认的 0跑了几小时才崩一次排查花了整整两天。5.2 sys_arch.c 里信号量、邮箱和超时的实现LwIP 在NO_SYS0模式下通过sys_arch.c把自身的信号量、邮箱、线程抽象映射到 FreeRTOS 上。核心映射关系是sys_sem_t映射成 FreeRTOS 的SemaphoreHandle_t用计数信号量实现。sys_mbox_t映射成QueueHandle_t队列元素存的是void*指针。sys_mutex_t映射成互斥量注意优先级继承要开否则高优先级任务等低优先级任务持有的锁会出现优先级反转。sys_thread_new用xTaskCreate创建任务栈大小参数单位要换算。超时处理上要特别注意单位。LwIP 的sys_arch_mbox_fetch参数是毫秒而xQueueReceive的参数是 tick 数需要除以portTICK_PERIOD_MS。当portTICK_RATE_HZ是 1000 时两者相等但如果 tick 频率改成 100直接传毫秒值就会导致超时时间放大 10 倍进而拖慢整体收发。u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { TickType_t ticks; if (timeout 0) { ticks portMAX_DELAY; } else { ticks timeout / portTICK_PERIOD_MS; if (ticks 0) ticks 1; } if (xQueueReceive(*mbox, msg, ticks) ! pdTRUE) { return SYS_ARCH_TIMEOUT; } return 0; }另外sys_arch_protect和sys_arch_unprotect的实现要根据是否启用中断嵌套来定简单场景用taskENTER_CRITICAL和taskEXIT_CRITICAL就够但要注意不能在中断里调用。6. 联调排查从 PHY 灯不亮到稳定 ping 的完整链路6.1 分层验证法别想一步到位我的习惯是把验证拆成三层每层单独跑通哪层出问题一目了然。第一层是裸机验证。不挂 FreeRTOS直接用 HAL 库初始化 ETH写一个最简单的收发测试能 ping 通或者能收发 UDP 就行。这一层排除的是硬件、PHY 时序、DMA 描述符、引脚复用这些纯底层问题。第二层是挂上 FreeRTOS 但不跑 LwIP。创建几个任务互相发信号量确认调度正常、SysTick 正常、串口打印正常。这一层排除的是 port 文件、中断优先级、堆配置这些问题。第三层才把 LwIP 加进来。先只跑一个简单的 TCP echo 服务跑通之后再上 DHCP、socket、应用层协议。这样即使出问题也能快速判断是新加的哪一层引起的。这个顺序看起来慢实际上比一上来就全堆上去然后对着黑盒猜要快得多。我见过最惨的一个情况是所有东西一次性合并结果 PHY 地址错了、中断优先级也错了、pbuf 池又太小三个问题叠在一起现象是偶发死机加偶发断网根本没法定位。6.2 常见故障现象与根因的对照表现象最可能的根因验证方法PHY 灯不亮RMII 参考时钟缺失或 PHY 未复位示波器量 50MHz 时钟读 PHY ID 全 0PHY 地址错或 MDIO 引脚配置错换几个常见地址试读裸机 ping 通挂 OS 后不通ETH 中断优先级越界检查中断优先级数值开机即 HardFaultFPU 未使能或中断向量表未映射查 CPACR 和 it.c 中的 ISR传输一段时间后断流pbuf 池耗尽或内存碎片增大 PBUF_POOL_SIZE切 heap_4大数据量时丢包TCP_WND/SND_BUF 太小提高到 4 倍 MSS 以上浮点结果异常中断里做了浮点运算把浮点运算移到任务中串口无输出栈太小导致溢出开configCHECK_FOR_STACK_OVERFLOW6.3 吞吐与稳定性压测怎么做功能跑通只是及格线真正上线前要做压测。我一般会做三件事一是长时 ping。连续跑 24 小时统计丢包率。正常应该接近 0如果有少量丢包检查 pbuf 池和 DMA 描述符数量。二是大文件传输。PC 端用iperf或者自己写个 TCP 客户端发 100MB 数据观察是否有卡顿、重传、内存增长。重点关注MEM_SIZE是否吃紧、堆是否被慢慢耗光。用xPortGetFreeHeapSize定时打印剩余堆如果数值持续下降不回升说明有泄漏或者碎片化。三是多任务并发。让网络任务和串口任务、ADC 任务同时跑把各任务优先级拉开观察网络延迟是否受影响。如果 CPU 占用过高可以考虑开硬件校验和减少软件计算量。关于 LwIP 的内存占用监控mem_used()和mem_peak()这两个接口很有用可以定期打印出来。但要注意它们依赖LWIP_STATS和MEMP_STATS不开统计功能是拿不到数据的。我个人的体会是F407 这套组合的稳定性八成取决于配置而不是代码本身。真正需要写的代码量并不大port 层几乎不用动ethernetif 和 sys_arch 也就几百行剩下的都是配置项的取舍。配置对了跑起来就是稳的配置错了写再多补丁也是按下葫芦浮起瓢。所以每次新项目开始我都会把FreeRTOSConfig.h和lwipopts.h这两个文件从头到尾读一遍把每个非默认值的项都问自己一句为什么设成这个值很多隐藏问题在写代码之前就被发现了。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号