环境:STM32F103VCT6
问题:
先初始化了外设,然后到调用 vTaskStartScheduler 启动调度器时就直接跳转到 HardFault_Handler
启动调试,然后找到HardFault_Handler,Show Caller Code 跳转到 post.c 该函数:
__asm void prvStartFirstTask( void )
{
PRESERVE8
/* Use the NVIC offset register to locate the stack. */
ldr r0, =0xE000ED08
ldr r0, [r0]
ldr r0, [r0]
/* Set the msp back to the start of the stack. */
msr msp, r0
/* Globally enable interrupts. */
cpsie i
cpsie f
dsb
isb
/* Call SVC to start the first task. */
svc 0
nop
nop
}
解决:
经过逐一排查,发现是 FreeRTOS 系统可管理的最高中断优先级问题,把可管理优先级调高就不会出错了。
修改前:
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
//中断最低优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */
//系统可管理的最高中断优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
//设置可以在中断服务程序中安全调用FreeRTOS API函数的最高中断优先级
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
修改后:
#ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
//中断最低优先级
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */
//设置可以在中断服务程序中安全调用FreeRTOS API函数的最高中断优先级
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 9
关于 configKERNEL_INTERRUPT_PRIORITY 定义可参考基于STM32应用的FreeRTOS中断设置
解决记录:修改启动文件无效
参考 FreeRTOS简单移植到STM32F103ZET6 修改启动文件 startup_stm32f10x_hd.s 无效,并且会报错
修改前:
修改后:
__heap_limit
IMPORT xPortPendSVHandler
IMPORT xPortSysTickHandler
IMPORT xPortSVCHandler
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
;DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
;DCD PendSV_Handler ; PendSV Handler
;DCD SysTick_Handler ; SysTick Handler
后来发现已经在 FreeRTOSConfig.h 文件里面做了以下定义,所以无需以上处理:
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler