前言:使用的芯片是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);
有错误麻烦各位及时指正了