解决STM32使用FreeRTOS时串口中断接收卡死问题

现在意法半导体的配套软件做得很全面了,简直可以说是保姆式的服务。从芯片选型,引脚定义,到代码模板生成,一条龙服务,很方便。但是方便也有方便的坏处,那就是有些细节的规则会造成天然的bug。
比如,在stm32cubeIDE里新建工程的时候,如果勾选了FREERTOS

那么,程序后台会默认把RTOS可控的优先级范围设定成5-15(目前还看不见,生成后在FreeRTOSConfig.h中可以查到):

接下来继续配置串口。


可以看到,串口中断的优先级已经被锁定成5,且不可更改。
实际上这样暂时还没有什么问题,生成代码后,做基本的串口收发一时半会儿也看不出有什么问题。
但是,一旦让程序多跑跑,就会发现,串口中断早晚会卡死,而其他程序还可以正常跑。

这是为什么呢?

在串口中断接收的函数中,有LOCK这样的功能。如果在LOCK期间程序被打断,那么就再也不能解锁,导致卡死。


而由于串口中断的优先级被默认限制成了5,RTOS就有了打断的可能。
所以一切问题的根源是stm32cubeIDE。
要解决这个问题也很简单,去stm32f1xx_hal_msp.c修改一下串口中断的优先级就好了。


默认是5,只要把优先级修改到0-4之间即可。这个范围内RTOS是不会管理的,也就是不会打断。

用到这个函数说明如下:

/**
  * @brief  Sets the priority of an interrupt.
  * @param  IRQn: External interrupt number.
  *         This parameter can be an enumerator of IRQn_Type enumeration
  *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xx.h))
  * @param  PreemptPriority: The preemption priority for the IRQn channel.
  *         This parameter can be a value between 0 and 15
  *         A lower priority value indicates a higher priority 
  * @param  SubPriority: the subpriority level for the IRQ channel.
  *         This parameter can be a value between 0 and 15
  *         A lower priority value indicates a higher priority.          
  * @retval None
  */
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{ 
  uint32_t prioritygroup = 0x00U;
  
  /* Check the parameters */
  assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
  
  prioritygroup = NVIC_GetPriorityGrouping();
  
  NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
}

关键是这句注释:

  •    This parameter can be a value between 0 and 15 A lower priority value indicates a higher priority 
    
  • 所以,保姆虽然事无巨细,但还是无法做到面面俱到呀。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 解决STM32使用FreeRTOS时串口中断接收卡死问题

    发表回复