这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » FAQ0111--代码异常跳过WFI()命令问题说明

共3条 1/1 1 跳转至

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

菜鸟
2021-06-19 16:59:38     打赏

Questions应用有时会遇到无法正常进入低功耗的问题

具体表现为执行__WFI()命令进入低功耗时,在无唤醒条件的情况下,系统却直接跳过该命令,代码继续向下执行的现象。

 

Answer

本文将采用低功耗的Standby模式为例进行分析及说明。

【问题根本原因】:

进入低功耗调用的__WFI()命令实质为等待中断,若在执行__WFI()命令时,NVIC中断内已有处于挂起且未被响应的中断的话,代码就会跳过__WFI命令继续向下执行。

此为ARM内核的特性,所有以ARM内核为基础设计的芯片均会存在此现象。

【问题解法】:

在执行__WFI()前,清除NVIC中断内所有处于挂起状态的NVIC pending位。

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) USART1RDBF标志被置位;

2) 因③的设定, USART1对应的NVIC pending位会跟随RDBF置位;

3) 因②的设定,置位的NVIC pending位会跳转到对应的中断函数执行;

4) 但又因④的设定,代码实际不会跳转到中断函数执行,且NVIC pending位将被一直保持置位状态;

5) 故在执行的时,因存在NVIC pending位处于置位状态,系统会直接跳过⑥内的__WFI();命令而继续向后执行,最终PC会停留到代码最后的while(1)语句。

【问题解法示例】:

为了能正常进入Standby,应用需要在执行__WFI()前清除处于置位状态的NVIC pending位,即在前示例代码的⑤⑥之间添加如下代码:

usart_flag_clear(USART1, USART_RDBF_FLAG); ///<清除USART1RDBF标志

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()进低功耗异常

次功能:




工程师
2021-06-19 19:16:51     打赏
2楼

感谢楼主分享


工程师
2021-06-19 19:21:34     打赏
3楼

学习一下


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]