如何在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不需要这个属性,但无论如何我都尝试了(并得到了相同的结果)。
我究竟做错了什么?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
胡扯123
1楼-- · 2019-07-14 23:36
我没有看到你所展示的任何错误。什么在CleanUpOverflow(); ......那里有什么可以禁用中断吗?
blueshine
2楼-- · 2019-07-15 02:09
谢谢你 - 我会在办公室时查看。两个ISR处理程序都调用一个函数(ISRHigh()和ISRLow()),每个函数都需要很长时间才能完成。我已经更新了这个问题。
胡扯123
3楼-- · 2019-07-15 03:45
是否有任何禁用/启用ISRLow()或CleanUpOverflow()中断的内容可能会延迟执行更高优先级的中断。
胡扯123
4楼-- · 2019-07-15 07:40
CC1101_INT_EXTI_LINE与IRQLOW_EXTI_LINE相同吗?
76r456546
5楼-- · 2019-07-15 12:50
 精彩回答 2  元偷偷看……
胡扯123
6楼-- · 2019-07-15 17:40
很好的发现,它在STL32F4的SPL中是相同的(我刚检查了v1.8.0的源代码)。我需要查看一些代码

一周热门 更多>