RT-Thread / rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS).
https://www.rt-thread.io
Apache License 2.0
10.61k stars 5.04k forks source link

STM32L4系列PM组件遇到BUG #3184

Closed bevis-wong closed 4 years ago

bevis-wong commented 5 years ago

调PM组件已经有一段时间了,发现一些问题。已经实在不知道如何修改了,还望能给个提示。谢谢 硬件平台:STM32L476

  1. drv_pm.c驱动运行模式在低频切换到高频等级时,有很大概率死机(shell无法输入输出) 触发方式80 -> 24 -> 2Mhz, 然后从低到高切,3轮内shell必卡死。 翻看ST官方低功耗例程也没看出什么问题已排除因为低等级功耗模式占用导致高等级模式无法申请的情况还有个问题,因为我用SIM7600模块,模块在收到网络下行可以给MCU输出信号唤醒,MCU唤醒是成功了,但是丢失第一包串口数据,必须要点第二次下行请求才可以收到。

  2. drv_pm.c驱动休眠模式切换中PM_SLEEP_MODE_STANDBY运行不正常。 PM_SLEEP_MODE_DEEP带RTC休眠 这个功能正常,外部中断可唤醒(运行后明显降低15ma) 但是PM_SLEEP_MODE_STANDBY,功耗不降反增10ma, 而且外部中断无法唤醒。

  3. PM_SLEEP_MODE_DEEP即使STOP2模式在被外部中断唤醒后,无法立即对即将到来的串口数据做接收处理,开启AT的数据流日志和手动添加日志可以看到,在被外部中断唤醒后,第一包到来的数据串口的时钟感觉变得好慢,每次只能接收0-几十个字节,当第二包数据到来时却又恢复正常了(因为是人手触发的下行串口数据起码间隔了1-2秒),实际上是不可能要加延时的。因为我司上一代产品也是这个电源管理策略F103的完全没有问题。

    PM组件又研究了2天,折腾了好多种时钟配置组合方式。结果发现把SystemClock_ReConfig里面的SystemClock_MSI_ON屏蔽掉后,4G模块的空中唤醒L476就不会影响到AT串口的数据接收了。但是测试了几组后发现又不行了(我系统休眠策略是是前40秒休眠4G模块,再过40秒进入STOP2模式),第1第2组还行,从第三组开始,AT串口又收不到数据了(已排除AT组件问题)。

因为我司上一代产品用的是UCOSF103做的,也是使用停止模式休眠,唤醒后直接重新设置系统时钟就好了,4G模块空中唤醒从未影响过串口数据。参考L4的PWR电源管理例程,里面使用的MSI作为主时钟,drv_pm的驱动看起来也没什么问题,board.c里面SystemClock_Config与cubeMX开启的外设时钟有关,因为先前的经验,停止模式后要恢复时钟,我尝试把SystemClock_80M改成与SystemClock_Config一样(毕竟默认都是80Mhz),或者使用原版的SystemClock_80M(里面只单一的恢复HSI时钟,其他外设时钟并没有开启),以上都失败了。

pm组件的细节总结:

  1. SystemClock_ReConfig 里面的 SystemClock_MSI_ON感觉至关重要,奇怪的是,这个时钟只有开,却没有关。若我把它屏蔽,我起码可以成功唤醒并接受AT串口数据2-3次,如果不屏蔽,空中唤醒那就一次都收不到了,不过主动式唤醒却不受影响(使用API释放当前等级,并且申请新的功耗模式)完成一些列动作后再发送上行数据OK。

  2. 如果我把 SystemClock_ReConfig 里面的 SystemClock_MSI_ON屏蔽掉,就算我从停止模式唤醒后,把所有系统时钟和外设时钟再开一次,我的系统定时器定时都会乱掉,例如8分钟变成2分钟。如果不屏蔽,空中唤醒就会丢失AT串口,但是不影响定时我本地主动唤醒发送上行数据。

  3. 系统初始化的SystemClock_Config 和运行模式切换需要做电压配置,休眠停止模式外部中断唤醒后的重设系统时钟不需要做电压配置(不知道对否) 详细 https://www.rt-thread.org/qa/thread-422515-1-1.html

shao7936626 commented 5 years ago

遇到了基本相同的问题

shao7936626 commented 5 years ago

@bevis-wong 我debug的时候,加了两行打印就解决了,不知道为何,问题出现在hal文件中,stm32l4xx_hal_rcc.c中HAL_RCC_OscConfig函数中462行左右,有个__HAL_RCC_MSI_RANGE_CONFIG宏的前后,加点打印或者是延时就可以了,我也不知道为什么

bevis-wong commented 5 years ago

@bevis-wong 我debug的时候,加了两行打印就解决了,不知道为何,问题出现在hal文件中,stm32l4xx_hal_rcc.c中HAL_RCC_OscConfig函数中462行左右,有个__HAL_RCC_MSI_RANGE_CONFIG宏的前后,加点打印或者是延时就可以了,我也不知道为什么

这个我在AT组件里串口接收数据源头尝试过了,加一些日志后也有延时的效果,这个只能暂时性的,实际应用稳定性不可知

armink commented 5 years ago

感谢反馈哈,后面我们很快会集中处理下 PM 相关的问题

shao7936626 commented 5 years ago

感谢反馈哈,后面我们很快会集中处理下 PM 相关的问题

Thank you very much

bevis-wong commented 4 years ago

感谢 zhangsz0516 大神提供的完整解决方案!