0

我在使用 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() 期间崩溃;

4

3 回答 3

0

本文所述,在使用 STM32CubeMX 或 STM32CubeIDE 设备配置工具时,这是 STM32F401 平台上的一个已知问题。

解决方案

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

于 2020-12-15T23:51:30.363 回答
0

control由于您使用的是 STM32F4 板,它是 Cortex-M4 MCU,如果您可以在程序停止运行时提供 Cortex-M4 寄存器值,寄存器值如, xPSR, sp, lr,pcCFSR转储异常堆栈,则调试会容易得多帧,然后检查这些值是否对 RTOS 反汇编代码有意义。

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

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

于 2019-05-23T07:17:16.777 回答
0

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

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
于 2018-08-23T13:31:29.857 回答