从sys/power/state分析并实现S3C2416的睡眠和唤醒

发布时间:2023-05-19  
环境:
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 speakingn");
#ifdef CONFIG_SUSPEND
printk("<0>""[#2]kernel speakingn");
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 Electronicsn");

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 speakingn");
smdk_machine_init();
#endif
}
注意,结果出来了:[#4]kernel speaking信息没有说明CONFIG_S3C24XX_SMDK宏未定义。
而CONFIG_S3C24XX_SMDK宏是在配置内核是选定MINI2451后默认选定的,仅仅是被友善之臂凝视掉了,在当前文件夹下的Kconfig:


config MACH_MINI2451
	bool "MINI2451"
	#select S3C24XX_SMDK
	select S3C_DEV_FB
	select S3C_DEV_HSMMC
	select S3C_DEV_HSMMC1
	select S3C_DEV_NAND
	select S3C_DEV_USB_HOST
	select S3C2416_SETUP_SDHCI
	select WIRELESS_EXT
	select WEXT_SPY
	select WEXT_PRIV
	select AVERAGE
	help
	  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 0
	int ret = gpio_request_array(smdk_led_gpios,
				     ARRAY_SIZE(smdk_led_gpios));
	if (!WARN_ON(ret 

3、在arch/arm/mach-s3c24xx文件夹下加入文件common-smdk.h



/* arch/arm/mach-s3c24xx/common-smdk.h
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks 
*
* 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睡眠唤醒的底层驱动实现                                  
S3C2416睡眠的底层实现


六、总结                                                                                        
1、灵感非常重要。
PS:“天才就是百分之中的一个的灵感加百分之99的汗水”。这仅仅是前半句,后半句是:“但那百分之中的一个的灵感,往往比百分之九十九的汗水来得重要”。


为什么从小听到的仅仅有前半句、、、不吐槽了。



2、正确的方法就是捷径。只是,歧路也能让人增长姿势。



3、Linux内核,尤其原理方面的东东,还知之甚少。路漫长爱漫长、、、

4、附件:Linux下截屏命令: import pic_name


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>