首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

s3c2440 省电模式开发详解

s3c2440 省电模式开发详解

=======================开发资源及配置

1、源码包
Kernel   :linux-2.6.18.2
Uboot    :u-boot-1.1.4
Gcc      :arm-linux-gcc-3.4.1.tar.bz2

开发流程及详细步骤
1、休眠部分

1.       电源管理守护进程
省略

2.       内核接口文件(arch/arm/kernel/apm.c)
电源守护进程通过apm.c的ioctl函数来使内核开始进入sleep模式。
case APM_IOC_SUSPEND:
        as->suspend_result = -EINTR;
        if (as->suspend_state == SUSPEND_READ) {
               as->suspend_state = SUSPEND_ACKED;
               suspends_pending--;
        } else {
               queue_event(APM_USER_SUSPEND, as);
        }
        if (suspends_pending == 0)
               apm_suspend(); //由此进入sleep
       调用的顺序如下:

3.       进sleep前的准备工作
A.关闭系统进程(kernel/power/ console.c)
int pm_prepare_console(void) //该函数使所有系统进程休眠或关闭。
B.关闭外设驱动电源(drivers/base/power/suspend.c)
int device_power_down(pm_message_t state) //该函数使所有设备驱动sleep

4.       进入sleep前的设置(arch/arm/mach-s3c2410/pm.c)
static int s3c2410_pm_enter(suspend_state_t state) //该函数引导进sleep前的设置

static int s3c2410_pm_enter(suspend_state_t state)
{
unsigned long regs_save[16];
unsigned long tmp;

s3c2410_pm_debug_init(); //sleep中uart不能再用,此函数实现uart重新初始化用来调试

DBG("s3c2410_pm_enter(%d)\n", state); //打印信息

if (state != PM_SUSPEND_MEM) {
        printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
        return -EINVAL;
} //判断是否是休眠只用ram实现,应为该项目不支持硬盘休眠功能。

if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
    !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
        printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
        printk(KERN_ERR PFX "Aborting sleep\n");
        return -EINVAL;
} //判断中断唤醒是否允许,不允许则不能进入休眠。

s3c2410_pm_check_prepare(); //如果需要在sleep前检查ram则此函数会运行,否则此函数为空,即如果CONFIG_S3C2410_PM_CHECK被定义。

s3c2410_sleep_save_phys = virt_to_phys(regs_save);
//将用来保存系统寄存器的数组地址转为物理地址,以供后面调用。
DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); //打印信息
__raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
                             //将系统唤醒时需要调用的函数地址写入GSTATUS3寄存器。
DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); //打印信息
DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); //打印信息

s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));  //保存io口配置状态
s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));      //保存中断配置状态
s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));  //保存核心配置状态
s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));    //保存串口配置状态

s3c2410_pm_configure_extint(); //配置外部中断唤醒,使系统休眠中可以按键唤醒

DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
    s3c_irqwake_intmask, s3c_irqwake_eintmask); //打印信息

__raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);        //屏蔽系统定义中断
__raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK); //打开外部唤醒中断

__raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
//通过写已经被申请的位,将中断请求寄存器清空

arm920_flush_kern_cache_all(); //清缓冲区

s3c2410_pm_check_store();//如果需要在sleep前检查ram则此函数会运行,否则此函数为空,即如果CONFIG_S3C2410_PM_CHECK被定义。

__raw_writel(0x00, S3C2410_CLKCON);  //关闭所有外设时钟
继承事业,薪火相传
返回列表