從sys/power/state分析並實現S3C2416的睡眠和喚醒,states3c2416

來源:互聯網
上載者:User

從sys/power/state分析並實現S3C2416的睡眠和喚醒,states3c2416

環境:PC: debian-7.6.0  ARM CPU: S3C2416  Linux-Kernel: 3.6.0(FriendlyARM)U-boot: 1.3.4

一、問題來源                                                                                                

根據需要,在S3C2416上添加中斷睡眠和喚醒功能,於是我就查查Linux支援S3C2416的睡眠模式:
cat /sys/power/state
執行完,萬萬沒想到:竟然是空的,該命令沒有任何輸出!也就是說,我的核心目前不支援任何方式的睡眠。
不可能啊!之前我用S3C2440的CPU(核心版本Linux_2_6_31)實現了中斷的睡眠和喚醒,而S3C2416的Linux 3.6核心配置就是參照著Linux 2.6.31進行的配置。
Linux 2.6.31執行:

S3C2440-Linux 2.6.31:cat /sys/power/state返回:mem

經過各種顛倒黑白顛三倒四的嘗試都失敗後,靈機一閃:既然是cat後沒反應,那就沿著cat /sys/power/state調用的函數從上到下,一步一步查。
指導思想有了,那就順蔓摸瓜的進行調試。

、調試流程                                                                         
顯示cat /sys/power/state執行結果的函數是state_show():
kernel/power/main.c

static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
char *s = buf;
printk("<0>""[#1]kernel speaking\n");
#ifdef CONFIG_SUSPEND
printk("<0>""[#2]kernel speaking\n");
int i;

for (i = 0; i < PM_SUSPEND_MAX; i++) {
if (pm_states[i] && valid_state(i))
s += sprintf(s,"%s ", pm_states[i]);
}
#endif
......
}

編譯、燒寫核心,執行cat命令,有[#2]kernel speaking資訊說明CONFIG_SUSPEND宏是有定義的。
pm_states[]數組在同檔案也有定義,那麼接下來就看函數valid_state():
kernel/power/suspend.c
bool valid_state(suspend_state_t state)
{
printk("<0>""[#3]kernel speaking[suspend_ops-%d]\n", suspend_ops);
return suspend_ops && suspend_ops->valid && suspend_ops->valid(state);
}


這個函數測試後顯示suspend_ops指標為0。哈哈,原因找到了,接著順藤摸瓜。
suspend_ops指向struct platform_suspend_ops結構體,每個成員的作用參見附錄博文。suspend_ops的賦值在在函數suspend_set_ops():
kernel/power/suspend.c
void suspend_set_ops(const struct platform_suspend_ops *ops)
{
lock_system_sleep();
suspend_ops = ops;
unlock_system_sleep();
}

suspend_set_ops()的調用在函數s3c_pm_init():
arch/arm/plat-samsung/pm.c
int __init s3c_pm_init(void)
{
printk("S3C Power Management, Copyright 2004 Simtec Electronics\n");

suspend_set_ops(&s3c_pm_ops);
return 0;
}


s3c_pm_init()的調用在函數smdk_machine_init():
void __init smdk_machine_init(void)
{
......
s3c_pm_init();
}


而smdk_machine_init()是在具體的板上調用,我用的S3C2416是友善之臂的核心板,在mini2451_machine_init():
arch/arm/mach-s3c24xx/mach-mini2451.c
static void __init mini2451_machine_init(void)
{
#if defined(CONFIG_S3C24XX_SMDK)
printk("<0>""[#4]kernel speaking\n");
smdk_machine_init();
#endif
}
注意,結果出來了:[#4]kernel speaking資訊沒有說明CONFIG_S3C24XX_SMDK宏沒有定義。
而CONFIG_S3C24XX_SMDK宏是在配置核心是選定MINI2451後預設選定的,只是被友善之臂注釋掉了,在目前的目錄下的Kconfig

config MACH_MINI2451bool "MINI2451"#select S3C24XX_SMDKselect S3C_DEV_FBselect S3C_DEV_HSMMCselect S3C_DEV_HSMMC1select S3C_DEV_NANDselect S3C_DEV_USB_HOSTselect S3C2416_SETUP_SDHCIselect WIRELESS_EXTselect WEXT_SPYselect WEXT_PRIVselect AVERAGEhelp  Say Y here if you are using an FriendlyARM MINI2451
三、添加中斷方式的睡眠和喚醒功能                                                
1、修改arch/arm/mach-s3c24xx/Kconfig,去掉S3C24XX_SMDK選項前的注釋
2、修改arch/arm/mach-s3c24xx/common-smdk.c,去掉s3c_pm_init之外的東東,並添加喚醒中斷喚醒源
以下修改參見核心Documentation/arm/Samsung-S3C24XX/Suspend.txt

static irqreturn_t button_irq(int irq, void *pw){return IRQ_HANDLED;}void __init smdk_machine_init(void){/* Configure the LEDs (even if we have no LED support)*/#if 0int ret = gpio_request_array(smdk_led_gpios,     ARRAY_SIZE(smdk_led_gpios));if (!WARN_ON(ret < 0))gpio_free_array(smdk_led_gpios, ARRAY_SIZE(smdk_led_gpios));if (machine_is_smdk2443())smdk_nand_info.twrph0 = 50;s3c_nand_set_platdata(&smdk_nand_info);platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));#endifrequest_irq(IRQ_EINT0, button_irq, IRQF_TRIGGER_FALLING, "IRQ_EINT0", NULL);enable_irq_wake(IRQ_EINT0);s3c_pm_init();}
3、在arch/arm/mach-s3c24xx目錄下添加檔案common-smdk.h

/* arch/arm/mach-s3c24xx/common-smdk.h** Copyright (c) 2006 Simtec Electronics* Ben Dooks <ben@simtec.co.uk>** Common code for SMDK2410 and SMDK2440 boards** http://www.fluff.org/ben/smdk2440/** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.*/extern void smdk_machine_init(void);

4、修改arch/arm/mach-s3c24xx/mach-mini2451.c,添加smdk_machine_init所在的標頭檔,即common-smdk.h
#include "common-smdk.h"

四、S3C2416睡眠喚醒測試                                                        
睡眠:
cat /sys/power/state
返回:mem
echo mem > /sys/power/state


睡好後,觸發IRQ_EINT0中斷(按鍵),CPU恢複之前的狀態。部分:


為了更好的測試,可以再睡眠前運行一個輸出遞增資料的程式,這樣可以直觀的看到喚醒後的狀態。


五、S3C2416睡眠喚醒的底層驅動實現                                  
待續...


六、總結                                                                                        
1、靈感很重要。
PS:“天才就是百分之一的靈感加百分之99的汗水”,這隻是前半句,後半句是:“但那百分之一的靈感,往往比百分之九十九的汗水來得重要”。
為什麼從小聽到的只有前半句、、、不吐槽了。

2、正確的方法就是捷徑。不過,歧路也能讓人增長姿勢。

3、Linux核心,尤其原理方面的東東,還知之甚少,路漫長愛漫長、、、

4、附件:Linux下截屏命令: import pic_name
標準linu休眠和喚醒機制分析(一)

標準linu休眠和喚醒機制分析(二)

標準linu休眠和喚醒機制分析(三)
標準linu休眠和喚醒機制分析(四)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.