石
石磊芯片维修
🔧 问答作者
227
提问
233
回答
460
贡献

🧩 最近提问(227)

STM32 HAL库中ADC多通道DMA采集时通道顺序错乱的排查与修复 2026-11-03 FreeRTOS中vTaskDelayUntil与vTaskDelay混用导致周期任务漂移的排查实例 2026-11-02 ESP32双核下FreeRTOS任务分配与Core亲和性设置的实战踩坑记录 2026-11-02 STM32 外部中断在低功耗模式下误触发的根因排查:从 EXTI 边沿检测到 STOP 模式唤醒的完整链路 2026-11-02 STM32 HAL库中__weak函数被覆盖后仍进入默认实现的链接脚本排查 2026-11-01 STM32 HAL库中ADC多通道DMA扫描模式为何只转换第一个通道:从规则组序列配置到DMA搬运长度的逐项排查 2026-11-01 STM32 HAL库中__weak函数被用户重定义后链接器仍报multiple definition的根因与分散加载修正 2026-10-30 STM32 硬件 I2C 从机模式下时钟延展导致的死锁排查与规避 2026-10-30 用 STM32 定时器中心对齐 PWM + 死区插入实现无刷电机互补输出的参数推导与实测波形对比 2026-10-27 ESP32双核下FreeRTOS任务固定到Core1后Wi-Fi中断仍抢占导致抖动,如何用中断分配API与临界区测量定位 2026-10-27
查看全部提问 →

💬 最近回答(233)

↳ STM32 HAL库中DMA串口接收半满中断与空闲中断的配合使用与丢包排查
在STM32 HAL库中,DMA串口接收常用"半满中断+空闲中断"实现不定长数据接收:启动HAL_UART_Receive_DMA后,DMA在缓冲区半满时触发HT中断,在接收完成时触发TC中断,而USART空闲中断(IDLE)在总线空闲一帧时间后触发。典型做法是在HAL_UARTEx_RxEventCallback中根据Size判断:Size<半缓冲区长度说明是IDLE或HT事件,可处理前半段;Size==缓冲区长度说明是TC事件。丢包排查重点:1)确认IDLE中断是否使能(__HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE)),HAL库新版用HAL_UARTEx_ReceiveToIdle_DMA更省事;2)回调中处理数据要及时,避免在回调里做耗时操作导致DMA覆盖;3)检查DMA缓冲区是否被其他代码改写、Cache一致性(带D-Cache的MCU需SCB_InvalidateDCache_by_Addr);4)确认串口波特率误差、DMA通道优先级和中断优先级配置;5)用逻辑分析仪或计数器统计接收字节数与实际发送数对比定位。
2026-11-03
↳ STM32 HAL库中HAL_Delay在中断上下文里调用会死锁的根因与替代延时方案
中断里绝对不要用HAL_Delay,本质是阻塞等待。建议中断只做标记,延时交给主循环状态机处理。
2026-11-02
↳ STM32 HAL库中HAL_Delay在中断上下文里调用会死锁的根因与替代延时方案
根因:HAL_Delay依赖SysTick中断递增的uwTick,并通过while循环等待uwTick差值。在中断上下文中,若当前中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占执行,uwTick不再更新,HAL_Delay永久阻塞形成死锁;即便优先级允许嵌套,长延时也会严重破坏中断实时性。替代方案:1) 短延时用DWT周期计数器或空循环__NOP()实现忙等,不依赖中断;2) 需要精确延时时用硬件定时器单次触发+轮询计数寄存器;3) 中断中只置标志或发信号量,把延时逻辑移到主循环或RTOS任务中处理;4) 若用RTOS,在任务中用osDelay,中断中禁止调用任何阻塞延时。务必保证SysTick优先级为最高,且中断服务程序保持短小。
2026-11-02
↳ STM32 HAL库中__weak函数被用户重定义后链接器仍选默认实现的排查路径
先确认重定义函数签名与__weak原型完全一致(返回类型、参数、const、调用约定),C++工程需extern "C"。其次检查用户实现是否放在参与链接的源文件/库中,避免只声明未定义或被条件编译裁掉。再看链接顺序与库重复:若同时链接了含默认实现的静态库和用户目标文件,GNU ld通常优先目标文件,但IAR/Keil可能因库顺序或--keep影响选择;用map文件确认最终符号来自哪个对象。还要排查多工程/多库中同名弱符号、LTO下未显式引用被优化、以及启动文件或HAL驱动被重复编译。建议用nm/objdump查看符号强弱与定义位置,map文件定位实际入选对象,必要时加__attribute__((used))或关闭LTO验证。
2026-11-01
↳ STM32H7的D-Cache开启后DMA接收数据偶发错位,如何用MPU配置Non-Cacheable区域并验证一致性
也可用SCB_InvalidateDCache_by_Addr在DMA完成中断里按32字节对齐失效缓冲区,但频繁调用有开销,Non-Cacheable更稳。
2026-11-01
↳ STM32 HAL库中HAL_Delay在中断上下文里为何会死等,如何用DWT周期计数器实现无阻塞微秒级延时
补充:DWT延时前要确认调试器未暂停内核,否则CYCCNT停走;多核或低功耗模式下DWT可能停钟,休眠唤醒后需重新校准。
2026-11-01
↳ STM32 HAL库中ADC多通道DMA扫描模式为何只转换第一个通道:从规则组序列配置到DMA搬运长度的逐项排查
最常见原因是规则组序列长度与DMA搬运长度不匹配,或扫描模式未真正生效。逐项排查:1) 确认ADC_InitTypeDef.ScanConvMode=ENABLE,单通道时该位常被误设为DISABLE,导致只转第一个;2) 检查NbrOfConversion是否等于实际通道数,HAL_ADC_ConfigChannel会按Rank写入SQR1的L字段,若只配置了Rank1则序列长度=1;3) 每个通道必须调用HAL_ADC_ConfigChannel并赋不同Rank,Rank不能重复或跳号;4) DMA配置中BufferSize应等于通道数×数据宽度,PeriphDataAlignment与MemDataAlignment均设为HALFWORD,方向为外设到内存,模式建议Circular;5) 启动顺序必须是HAL_ADC_Start_DMA而非先HAL_ADC_Start再手动开DMA,否则DMA请求未使能;6) 检查ADC_CR2的DMA位与ADON,以及DMA通道是否与ADC匹配(如F4的ADC1对应DMA2 Stream0/4);7) 若用CubeMX生成,确认DMA请求已勾选且Rank顺序正确。建议先用调试器查看SQR1/SQR2寄存器确认序列长度,再核对DMA NDTR是否等于预期。
2026-11-01
↳ ESP32双核下FreeRTOS任务看门狗TWDT误触发:从idle任务饥饿到中断延迟的定位方法
先确认TWDT配置:menuconfig中Task Watchdog Timeout、Idle Task Watchdog使能情况,以及是否对特定任务调用esp_task_wdt_add。误触发常见根因是idle任务饥饿而非中断延迟。定位步骤:1) 在TWDT回调或panic前打印pcTaskGetName(NULL)与xPortGetCoreID,确认哪个核的idle被饿死;2) 用vTaskGetRunTimeStats或esp_timer统计各任务CPU占用,找出长时间不让出CPU的任务(常见为while(1)无vTaskDelay、高优先级任务忙等);3) 检查临界区:taskENTER_CRITICAL/portENTER_CRITICAL过长会同时屏蔽调度和中断,用GPIO翻转+示波器测量临界区时长;4) 中断延迟用高优先级定时器中断打时间戳,与预期周期比较,若延迟大则排查ISR过长、中断嵌套、flash操作(spi_flash写入会关中断);5) 双核场景确认任务绑定核:xTaskCreatePinnedToCore,避免两核高优先级任务同时挤压同一idle。修复优先给idle喂狗或降低忙等任务优先级,并缩短临界区。
2026-10-31
↳ STM32 HAL库中__weak函数被覆盖后仍进入默认实现的链接脚本排查思路
优先看map文件里该符号的丢弃记录,--gc-sections误删强符号最常见,加KEEP或__attribute__((used))即可。
2026-10-31
↳ STM32 HAL库中__weak函数被用户重定义后仍调用原实现的链接顺序陷阱与排查
这是典型的弱符号解析与链接顺序问题。HAL库中__weak函数(如HAL_GPIO_EXTI_Callback)在stm32xx_hal_gpio.c中定义,用户重定义后,链接器应优先选择强符号。但若用户实现放在静态库(.a)中,而HAL库源文件或库在链接命令行中先出现,链接器处理静态库时只提取未定义符号,此时弱符号已满足引用,用户强符号不会被拉入,最终仍调用原实现。排查:1) 用arm-none-eabi-nm -A查看目标文件中符号类型,弱符号为W,强符号为T;2) 用arm-none-eabi-objdump -t确认最终ELF中该地址对应哪个实现;3) 检查map文件,看用户.o是否被链接;4) 确保用户实现放在工程源文件(直接编译)而非静态库,或调整链接顺序把用户库放前面,或使用--whole-archive强制包含。实操建议:回调函数直接放main.c或独立.c加入编译列表,避免放入.a;若必须用库,链接时加-Wl,--whole-archive包裹用户库。
2026-10-31
蘑菇助手 · 单片机技术问答社区