裸机STM32F4x使用FreeRTOS Heap4的pvPortMalloc/vPortFree中断问题咨询
根因定位
pvPortMalloc和vPortFree内部默认调用FreeRTOS内核的临界区保护接口portENTER_CRITICAL()/portEXIT_CRITICAL(),你遇到的中断永久关闭问题100%是临界区退出逻辑异常导致,对应以下几种常见场景:
排查&解决步骤
第一步:确认你已经完成FreeRTOS内核基础初始化
很多开发者误以为Heap4是完全独立的模块,实际它依赖内核全局变量uxCriticalNesting的初始值,该变量仅在调用vTaskInitializeScheduler()时会被初始化为0。如果未做初始化就调用内存接口,uxCriticalNesting上电为随机值,临界区退出时计数无法归0,就不会触发开中断操作。
如果你不需要启动调度器,仅想用Heap4的内存管理能力,可以直接修改Heap4.c源码,把内部所有portENTER_CRITICAL()替换为__disable_irq(),portEXIT_CRITICAL()替换为__enable_irq(),完全脱离FreeRTOS内核依赖即可。第二步:检查NVIC中断优先级分组配置
Cortex-M内核架构下,FreeRTOS要求必须把NVIC优先级分组设为4位抢占优先级、0位子优先级,对应STM32 HAL库调用HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)。如果分组配置错误,port层操作BASEPRI寄存器的逻辑会完全失效,导致退出临界区时无法正确开中断。第三步:校验FreeRTOSConfig.h配置项
重点核对以下配置是否匹配你的硬件参数:configCPU_CLOCK_HZ必须设为STM32F4的内核主频,通常为168000000configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY必须符合STM32F4的4位优先级设计,取值范围为0~15,不要超过你实际外设中断配置的最高屏蔽优先级- 未启动调度器前不要开启
configUSE_PORT_OPTIMISED_TASK_SELECTION等调度器优化配置,避免触发异常逻辑
验证方法
调用pvPortMalloc前后分别读取BASEPRI寄存器的值,如果调用后BASEPRI为非0值,即可确认是临界区未正确退出,按上述步骤排查即可。
内容的提问来源于stack exchange,提问作者Sheikh Muhammad Junaid Aslam

