一、前言
前段时间由于项目需求需要实现电源管理锁(PM_LOCK),由于之前没有接触过,网上的资料也比较少,只能找到esp32相关的实现案例,于是下载了esp-idf准备了解它的实现原理,看看能不能仿照它来实现,大概对着源码分析了两三天,终于有了一些眉目。esp32的pm_lock是配合动态调频算法一起使用的,它通过3种电源管理锁来控制动态调频算法,当应用程序获取电源管理锁后,CPU或者APB频率会设置成最大值,此时动态调频算法将会受限。释放电源管理锁后,限制解除。并且esp32很多外设驱动程序可以感知动态调频,在调频期间调用电源管理锁,避免频率变化造成影响,防止执行重要任务(数据接收及处理等等)时系统进入低功耗模式从而影响了任务执行。
二、DVFS动态调频算法
了解了esp32的pm_lock和动态调频后,其实主要的困难是解决动态调频问题,我就想着这个应该如何在stm32上实现,是不是将esp32的动态调频算法移植过去就可以用了。然后我开始了解动态调频的实现原理和实现方法,在网上找到很多相关的资料以及论文,发现和我想象的并不一样。下面是参考的一些论文资料。
DVFS 技术就是动态地调整芯片的工作电压和工作频率,根据芯片的性能要求,通过调整工作电压来实现动态功耗的降低。
一个典型的 DVFS 系统的工作流程如下:
1)采集与系统负载有关的信号,计算当前的系统负载。这个过程可以用软件实现,也可以用硬件实现。软件实现一般是在操作系统的核心调用中安放钩子,特别是调度器,根据其调用的频度来判断系统的负载。硬件实现通过采集一些核心信号中断线、Cache、内存总线的使用情况等,计算当前的系统负载。
2)根据系统的当前负载,预测系统在下一时间段需要的性能。有多种预测算法可以选择,要根据具 体的应用来决定。这种预测,既可由软件实现,也可由硬件实现。
3)将预测的性能转换成需要的频率,从而调整芯片的时钟设置。
4)根据新的频率计算相应的电压。通知电源管理模块调整相应模块的工作电压。这需要特别的电源管理芯片,以支持微小的电压调整,并且能在极短的时间内(几十 μs)完成电压的调整。
上面这两段话引用的是《中国集成电路》期刊上面的文章,那么从DVFS的工作流程可以看出前面3个步骤既可以用软件完成,也可以用硬件完成,但是第4步中提到了特别的电源管理芯片就只能是硬件来实现了,我又去找了一下这个芯片的具体说明以及有哪些MCU是包含这个芯片的。
PMIC(Power Management IC)为电源管理芯片,负责提供CPU所需要的电压。该芯片提供两种接口给CPU:常规的SPI(Serial Programmable Interface)和专用于动态电压调节的DVS接口。
这是市面上部分具有PMIC支持DVFS的mcu:
- ESP32系列:支持灵活的频率调整,适用于低功耗应用。
- STM32系列:一些高性能型号(如STM32F7、STM32H7)提供DVFS功能。
- NXP LPC系列:如LPC546xx,具有DVFS支持。
- TI MSP430系列:某些型号支持DVFS以优化功耗。
三、stm32f407实现调频的难点分析
知道stm32f407无法实现动态调频以后,我就把精力放在手动调频上了,但是这又是一个难点,对于stm32f407,调整频率操作比较复杂,一般stm32用的是PLL时钟作为时钟源,如果要更改频率,那么首先要切换时钟源为HSE或者HSI,然后再更改CPU频率,最后再把时钟源切回PLL时钟。这样一顿操作后,时钟会被耽搁,通信也会出问题。目前还没有想到办法来解决这些问题。
四、PM_LOCK简易实现
我把以上难点在组会上和我导师进行沟通,他告诉我其实普通低性能单片机不需要调频,对于这个项目需求只需要理解电源管理锁的目的,实现电源管理锁就可以了。其实管理锁的目的就是防止执行重要任务时系统进入低功耗模式从而影响了任务执行,于是我有了这个想法:用计数型信号量来实现简易的电源管理锁,向外部提供获得锁和释放锁的接口,当需要执行数据交互或者处理这类重要任务时,持有锁,执行完释放锁,当系统准备进入低功耗模式时会先判断这个电源管理锁是否为0。以下是实现过程。