FreeRTOS 在串口中断中推送消息到队列configASSERT((portAIRCR_REG&portPRIORITY_GROUP_MASK) <= ulMaxPRIGROUPValue);

前言:使用的芯片是GD32F305VCT6, 使用的FreeRTOS版本是FreeRTOS Kernel V10.4.6

一、问题描述

在串口接受中断中调用的推送函数是xQueueSendToBackFromISR,发现程序在执行完

configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );

之后进入了如下的钩子函数

void vAssertCalled( void )
{
    while(1);
}

二、程序配置和操作方法

由于我的程序没有调用nvic_priority_group_set设置优先级分组 ,因此在调用nvic_irq_enable之后会使用默认中断优先级分组nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  设置的中断优先级是nvic_irq_enable(USART2_IRQn, 1, 2);

推送任务进入中断之后,调用xQueueSendToBackFromISR推送消息到其他任务队列,结果

程序执行完configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); 之后卡死,执行时debug获取参数如下

  计算参数发现程序在改配置下计算portAIRCR_REG & portPRIORITY_GROUP_MASK出来时为0x500 并不小于ulMaxPRIGROUPValue的0x300。

三、解决办法

        /* Priority grouping:  The interrupt controller (NVIC) allows the bits
         * that define each interrupt's priority to be split between bits that
         * define the interrupt's pre-emption priority bits and bits that define
         * the interrupt's sub-priority.  For simplicity all bits must be defined
         * to be pre-emption priority bits.  The following assertion will fail if
         * this is not the case (if some bits represent a sub-priority).
         *
         * If the application only uses CMSIS libraries for interrupt
         * configuration then the correct setting can be achieved on all Cortex-M
         * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
         * scheduler.  Note however that some vendor specific peripheral libraries
         * assume a non-zero priority group setting, in which cases using a value
         * of zero will result in unpredictable behaviour. */

        /*优先级分组:中断控制器(NVIC)允许该比特位
        *定义了每个中断在比特之间拆分的优先级
        *定义中断的抢占优先级
        *中断的次优先级。为简单起见,所有比特位都必须定义
        *是抢占优先级位。如果。下面的断言将失败
        *情况并非如此(如果某些比特位表示次优先级)。
        *
        *如果应用程序仅使用CMSIS库进行中断
        *配置然后可以在所有Cortex-M上实现正确的设置
        *通过调用NVIC_SetPriorityGrouping(0)来处理设备;在启动
        *调度器。但请注意,某些供应商特定的外设库
        *假设一个非零的优先级组设置,在这种情况下使用一个值
        *值为0将导致不可预测的行为。* /
        configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );

在语句configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );上方有一段注释是希望程序的设置是没有子优先级只有抢占优先级的,也就是子优先级的中断要设置为0,于是决定配置一下优先级分组为nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0); 问题解决程序正常运行

四、注意事项

由于我想在中断中推送消息,但是FreeRTOSConfig.h中的配置项为5

#define configMAX_SYSCALL_INTERRUPT_PRIORITY    5 /* equivalent to 0xa0, or priority 5. */

因此最好将nvic_irq_enable(USART2_IRQn, 1, 2); 配置为nvic_irq_enable(USART2_IRQn, 6, 0);


有错误麻烦各位及时指正了

当你提到程序在 `configASSERT((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0);` 卡住时,这通常意味着某个地方出现了不符合预期的行为。特别是在使用动态内存分配函数如 `pvPortMalloc()` 的情况下出现问题,可能涉及到堆管理、中断环境以及临界区控制等多个方面的原因。让我们逐步排查并理解这个问题。 ### 理解问题背景 首先回顾一下 `vPortEnterCritical()` 中的这段代码片段: ```c if (uxCriticalNesting == 1) { configASSERT((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0); } ``` 这里的断言用于确保调用者不是从中断服务例程(ISR)内部直接进入临界区的,因为普通用户级别的临界区处理并不适用于 ISR 场景。如果从 ISR 内部调用了非 ISR 版本的临界区函数就会触发这一断言失败,进而可能导致程序挂起或其他未定义行为。 ### 分析原因 既然你提到的是 `pvPortMalloc()` 导致上述断言失效,那么很可能是由于以下几个原因之一造成的: 1. **从中断上下文调用**:如果你是从一个中断服务程序中调用了 `pvPortMalloc()` 或其它类似的标准 C 库或 RTOS API 函数,而不是专门针对 ISR 设计的安全版本,则会导致系统认为它不应该在此处关闭中断而产生冲突。 2. **堆空间不足或损坏**:当可用堆大小不足以满足请求时,某些实现可能会陷入无限循环等待更多空闲内存块释放出来;另外如果是堆本身遭到破坏也会影响正常的分配过程。不过这类情况一般不会直接引发上面说的那种特定类型的断言错误,但仍需考虑进去作为潜在因素之一。 3. **配置不当**:FreeRTOS 配置文件里有关于栈深度、队列长度等参数设置不合理的话,在极端条件下也可能间接影响到内存管理和调度机制的工作状态。例如设定过小的任务栈容易造成溢出从而覆盖了不该改动的数据区域包括那些与中断相关的寄存器信息等等。 4. **并发访问冲突**:尽管不太常见但也有可能存在多任务之间对于相同资源的竞争状况未能得到良好解决,最终导致意外后果发生。 ### 解决建议 基于以上可能性,我们给出以下几种解决方案来进行尝试: - **检查调用位置**: - 检查你的代码是否确实从未曾试图在一个 ISRs 内调用过标准形式而非 FromISR 结尾版别的 FreeRTOS 动态内存管理功能。 - **改用适合 ISR 的函数**: - 使用专门为中断环境设计的安全版本比如 `xQueueSendToBackFromISR()`, `pvPortMallocFromISR()` 等代替默认的选择。 - **增加调试日志**: - 添加更多的打印语句或者借助 JTAG 接口配合 IDE 工具进行单步跟踪来定位具体的卡顿点究竟发生在哪一行代码上。 - **审查堆初始化和尺寸调整**: - 核对你项目内关于总 heap size 和各个 task stack size 相关选项的实际取值是不是合适合理范围内。 - **优化资源争用策略**: - 如果确实发现了多个 tasks 对单一 shared resource 存在同一时间内争夺使用权的现象,则应当引入适当的同步原语诸如 semaphores, mutexes 加强协调沟通减少不必要的碰撞几率。 最后还要强调一点的就是务必遵循官方文档提供的最佳实践指南去做相应的修改和完善工作哦! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值