伴随着嵌入式产品的普及,电源管理开发和设计成为了嵌入式系统开发的重点和重要部分。因为嵌入式设备对能耗越来越敏感,而电源管理技术正是这些产品设计的关键所在。目前嵌入式系统的电源管理技术正由传统的基于电源管理器件和外设控制为主的静态控制方式,转到以操作系统为核心的动静态结合的综合控制模式。
为了应对电源管理面临的挑战,在嵌入式系统开发时需要设计多种电源模式,以便在不同工作状态时有多种能耗模式可供选择。休眠和唤醒功能正是目前WINCW系统开发的研究热点之一。那么,休眠唤醒功能是什么原理呢?它能达到什么样的效果。这首先要从硬件说起,当系统进入休眠模式后,整个系统会进入低功耗休眠模式,只有当外部中断中任意一个中断被触发或者实时时钟中断被触发时,系统才会被唤醒。
一.什么是休眠唤醒功能?
(1)什么是WinCE休眠唤醒功能?
在WinCE系统中支持多种电源状态:①ON状态,用户在主动使用设备。②UserIdle状态,用户与设备停止交互,但仍有可能使用设备。③SystemIdle状态,在经过一段时间的UserIdle后进入此状态,但是驱动和系统仍然活动。④Suspend状态,当驱动程序和系统进程不再与系统交互时进入此状态。⑤ColdReboot和Reboot状态,冷启动后系统电源状态。其中,按功率消耗由小到大可分为睡眠(sleep)、空闲(idle)、运行(Run)等模式。大多时间内,在运行态(Run)时设备全部正常工作,而在睡眠与空闲模式时系统则是按照特定的模式进行相应的节能。
通常,嵌入式系统在大多数时间都不需要关注WinCE 设备的电源损耗,但是在某些时候要注意这些损耗。因此,最好的节能方法是使系统适时的进出休眠状态。例如,WinCE系统先检查任务负载情况,如果没有需要运行的任务,则一般进入空闲节能状态等待唤醒,在空闲一段时间后再进入深度睡眠,挂起到RAM中或者硬盘上。当WinCE 系统被挂起,为了省电系统需要关闭CPU处理器及大部分设备的供电,然后在需要唤醒时再通过定时器或中断模块唤醒。比如用户按下On/Off按钮时,或者监视用户活动的定时器超时,或者应用程序API都可以使得嵌入式系统休眠。而当用户再次按下On/Off或者有其它唤醒中断发生时,系统内核调用OEMPowerOff()函数,在系统唤醒后继续从OEMPowerOff()被挂起处执行。OEMPowerOff函数能进行CPU寄存器保存、设置及唤醒恢复等功能。系统Idle状态和前面说的UserIdle状态是不同概念,前者是CPU负荷驱动,代表系统空闲;后者是用户活动驱动,代表用户空闲。
(2)休眠唤醒功能的具体内容
一般来说,WINCE电源状态有六种状态,分别是S0到S5:S0实际上这就是我们平常的工作状态,所有设备全开;S1也称为POS(Power on Suspend),这时除了通过CPU时钟控制器将CPU关闭之外,其它的部件仍然正常工作;S2这时CPU处于停止运作状态,总线时钟也被关闭,但其余的设备仍然运转;S3这就是我们熟悉的STR(Suspend to RAM);S4也称为STD(Suspend to Disk),这时系统主电源关闭,但是硬盘仍然带电并可以被唤醒;S5这种状态是最干脆的,就是连电源在内的所有设备全部关闭,即关机(Shutdown)。
WINCE电源管理休眠和唤醒可实现以下功能:用户可以使外设在指定时间开关,或操作系统可以根据具体需求来分配电能源,或在无人使用时可以使系统进入休眠状态,但保证一些通信设备打开。也就是说,嵌入式系统能够管理闲置的设备,关闭设备并提供恢复手段,主要支持三种节电方式:①Suspend即挂起,显示屏自动关闭,只是主机通电。这时敲任意键即可恢复原来状态。②Suspend to Ram 即挂起到内存,系统把当前信息储存在内存中,只有内存等几个关键部件通电,这时系统处在高度节电状态,按任意键后系统从内存中读取信息很快恢复到原来状态。③Suspend to Disk即挂起到硬盘,即系统将自动关机,关机前将当前数据存储在硬盘上,用户下次按开关键开机时计算机将无须启动系统,直接从硬盘读取数据,恢复原来状态。
在嵌入式系统中,我们最常用到的是S3状态,即Suspend to RAM(挂起到内存)状态。顾名思义,STR就是把系统进入STR前的工作状态数据都存放到内存中去。在STR状态下,电源仍然继续为内存等最必要的设备供电,以确保数据不丢失,而其它设备均处于关闭状态,系统的耗电量极低。一旦我们按下Power按钮系统就被唤醒,马上从内存中读取数据并恢复到STR之前的工作状态。内存的读写速度极快,因此我们感到进入和离开STR状态所花费的时间不过是几秒钟而已。而S4状态即STD(挂起到硬盘)与STR的原理是完全一样的,只不过数据是保存在硬盘中。由于硬盘的读写速度比内存要慢得多,因此用起来也就没有STR那么快了,但STD模式是一种更省电的高级应用,是将当前系统状态保存到硬盘后,硬盘随即停止转动系统进入低功耗状态。当再开机时系统会跳过自检,直接从硬盘恢复原来的系统状态,而不是正常系统的默认状态,从而缩短了开机时间。
二.休眠功能的具体实现过程
WinCE休眠可以理解为待机,是把系统的功耗降到最低,但不是关机。让WinCE系统进入休眠的方法有很多,如在应用程序或驱动中调用SetSystemPowerState函数。一般来说,对于支持电源管理的驱动,系统会调用此驱动的XXX_PowerDown接口来关闭设备电源,之后系统会再调用OEMPowerOff()函数来实现。OEMPowerOff()函数由OEM来完成,这个函数也许会位于 Power.c或者Off.c的文件中。OEMPowerOff()是由OEM来实现的,其代码和流程也许不同,但基本按照下面的方法来完成:
(1)先进行休眠前平台相关的动作
这些相关的平台动作包括:为休眠模式设置合理的GPIO,合理配置实时时钟在内的唤醒源,调用BSPPowerOFF关闭休眠时不必要的设备电源。比如清屏、设置AD、挂起USB等。还包括保存芯片所有的寄存器值到一个静态数组(就是堆栈中),比如将休眠返回地址或一些不希望在休眠模式下丢失的数据进行保存。最后,是调用 CPULCDOff函数来关闭LCD背光。
(2)调用 ConfigStopGPIO,设置各IO休眠后的状态
这个动作是指保存当前GPIO和LCD控制器等信息在内存中,设置GPIO为低功耗状态,关闭kitl LCD等设备。同时,呼叫OALCPUPowerOff()进行挂起。OALCPUPowerOff()是一个位于Startup.s中的汇编函数。通常还包括保存通用寄存器的值到堆栈,如保存Wakeup后的地址、MMU寄存器,并进入各模式将sp和lr寄存器保存到内存RAM的某一个位置,这个位置是由config.bib指定保留的。至于为什么不象之前一样保存到堆栈呢?是因为系统唤醒后跳转到Reset开始执行,这时候堆栈还没有初始化,这也是Poweroff过程复杂的原因。
(3)屏蔽所有中断,清理Cache
在设置好各IO的休眠状态后,系统会在中断屏蔽寄存器中屏蔽所有中断,然后再清理Cache,做好休眠前的准备。
(4)设置唤醒中断,调用 CPUPowerOff
一般来说,唤醒中断可以是外部中断0,1,2,或者RTC中断。在设置好唤醒中断后,系统需要再调用OALCPUPowerOff,并设置REFRESH让SDRAM进入自刷新模式,然后等待SDRAM自刷新有效,并设置 MISCCR使 SDRAM 的信号 (SCLK0,SCLK1 and SCKE) 在 Power_OF 模式下被保护,设置CLKCON进入Power_OFF模式,最终CPU进入Poweroff状态。但因为关机最终也会调到OEMPOWEROFF函数,所以在此函数中到底去休眠还是关机就要自己根据实际情况区分一下了。而且在这个过程中,最容易出问题的部分是调用OALCPUPowerOff的过程中,这是由于CPU在休眠期间是会掉电的。
三.唤醒功能的具体实现流程
在休眠状态,WINCW系统中消耗的能源会大幅度降低。那么接下来,就是另一个艰巨的任务了:系统唤醒。唤醒系统基本上是个硬件过程,它和硬件紧密相关。一般是用一个外部中断来唤醒,这就要求休眠的时候这个中断源不能断电。一般来说,驱动程序里都已经做好了PowerUp和PowerDown,当然也有些驱动里有不同的处理,如使用PowerOn和PowerOff。但不论何种方式Reset,都是先执行Bootloader的代码,所以唤醒过程需要Bootloader的参与配合。详细的实现流程如下:
(1)通过唤醒源唤醒系统,产生内部复位信号
当我们细心观看WINCE系统由SLEEP到NORMAL的切换时,中间要经过一个 RESET的过程,这个过程称之为 Power On Reset。也就是说,当系统被外部中断唤醒时,相当于发生了一次Power Reset的过程。那么唤醒系统,就类似于给系统做了一个硬件复位,并会在GSTATUS2中保存一个数值来表明Reset的原因。而且,Power On Reset后,在之前Sleep过程中保存下来的RAM里的系统数据是不会丢失的。我们要做的唤醒系统,就是把这些数值恢复到它原来的地址里去。
(2)测试是否是Power_OFF模式唤醒
当WINCE系统唤醒之后,它运行的第一段程序是什么呢?这点很重要,因为唤醒=Power Reset,所以Reset CPU之后,运行第一段程序自然就是Bootloader了。现在我们再看看Bootloader是怎么处理的,如果是Reset复位就会直接跳转到0地址,也就是ResetHandler去执行。事实上,无论是HardReset还是PowerReset这个部分都要执行,主要是做初始化CPU时钟的工作。这是因为Power off模式和其它睡眠模式不同,其它的睡眠模式唤醒后会从睡眠处继续运行,而Power off模式唤醒后是从Reset处执行。
接下来,系统会通过读取 GSTATUS2 寄存器里的数值,来判断Reset的原因。如果这个值是0x2,那么就是唤醒引起的PowerReset,然后会继续向下执行唤醒的恢复操作。例如,先是恢复CPU的时钟,开启RAM的自刷新,再跳转到 RAM中的一个地址去执行Bootloader,然后把NandFlash里的数据装载完毕,也就是说WINCE的操作系统被唤醒了。如果判断GSTATUS2里的数值是0x4,则说明发生了看门狗Reset,那么就要执行看门狗Reset的恢复过程。如果二者都不是的话,那么就认为是发生了Hard Reset,就要按照正常的步骤去加载Wince系统。
(3)恢复SDRAM控制器信息,打开相关设备电源
系统唤醒的最后一个步骤,是系统会设置MISCCR,释放SDRAM信号保护,然后等待直到SDRAM自刷新释放。并读取GSTATUS值,利用它们回复到睡眠前的程序位置。最后是恢复保存在内存中的GPIO和LCD控制器等信息,并调用BSPPowerOn打开相关设备电源,然后返回。