关于#学习freertos使用时发生中断卡死#的问题,如何解决?

学习消息队列,调用freertos中断API函数时,出现了问题,调试追踪发现卡死在portASSERT_IF_INTERRUPT_PRIORITY_INVALID();这个宏,该如何解决呢。

其中主要是两个中断,配置如下:

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

HAL_NVIC_SetPriority(EXTI4_IRQn, 7, 0);    // 对应是 CLK_CHECK_Pin 中断
HAL_NVIC_EnableIRQ(EXTI4_IRQn);

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0); // 对应是 B2A_Pin 中断
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

其中CLK_CHECK_Pin 中断发生时都能正常响应,就是当B2A_Pin 中断来临时出现卡死portASSERT_IF_INTERRUPT_PRIORITY_INVALID();这里,我的系统中实时性高,没法用printf来进行调试,只有通过逻辑分析仪和翻转LED来进行调试,已经尝试更改了B2A_Pin了的优先级设置为


HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0); // 对应是 B2A_Pin 中断
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

还是死机,暂时不晓得咋处理,现在唯一的解决方式在B2A_Pin 中断发生时不使用freertos相关API。来平台主要是想问一下有没有人碰到过类似的事情,如何解决的,同时是方便自己对freertos的理解

相关的业务的代码如下:

#include "business_task.h"
#include "main.h"
#include 


osThreadId businessTaskHandle;

osMessageQId businessQueueHandle;

// 业务任务的入口函数
void StartBusinessTask(void const * argument)
{
    uint32_t data = 0;
    // 在这里编写任务的代码
    while (1) {
        // 从消息队列中获取数据
        osEvent event = osMessageGet(businessQueueHandle, osWaitForever);
        data = event.value.v;
        // 处理数据并进行相应的操作
        if (data == CLK_CHECK_Pin) {
            do_something();  // 这里需要很长时间来进行处理
        }
        else if(data == B2A_Pin) {
            HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
        }
    }
}

// void SetBusinessQueueHandle(osMessageQId queue_id)
// {
//     // 将消息队列句柄保存到全局变量中
//     businessQueueHandle = queue_id;
// }


// 初始化业务任务
void InitBusinessTask(void)
{
    osThreadDef(businessTask, StartBusinessTask, osPriorityRealtime, 0, 128);
    businessTaskHandle = osThreadCreate(osThread(businessTask), NULL);


    osMessageQDef(businessQueue, 16, uint32_t); // 将队列的最大容量设置为 16
    businessQueueHandle = osMessageCreate(osMessageQ(businessQueue), NULL);

    
    // 将业务任务的消息队列句柄传递给中断处理函数
    // SetBusinessQueueHandle(businessQueueHandle);
}



// 向业务任务发送数据
bool SendDataToBusinessTask(uint32_t data)
{
    if (osMessagePut(businessQueueHandle, data, 0) != osOK) {
        return false;
    }
    return true;

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == CLK_CHECK_Pin) {
        SendDataToBusinessTask(CLK_CHECK_Pin);
    }
    else if (GPIO_Pin == B2A_Pin) {
        // HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
        SendDataToBusinessTask(B2A_Pin);
    }
}


FreeRTOSConfig.h的内容如下:


/* USER CODE BEGIN Header */
/*
 * FreeRTOS Kernel V10.0.1
 * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */
/* USER CODE END Header */

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * These parameters and more are described within the 'configuration' section of the
 * FreeRTOS API documentation available on the FreeRTOS.org web site.
 *
 * See http://www.freertos.org/a00110.html
 *----------------------------------------------------------*/

/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */

/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
  #include 
  extern uint32_t SystemCoreClock;
#endif
#define configUSE_PREEMPTION                     1
#define configSUPPORT_STATIC_ALLOCATION          1
#define configSUPPORT_DYNAMIC_ALLOCATION         1
#define configUSE_IDLE_HOOK                      0
#define configUSE_TICK_HOOK                      0
#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
#define configTICK_RATE_HZ                       ((TickType_t)1000)
#define configMAX_PRIORITIES                     ( 7 )
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTOTAL_HEAP_SIZE                    ((size_t)6144)
#define configMAX_TASK_NAME_LEN                  ( 16 )
#define configUSE_16_BIT_TICKS                   0
#define configUSE_MUTEXES                        1
#define configQUEUE_REGISTRY_SIZE                8
#define configUSE_PORT_OPTIMISED_TASK_SELECTION  1


/* Co-routine definitions. */
#define configUSE_CO_ROUTINES                    0
#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet            1
#define INCLUDE_uxTaskPriorityGet           1
#define INCLUDE_vTaskDelete                 1
#define INCLUDE_vTaskCleanUpResources       0
#define INCLUDE_vTaskSuspend                1
#define INCLUDE_vTaskDelayUntil             0
#define INCLUDE_vTaskDelay                  1
#define INCLUDE_xTaskGetSchedulerState      1

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
 /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
 #define configPRIO_BITS         __NVIC_PRIO_BITS
#else
 #define configPRIO_BITS         4
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   15

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#include "main.h"
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; )HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);}
/* USER CODE END 1 */

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler    SVC_Handler
#define xPortPendSVHandler PendSV_Handler

/* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick,
              to prevent overwriting SysTick_Handler defined within STM32Cube HAL */

#define xPortSysTickHandler SysTick_Handler

/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
/* USER CODE END Defines */

#endif /* FREERTOS_CONFIG_H */

以下内容部分参考ChatGPT模型:


这个问题可能是由于中断优先级设置不当导致的。您可以尝试将B2A_Pin中断的优先级设置为更高的值,例如6或7。同时,确保您在FreeRTOSConfig.h中正确地设置了configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY宏。如果这些操作没有解决问题,您可以尝试在HAL_GPIO_EXTI_Callback函数中使用vTaskNotifyGiveFromISR函数代替SendDataToBusinessTask函数,这可能会更好地与FreeRTOS API协同工作。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
在FreeRTOS中,中断的优先级必须要小于configMAX_SYSCALL_INTERRUPT_PRIORITY所定义的值,该值的默认设置为5,在FreeRTOSConfig.h中可以看到。因此,在配置中断优先级时,需要确保在使用FreeRTOS之前已经减小了中断优先级。

要解决在 portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); 处崩溃的问题,您需要检查中断优先级是否正确配置。建议您将B2A_Pin中断的优先级设置为具有较高优先级的IRQn,如USART_RX_IRQn,并确保设置正确。另外,建议您在编写业务代码时使用FreeRTOS API,以避免出现问题。

另外,您可以使用实时内存分析器或记录器来检查任务和堆栈的使用情况,以帮助您解决问题。

最后,以下是一个参考的配置示例,可以作为您的FreeRTOSConfig.h文件的参考,以确保正确配置:

#define configUSE_PREEMPTION             1
#define configUSE_IDLE_HOOK              0
#define configUSE_TICK_HOOK              0
#define configCPU_CLOCK_HZ               ( SystemCoreClock )
#define configTICK_RATE_HZ               ((TickType_t)1000)
#define configMINIMAL_STACK_SIZE         ((uint16_t)128)
#define configTOTAL_HEAP_SIZE            ((size_t)(50 * 1024))
#define configMAX_TASK_NAME_LEN          (16)
#define configUSE_TRACE_FACILITY         1
#define configUSE_16_BIT_TICKS           0
#define configIDLE_SHOULD_YIELD          1
#define configUSE_MUTEXES                1
#define configUSE_RECURSIVE_MUTEXES      1
#define configUSE_COUNTING_SEMAPHORES    1
#define configQUEUE_REGISTRY_SIZE        8
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configMAX_PRIORITIES             (7)
#define configKERNEL_INTERRUPT_PRIORITY (0xF << (8 - configPRIO_BITS))
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  (0x0 << (8 - configPRIO_BITS))

希望这些信息能够帮助到您解决问题。
如果我的回答解决了您的问题,请采纳!

这个宏是在检查中断优先级是否有效,如果无效会导致系统卡死。出现这个问题,可能是由于中断优先级设置错误或者中断服务函数中产生了死循环等问题。

解决方法如下:

1.检查中断优先级设置是否正确,确保中断优先级不低于FreeRTOS内核的最低优先级。

2.检查中断服务函数中是否产生了死循环,可以在中断服务函数中适当添加延时以避免产生死循环。

3.尝试在调用中断API函数之前禁用中断,并在调用完毕后重新使能中断,以避免中断优先级冲突导致的系统卡死问题。

4.如果以上方法都没有解决问题,可以考虑重新编译和链接FreeRTOS库,并确保使用的是最新的版本。

总之,解决这个问题需要仔细检查和诊断,找到问题的根本原因并逐一排除。

这个错误提示是FreeRTOS的一个断言机制,它用于检测中断的优先级是否合法,如果不合法,则会触发该错误,导致程序停止。

在你的代码中,错误提示是出现在B2A_Pin的中断处理程序中,但是你已经将其优先级设置为0,而CLK_CHECK_Pin的中断处理程序没有出现问题。

我注意到你的业务任务使用了osPriorityRealtime优先级,而不是优先级7和10,所以这可能是导致问题的原因之一。FreeRTOS内核定义了一些不同的任务优先级,在不同的应用场景中可以使用不同的优先级。

如果你的业务任务确实需要高优先级,请确保它的优先级低于所有中断优先级,否则可能会导致中断嵌套问题。

另外,检查一下B2A_Pin的中断处理程序中是否有一些需要太长时间来执行的操作,可能会导致响应时间超时,进而导致中断嵌套。

如果你仍然无法解决问题,请尝试调用vApplicationStackOverflowHook()函数,它会在堆栈溢出时调用。你可以在该函数中添加一些调试信息,以便更好地了解问题所在。

最后,检查一下FreeRTOS的内核配置是否正确。你可以尝试将FreeRTOSConfig.h文件的配置还原为默认值,并确保你的应用程序与该配置兼容