新闻中心

EEPW首页 > 测试测量 > 设计应用 > 基于SEP0611的电源管理驱动设计

基于SEP0611的电源管理驱动设计

作者: 时间:2012-03-28 来源:网络 收藏

首先调用device_prepare,该设备准备函数通常无操作;然后调用device_suspend函数,使设备驱动进入休眠模式。在该函数中,系统会遍历dpm_active链表,为该链表上的每个驱动调用suspend函数(该函数负责挂起设备驱动),正常返回后会将其移至dpm_off链表队列。至此,已完成休眠准备部分的工作。下面以音频驱动为例展示设备驱动suspend函数的填写(函数头略):
c.jpg
这段代码主要实现:保存音频设备硬件寄存器;禁止音频设备时钟。
3.2 休眠进入和休眠退出
完成了进入休眠的准备工作,接下来就是进入休眠。suspend_enter是休眠进入函数,该函数将调用suspend_ops->enter(state),调用该函数即是调用驱动接口函数sep_pm_enter;该接口函数在sep_pm.c中实现。该文件将保存在CPU寄存器,将休眠代码搬运到sram中,然后系统在sram中执行休眠代码,先让DDR进入自刷新状态,而后处理器进入sleep模式。当系统处于休眠模式时,一旦接收到唤醒事件的中断,如内部的RTC ALARM中断或者外部的Wakeup按键信号才能够让系统退出休眠,即唤醒系统。综上,进入/退出休眠的代码流程图如图2所示。

本文引用地址:https://www.eepw.com.cn/article/194210.htm

b.jpg


在图2中的休眠进入部分,保存CPU各模式状态之后,跳转到sram执行DDR2的自刷新和休眠的进入,而这段代码(DDR2的自刷新和休眠的进入)此前已由copy functo sram函数搬运至sram中;而跳转通过将sram的物理地址静态映射到linux内核(在对应架构的mm.c中)实现。此后,系统处于休眠(sleep)模式,直至唤醒信号的到来。中可用的唤醒信号有:电源键、RTC的ALARM中断、外部GPIO(AO)口。一旦唤醒信号到来,即是该执行休眠退出部分了。PMU硬件部分将让系统重新上电,而软件则回到bootloader部分执行,在bootloader中有一段分支代码,该部分代码判断是一次正常启动还是一次从休眠的唤醒,若是后者,则恢复CPU各模式状态,此后回到linux操作系统。需要说明的是,在进入休眠部分的保存CPU各模式状态之前,PC值(用于返回的地址,实际保存的是PC值加上0x10(合4条指令))已经被保存到一个硬件寄存器中;因此,在退出休眠部分的恢复CPU各模式状态之后,将PC值从硬件寄存器取出,通过其使程序回到linux操作系统执行。
3.3 完成唤醒
上面讲到了程序回到linux系统执行后,休眠内核层将通过suspend_devices_and_enter函数中位于调用suspend_enter之后的部分和sus pend_finish函数完成与休眠准备相逆的操作。
首先在suspend_devices_and_enter函数中执行以下完成唤醒的工作:
(1)调用dpm_suspend_end函数,该函数分为两步。
首先调用设备唤醒函数device_resume,该函数会遍历dpm_off链表队列,依次调用该队列上设备驱动的resume函数,让驱动恢复正常工作模式,并将其从dpm_off队列恢复至dpm_active队列。然后调用device_complete函数,该函数通常无操作。下面仍以音频驱动为例展示设备驱动resume函数的填写(函数头略):
d.jpg
这段代码主要实现:
(1)使能音频设备时钟;初始化音频相关的GPIO口;恢复音频设备硬件寄存器。
(2)调用resume_console函数释放控制台信号量以唤醒控制台。
(3)调用suspend_ops->end。
其次suspend_finish函数完成与suspend_prepare函数相逆的操作:
(1)唤醒进程,通过thaw_processses函数实现。
(2) 执行pm_notitier_call_chain函数,该函数调用notifier_call_chain函数来通知事件(完成唤醒)的到达。
(3)从全局变量恢复控制台。
至此,系统完成唤醒,且系统中所有的设备驱动能正常工作。



评论


相关推荐

技术专区

关闭