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

关于HAL库外部中断进两次中断服务的问题

[复制链接]
数码小叶 提问时间:2020-6-18 11:01 /
最近一个应用里用到了STM32F4的两个外部中断,但是最终结果一直不对,发现仿真是正确的,单独运行就不正确,多次调试后发现问题出现在中断上,中断服务函数进了两次,但是这个应用只允许进一次中断
在网上搜索到问题的原因

Q: When I cleared the interrupt as the last instruction in the ISR,
the ISR code is called immediately upon exit half the time. Is there a
possibility of race condition ?

Answer:
The core (Cortex-M3) generates bufferable write transfer. This mean
that the CPU consider that the data is written from an AHB point of
view while the APB write transfer is managed by the AHB2APB bridge and
could be written later. In this case the CPU left the interrupt
routine while the interrupt is not yet cleared the CPU will re-enter  
again on the interrupt handler. To avoid this race condition :

1) ISR routine has to clear the interrupt  peripheral flag when just
entering in the routine to avoid interrupt missing.

2)ISR routine has to Implement a write to the APB  peripheral register
( to clear the peripheral flag) then followed by a read  access to the
same register/flag. This operation will force the write buffer to
complete the effective write and will stall the CPU until the
effective write of the bit in the register. Therefore  it is
independent from the AHB/APB ratio prescaler.
Here an example :

STR R1, [R0, #0] ; Store R1 register  peripheral   register  ( or
using bit-banding peripheral address)

LDR R2, [R0, #0] ; Load the peipheral register; This will  hold the
CPU until the effective write of R1.

Use Cortex-M3 Bit-banding feature for interrupt clearing since it is
an atomic operation and NVIC pending interrupts will be ignored during
this operation, however Read-Modify-Write is not.


知道了问题出现的原因是AHB2APB桥延迟,其中看到几条建议:
1)进入中断后,判断了相应标志位,就clear之,在作后续的处理
3、解决方法:清中断标志,只要不是中断函数的最后一条语句就没问题了。
当前这个情况下把程序下载到板子上运行的时候,按下按键,LED的状态会翻转两次,后来尝试改了一下软件生成的代码,将清中断标志位那条语句放到调用中断回调函数之后就可以了



程序原本的代码:


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
        if(GPIO_Pin == GPIO_PIN_8)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;

        }
        else if(GPIO_Pin == GPIO_PIN_9)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;
        }
}


原本的清标志是自动生成的


void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
       HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}



按照建议,改成如下依旧无效果


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
       __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
        if(GPIO_Pin == GPIO_PIN_8)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;

        }
        else if(GPIO_Pin == GPIO_PIN_9)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;
        }
}

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
      if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
      {
               __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
              HAL_GPIO_EXTI_Callback(GPIO_Pin);
             __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
     }
}

收藏 评论2 发布时间:2020-6-18 11:01

举报

2个回答
lebment 回答时间:2020-6-18 11:38:26
这时候示波器应该掏出来看看了。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

数码小叶 回答时间:2020-6-19 09:03:50
lebment 发表于 2020-6-18 11:38
这时候示波器应该掏出来看看了。

示波器干嘛。。。??

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版