CubeMX freeRTOS V9在STM32F4上崩溃

时间:2018-08-21 12:55:44

标签: freertos stm32f4 cubemx

我在使用cubeMX的STM32F4上遇到freeRTOS的特定问题。当我使用支持freeRTOSv8的CubeMX的较旧版本(带有软件包支持,例如STM32Cube_FW_F4_V1.14.0)时,它运行良好,没有问题。当我将CubeMX更新为支持freeRTOSv9的最新版本时,它在运行RTOS调度程序的托盘中崩溃了。

    BaseType_t xPortStartScheduler( void )
{
    /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
    See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
    configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );

    /* This port can be used on all revisions of the Cortex-M7 core other than
    the r0p1 parts.  r0p1 parts should use the port from the
    /source/portable/GCC/ARM_CM7/r0p1 directory. */
    configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
    configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );

    #if( configASSERT_DEFINED == 1 )
    {
        volatile uint32_t ulOriginalPriority;
        volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
        volatile uint8_t ucMaxPriorityValue;

        /* Determine the maximum priority from which ISR safe FreeRTOS API
        functions can be called.  ISR safe functions are those that end in
        "FromISR".  FreeRTOS maintains separate thread and ISR API functions to
        ensure interrupt entry is as fast and simple as possible.

        Save the interrupt priority value that is about to be clobbered. */
        ulOriginalPriority = *pucFirstUserPriorityRegister;

        /* Determine the number of priority bits available.  First write to all
        possible bits. */
        *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;

        /* Read the value back to see how many bits stuck. */
        ucMaxPriorityValue = *pucFirstUserPriorityRegister;

        /* Use the same mask on the maximum system call priority. */
        ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;

        /* Calculate the maximum acceptable priority group value for the number
        of bits read back. */
        ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
        while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
        {
            ulMaxPRIGROUPValue--;
            ucMaxPriorityValue <<= ( uint8_t ) 0x01;
        }

        /* Shift the priority group value back to its position within the AIRCR
        register. */
        ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
        ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;

        /* Restore the clobbered interrupt priority register to its original
        value. */
        *pucFirstUserPriorityRegister = ulOriginalPriority;
    }
    #endif /* conifgASSERT_DEFINED */

    /* Make PendSV and SysTick the lowest priority interrupts. */
    portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
    portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

    /* Start the timer that generates the tick ISR.  Interrupts are disabled
    here already. */
    vPortSetupTimerInterrupt();

    /* Initialise the critical nesting count ready for the first task. */
    uxCriticalNesting = 0;

    /* Ensure the VFP is enabled - it should be anyway. */
    vPortEnableVFP();

    /* Lazy save always. */
    *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;

    /* Start the first task. */
    prvPortStartFirstTask();

    /* Should never get here as the tasks will now be executing!  Call the task
    exit error function to prevent compiler warnings about a static function
    not being called in the case that the application writer overrides this
    functionality by defining configTASK_RETURN_ADDRESS. */
    prvTaskExitError();

    /* Should not get here! */
    return 0;
}
/*-----------------------------------------------------------*/

在第一个任务启动期间崩溃 prvPortStartFirstTask();

3 个答案:

答案 0 :(得分:0)

看起来没有实现PendSV_HandlerSVC_HandlerSysTick_Handler中断处理程序。请检查stm32f4xx_it.c和FreeRTOSConfig.h文件。通常通过定义连接的中断:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

答案 1 :(得分:0)

由于您使用的是STM32F4板卡,所以它是Cortex-M4 MCU,如果您可以在程序停止运行时提供Cortex-M4寄存器值,control,{ {1}},xPSRsplrpc并转储异常堆栈帧,然后检查这些值是否对RTOS反汇编代码有意义。

在用于Cortex-M4的FreeRTOS端口中,CFSR的最后一步是生成SVC异常,然后CPU跳转到SVC处理程序例程。在SVC例外之前,FreeRTOS甚至还没有开始运行第一个任务。

因此,在您的情况下,CPU不太可能在prvPortStartFirstTask()PendSV_Handler中停顿,如果打开了您的MPU,它更有可能卡在故障处理程序例程(例如HardFault或MemManage故障)上。 STM32F4开发板)。如果使用GDB,则可以在此故障处理程序例程SysTick_HandlerHardFault_Handler上添加断点,以找出问题所在。

答案 2 :(得分:0)

根据this post的规定,使用STM32CubeMX或STM32CubeIDE器件配置工具时,这是STM32F401平台上的一个已知问题。

解决方案

在您的STMCubeMX项目中,查找 stm32f4xx_hal_msp.c 文件。然后,将行HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);替换为HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);