你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

笔记---FreeRtos系统中外设中断优先级设置的要点

[复制链接]
power568 发布时间:2019-4-16 14:15
本帖最后由 power568 于 2019-4-16 16:07 编辑

       最近在写一个串口通讯的程序,软件、硬件平台如下:
硬件: STM32F429ZG
系统: FreeRtos、HAL库
工具:  Iar7.6

       计划是利用串口DMA+IDLE空闲中断的方式接收数据,在中断内将接收到的数据通过队列的方式发送出去,在任务内部等待接收队列,串口中断配置及ISR如下:
  1. HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);//// 中断配置,优先级大小不能乱配置
  2. HAL_NVIC_EnableIRQ(USART1_IRQn);

  3. void USART1_IRQHandler(void)
  4. {
  5.         uint32_t                 flag=0;
  6.         BaseType_t        pHigherPriorityTaskWoken = pdFALSE;
  7.        
  8.         flag = __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE);
  9.         if((flag != RESET))
  10.         {
  11.                 __HAL_UART_CLEAR_IDLEFLAG(&huart1);
  12.                 huart1.Instance->SR;  
  13.                 huart1.Instance->DR;

  14.                 HAL_UART_DMAStop(&huart1);
  15.                 xQueueSendFromISR(UrtK125RcvQueue, DrvUsartRcvBuf, &pHigherPriorityTaskWoken);
  16.                 portYIELD_FROM_ISR(pHigherPriorityTaskWoken);
  17.         }
  18. }
复制代码


  //// 为什么代码提交后,代码对齐格式变了呢???

       调试发现进入中断后,程序卡在了函数xQueueSendFromISR(UrtK125RcvQueue, DrvUsartRcvBuf, &pHigherPriorityTaskWoken)内部configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )处,具体为:
  1. #if( configASSERT_DEFINED == 1 )

  2.         void vPortValidateInterruptPriority( void )
  3.         {
  4.         uint32_t ulCurrentInterrupt;
  5.         uint8_t ucCurrentPriority;

  6.                 /* Obtain the number of the currently executing interrupt. */
  7.                 __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
  8.                 //// ulCurrentInterrupt 调试显示为53

  9.                 /* Is the interrupt number a user defined interrupt? */
  10.                 if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
  11.                 {
  12.                         /* Look up the interrupt's priority. */
  13.                         ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
  14.                         //// 当串口优先级设置小于5时,ucCurrentPriority的值小于0x50,导致下面的宏断
  15.                         //// 言configASSERT条件值"==0",进而卡住
  16.                         //// 当串口优先级设置大于等于5时,ucCurrentPriority的值大于等于0x50,下面的
  17.                         //// 宏configASSERT条件值"==1",所以不会卡住

  18.                         /* The following assertion will fail if a service routine (ISR) for
  19.                         an interrupt that has been assigned a priority above
  20.                         configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
  21.                         function.  ISR safe FreeRTOS API functions must *only* be called
  22.                         from interrupts that have been assigned a priority at or below
  23.                         configMAX_SYSCALL_INTERRUPT_PRIORITY.
  24.                         //// 如果一个调用FreeRtos安全ISR API接口的中断ISR优先级分配大于
  25.                         //// configMAX_SYSCALL_INTERRUPT_PRIORITY(即中断优先级值小于
  26.                         //// configMAX_SYSCALL_INTERRUPT_PRIORITY,因为FreeRtos中值越小优先级越高),
  27.                         //// 下面的断言就会失败。FreeRtos安全ISR API接口必须只能在优先级分配大于
  28.                         //// configMAX_SYSCALL_INTERRUPT_PRIORITY的中断ISR中调用
  29.                         
  30.                         Numerically low interrupt priority numbers represent logically high
  31.                         interrupt priorities, therefore the priority of the interrupt must
  32.                         be set to a value equal to or numerically *higher* than
  33.                         configMAX_SYSCALL_INTERRUPT_PRIORITY.
  34.                         //// 数值小的中断优先级逻辑上具有高的中断有限权,因此设置时,中断的优先级
  35.                         //// 值必须必configMAX_SYSCALL_INTERRUPT_PRIORITY大

  36.                         Interrupts that        use the FreeRTOS API must not be left at their
  37.                         default priority of        zero as that is the highest possible priority,
  38.                         which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
  39.                         and        therefore also guaranteed to be invalid.
  40.                         //// 使用FreeRTOS API的中断的优先级禁止使用其0的认值,因为此时中断优先级最
  41.                         //// 高,0值的优先级必然大于configMAX_SYSCALL_INTERRUPT_PRIORITY,因此也必
  42.                         //// 然无效

  43.                         FreeRTOS maintains separate thread and ISR API functions to ensure
  44.                         interrupt entry is as fast and simple as possible.
  45.                         //// FreeRTOS为了确保中断入口尽可能的快和简单,因此分离了线程ISR API接口

  46.                         The following links provide detailed information:
  47.                         http://www.freertos.org/RTOS-Cortex-M3-M4.html
  48.                         http://www.freertos.org/FAQHelp.html */
  49.                         configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); //// 程序卡住位置
  50.                         //// ucMaxSysCallPriority值为0x50
  51.                 }

  52.                 /* Priority grouping:  The interrupt controller (NVIC) allows the bits
  53.                 that define each interrupt's priority to be split between bits that
  54.                 define the interrupt's pre-emption priority bits and bits that define
  55.                 the interrupt's sub-priority.  For simplicity all bits must be defined
  56.                 to be pre-emption priority bits.  The following assertion will fail if
  57.                 this is not the case (if some bits represent a sub-priority).

  58.                 If the application only uses CMSIS libraries for interrupt
  59.                 configuration then the correct setting can be achieved on all Cortex-M
  60.                 devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
  61.                 scheduler.  Note however that some vendor specific peripheral libraries
  62.                 assume a non-zero priority group setting, in which cases using a value
  63.                 of zero will result in unpredicable behaviour. */
  64.                 configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
  65.         }

  66. #endif /* configASSERT_DEFINED */
复制代码

       相关宏定义如下:
  1. #define portFIRST_USER_INTERRUPT_NUMBER                ( 16 )
复制代码

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

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

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

  15. /* Normal assert() semantics without relying on the provision of an assert.h
  16. header file. */
  17. /* USER CODE BEGIN 1 */   
  18. #define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
  19. /* USER CODE END 1 */
复制代码
  1. #define configPRIO_BITS         4
复制代码


简单总结如下:
       使用了FreeRtos操作系统后,外设中断优先级值不能设置小于configMAX_SYSCALL_INTERRUPT_PRIORITY,否则会导致了宏configASSERT的条件成立,进而卡住了。





收藏 2 评论1 发布时间:2019-4-16 14:15

举报

1个回答
Kevin_G 回答时间:2019-4-16 15:50:42
收藏

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版