搜索
查看: 4861|回复: 1

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

[复制链接]

该用户从未签到

40

主题

799

帖子

4

蝴蝶豆

金牌会员

最后登录
2021-3-26
发表于 2019-4-16 14:15:22 | 显示全部楼层 |阅读模式
本帖最后由 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的条件成立,进而卡住了。





回复

使用道具 举报

该用户从未签到

6

主题

1029

帖子

133

蝴蝶豆

金牌会员

最后登录
2021-4-24
发表于 2019-4-16 15:50:42 | 显示全部楼层
收藏
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-5 13:55 , Processed in 1.172170 second(s), 30 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表