打印
[国产单片机]

FAQ0111--代码异常跳过__WFI()命令问题说明

[复制链接]
1401|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hoop|  楼主 | 2021-6-19 16:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hoop 于 2022-3-19 13:35 编辑

Questions应用有时会遇到无法正常进入低功耗的问题?
具体表现为执行__WFI()命令进入低功耗时,在无唤醒条件的情况下,系统却直接跳过该命令,代码继续向下执行的现象。
Answer
本文将采用低功耗的Standby模式为例进行分析及说明。
【问题根本原因】:
进入低功耗调用的__WFI()命令实质为“等待中断”,若在执行__WFI()命令时,NVIC中断内已有处于挂起且未被响应的中断的话,代码就会跳过__WFI命令继续向下执行。
此为ARM内核的特性,所有以ARM内核为基础设计的芯片均会存在此现象。
【问题解法】:
在执行__WFI()前,清除NVIC中断内所有处于挂起状态的NVICpending位。
Analysis
本文将采用低功耗的Standby模式加上USART1的接收中断为例进行说明分析。
【问题代码段示例】(其中不参与本文说明的代码未贴出):
  
crm_periph_clock_enable(CRM_PWC_PERIPH_CLOCK, TRUE); ///<①开启PWR时钟
  
nvic_irq_enable(USART1_IRQn, 0, 0);          ///<②使能USART1对应的NVIC中断
  
usart_interrupt_enable(USART1, USART_RDBF_INT, TRUE); ///<③使能USART1接收中断
  
__disable_irq();    ///<④禁止所有NVIC中断响应
  
while(usart_flag_get(USART1, USART_RDBF_FLAG) == RESET); ///<⑤等待RDBF标志置位
  
pwc_standby_mode_enter(); ///<⑥进Standby的命令
  
while(1);
  
【问题逻辑分析】:
在实际运行时,当收到数据后
1) USART1的RDBF标志被置位;
2) 因③的设定,USART1对应的NVIC pending位会跟随RDBF置位;
3) 因②的设定,置位的NVICpending位会跳转到对应的中断函数执行;
4) 但又因④的设定,代码实际不会跳转到中断函数执行,且NVIC pending位将被一直保持置位状态;
5) 故在⑥执行的时,因存在NVIC pending位处于置位状态,系统会直接跳过⑥内的__WFI();命令而继续向后执行,最终PC会停留到代码最后的while(1)语句。
【问题解法示例】:
为了能正常进入Standby,应用需要在执行__WFI()前清除处于置位状态的NVICpending位,即在前示例代码的⑤⑥之间添加如下代码:
  
usart_flag_clear(USART1, USART_RDBF_FLAG); ///<清除USART1的RDBF标志
  
NVIC_ClearPendingIRQ(USART1_IRQn); ///<清除USART1对应的NVIC pending标志
  
【注意事项】:
A.   本文只针对调用__WFI()进入的低功耗,__WFE()不存在类似问题;
B.   若不使能外设对应的NVIC中断,此时NVIC pending位同样会被置位,不过该置位的NVIC pending位不会对应用产生任何影响;
C.   问题解法中,在清除NVIC pending标志前,一定要先清除对应外设的中断标志,如前述示例中,USART1对应的NVIC pending位会跟随RDBF置位,若不先清除RDBF的话,将无法清除其对应的NVIC pending位;
D.   在非低功耗应用中,同样需要注意本文所述问题,因为置位的NVIC pending位会带来后续中断函数额外多执行一次的现象;
E.   一般带有指令跳转的IAP或其他相关应用会很容易撞到本文所述问题。建议初始设计时要严格注意使用到的外设对应的NVIC pending位的状态。
类型:MCU应用
适用型号:AT32全系列
主功能:NVIC pending位清除,执行__WFI()进低功耗异常
次功能:

FAQ0111_代码异常跳过__WFI()命令问题说明_V2.0.0.pdf

434.19 KB

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

322

帖子

0

粉丝