如何在STM32F105上中断具有更高优先级ISR的ISR?

2019-07-14 17:20发布

我有两个外部中断源进入STM32F105。我想要其中一个(称之为“IRQHigh”)来抢占另一个(“IRQLow”)。目前,如果在IRQLow ISR期间触发IRQHigh,程序流将等待,直到我清除IRQLow ITPending位,然后才分支到IRQHigh ISR。STM32F105是基于Cortex-M3的微控制器。它支持嵌套中断。我的应用程序是用C语言编写的,使用Eclipse中的GCC(ARM-none-eabi-gcc)和STM32F1标准外设库。我认为我已正确配置优先级但我必须遗漏一些东西。
这是相应的初始化代码。我已经删除了AFB时钟命令,GPIO配置等,因为每个子系统似乎都能正常工作:
  1. <font size="4">#define IRQHIGH_EXti_PORT  GPIO_PortSourceGPIOA
  2. #define IRQHIGH_EXTI_PIN   GPIO_PinSource3
  3. #define IRQHIGH_EXTI_LINE  EXTI_Line3
  4. #define IRQHIGH_EXTI_IRQn  EXTI3_IRQn

  5. #define IRQLOW_EXTI_PORT   GPIO_PortSourceGPIOC
  6. #define IRQLOW_EXTI_PIN    GPIO_PinSource11
  7. #define IRQLOW_EXTI_LINE   EXTI_Line11
  8. #define IRQLOW_EXTI_IRQn   EXTI15_10_IRQn

  9. NVIC_InitTypeDef NVIC_InitStructure;
  10. EXTI_InitTypeDef EXTI_InitStructure;

  11. // Sixteen levels of pre-emption priority, no subpriorities
  12. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

  13. // IRQHigh

  14.     // Connect EXTI Line to GPIO Pin
  15.     GPIO_EXTILineConfig(IRQHIGH_EXTI_PORT, IRQHIGH_EXTI_PIN);

  16.     // Configure EXTI line
  17.     EXTI_InitStructure.EXTI_Line = IRQHIGH_EXTI_LINE;
  18.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  19.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  20.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  21.     EXTI_Init(&EXTI_InitStructure);

  22.     // Configure and enable EXTI Interrupt
  23.     NVIC_InitStructure.NVIC_IRQChannel = IRQHIGH_EXTI_IRQn;
  24.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  25.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  26.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  27.     NVIC_Init(&NVIC_InitStructure);

  28. // IRQLow

  29.     // Connect EXTI Line to GPIO Pin
  30.     GPIO_EXTILineConfig(IRQLOW_EXTI_PORT, IRQLOW_EXTI_PIN);

  31.     // Configure EXTI line
  32.     EXTI_InitStructure.EXTI_Line = IRQLOW_EXTI_LINE;
  33.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  34.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  35.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  36.     EXTI_Init(&EXTI_InitStructure);

  37.     // Configure, but do not enable, EXTI Interrupt
  38.     NVIC_InitStructure.NVIC_IRQChannel = IRQLOW_EXTI_IRQn;
  39.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
  40.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  41.     NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
  42.     NVIC_Init(&NVIC_InitStructure);</font>
复制代码IRQ处理程序设置如下:
  1. <font size="4">void EXTI3_IRQHandler(void)
  2. {
  3.     IRQHigh();
  4.     EXTI_ClearITPendingBit(IRQHIGH_EXTI_LINE);
  5. }

  6. void EXTI15_10_IRQHandler(void)
  7. {
  8.     if (EXTI_GetITStatus(IRQLOW_EXTI_LINE) == SET)
  9.     {
  10.         if (IRQLow()) // This returns a non-zero value if an overflow happened
  11.         {
  12.             CleanUpOverflow();
  13.         }

  14.         // Clear interrupt bit.
  15.         EXTI_ClearITPendingBit(IRQLOW_EXTI_LINE);
  16.     }
  17.     else // unknown EXTI source
  18.     {
  19.         ErrorHandler(ERR_UNKNOWN_EXTI15_10_IRQ); // This never happens
  20.     }
  21. }</font>
复制代码
一些注意事项:
  • IRQHigh()和IRQLow()每个都需要很长时间才能完成(这就是为什么我想让一个人打断另一个)
  • IRQLow最初未启用,但已启用 NVIC_EnableIRQ(IRQLOW_EXTI_IRQn);
  • 在EXTI15_10_IRQHandler()中,我从IRQLow()获得一个返回值。
  • 我已经声明了xxx_IRQHandler()函数__attribute__ ((interrupt ("IRQ")))。我知道Cortex-M3不需要这个属性,但无论如何我都尝试了(并得到了相同的结果)。
我究竟做错了什么?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。