当前位置:网站首页>kernel syscore
kernel syscore
2022-07-31 11:52:00 【szembed】
syscore作为低功耗流程的一部分,其涉及的文件主要有syscore_ops.h和syscore.c,这一级别的回调函数是在完全屏蔽中断的场景下进行的。
1、主要结构体struct syscore_ops,该结构体是syscore操作的对象类型。
-
struct
syscore_ops {
-
struct
list_head node;
//用于链表控制,注册和删除syscore对象时操作此链表完成
-
int (*suspend)(
void);
//睡眠流程时回调函数
-
void (*resume)(
void);
//唤醒流程时回调函数
-
void (*shutdown)(
void);
//这一级别的回调函数主要用于系统级的重启、停止或者掉电时才会使用
-
};
2、主要接口:
-
extern void register_syscore_ops(struct syscore_ops *ops);
//注册syscore回调函数
-
extern void unregister_syscore_ops(struct syscore_ops *ops);
//取消注册的回调函数
-
#ifdef CONFIG_PM_SLEEP
-
extern int syscore_suspend(void);
//回调注册的syscore对象的suspend回调函数
-
extern void syscore_resume(void);
//回调注册的syscore对象的resume回调函数
-
#endif
-
extern void syscore_shutdown(void);
//回调注册的syscore对象的shutdown回调函数
3、具体实现,syscore.c
1)全局变量
-
static LIST_HEAD(syscore_ops_list);
//初始化控制链表头结点,统一管理注册的syscore对象
-
static DEFINE_MUTEX(syscore_ops_lock);
//访问上述链表时,通过此互斥信号量来互斥访问
2)register_syscore_ops:其他组件主要通过此接口来注册回调函数,我们可以看到,把注册的对象存放在了syscore_ops_list链表中。
-
/**
-
* register_syscore_ops - Register a set of system core operations.
-
* @ops: System core operations to register.
-
*/
-
void register_syscore_ops(struct syscore_ops *ops)
-
{
-
mutex_lock(&syscore_ops_lock);
-
list_add_tail(&ops->node, &syscore_ops_list);
-
mutex_unlock(&syscore_ops_lock);
-
}
3)unregister_syscore_ops:与register_syscore_ops功能相反,取消注册,从控制链表中删除。
-
/**
-
* unregister_syscore_ops - Unregister a set of system core operations.
-
* @ops: System core operations to unregister.
-
*/
-
void unregister_syscore_ops(struct syscore_ops *ops)
-
{
-
mutex_lock(&syscore_ops_lock);
-
list_del(&ops->node);
-
mutex_unlock(&syscore_ops_lock);
-
}
4)syscore_suspend:该接口回调所有注册对象的suspend接口,该接口在suspend.c的suspend_enter函数中被调用,执行cpu掉电前的最后阶段操作。
-
/**
-
* syscore_suspend - Execute all the registered system core suspend callbacks.
-
*
-
* This function is executed with one CPU on-line and disabled interrupts.
-
*/
-
int syscore_suspend(void)
-
{
-
struct
syscore_ops *ops;
-
int ret =
0;
-
-
pr_debug(
"Checking wakeup interrupts\n");
-
-
/* Return error code if there are any wakeup interrupts pending. */
-
ret =
check_wakeup_irqs();
-
if (ret)
-
return ret;
-
-
WARN_ONCE(!
irqs_disabled(),
-
"Interrupts enabled before system core suspend.\n");
//我们可以看到,如果此时中断没有屏蔽掉,会有警告产生
-
-
list_for_each_entry_reverse(ops, &syscore_ops_list, node)
//按照链表逆序执行各个注册对象的suspend回调函数
-
if (ops->suspend) {
-
if (initcall_debug)
-
pr_info(
"PM: Calling %pF\n", ops->suspend);
-
ret = ops->
suspend();
-
if (ret)
-
goto err_out;
-
WARN_ONCE(!
irqs_disabled(),
-
"Interrupts enabled after %pF\n", ops->suspend);
-
}
-
-
return
0;
-
-
err_out:
-
pr_err(
"PM: System core suspend callback %pF failed.\n", ops->suspend);
-
-
list_for_each_entry_continue(ops, &syscore_ops_list, node)
//如果有失败的,则执行已经执行过suspend回调的对象的resume回调
-
if (ops->resume)
-
ops->
resume();
-
-
return ret;
-
}
-
EXPORT_SYMBOL_GPL(syscore_suspend);
-
5)syscore_resume:执行注册对象的resume回调,在suspend.c的唤醒流程中被调用
-
/**
-
* syscore_resume - Execute all the registered system core resume callbacks.
-
*
-
* This function is executed with one CPU on-line and disabled interrupts.
-
*/
-
void syscore_resume(void)
-
{
-
struct
syscore_ops *ops;
-
-
WARN_ONCE(!
irqs_disabled(),
-
"Interrupts enabled before system core resume.\n");
-
-
list_for_each_entry(ops, &syscore_ops_list, node)
-
if (ops->resume) {
-
if (initcall_debug)
-
pr_info(
"PM: Calling %pF\n", ops->resume);
-
ops->
resume();
-
WARN_ONCE(!
irqs_disabled(),
-
"Interrupts enabled after %pF\n", ops->resume);
-
}
-
}
6)syscore_shutdown:该接口正常睡眠流程中不涉及调用,主要在sys.c中调用,涉及系统重启、halt等流程。
-
/**
-
* syscore_shutdown - Execute all the registered system core shutdown callbacks.
-
*/
-
void syscore_shutdown(void)
-
{
-
struct
syscore_ops *ops;
-
-
mutex_lock(&syscore_ops_lock);
-
-
list_for_each_entry_reverse(ops, &syscore_ops_list, node)
-
if (ops->shutdown) {
-
if (initcall_debug)
-
pr_info(
"PM: Calling %pF\n", ops->shutdown);
-
ops->
shutdown();
-
}
-
-
mutex_unlock(&syscore_ops_lock);
-
}
边栏推荐
- 普林斯顿微积分读本03第二章--编程实现函数图像绘制、三角学回顾
- 一文带你了解redux的工作流程——actionreducerstore
- MySQL limit paging query and performance issues
- 连续变量离散化教程
- Use Excel to read data exposed by SAP ABAP CDS View through ODBC
- MySQL 的几种碎片整理方案总结(解决delete大量数据后空间不释放的问题)
- JVS低代码能力简介及功能清单
- ESP8266-Arduino编程实例-PIR(被动红外)传感器驱动
- Different lower_case_table_names settings for server ('1') and data dictionary ('0') solution
- 学自动化测试哪个培训机构好 试听课程后就选了这个地方学习
猜你喜欢
JVS轻应用的组成与配置
MySQL百万数据优化总结 一
MySQL 行级锁(行锁、临键锁、间隙锁)
MySql模糊查询大全
一文吃透接口调用神器RestTemplate
【软件工程之美 - 专栏笔记】33 | 测试工具:为什么不应该通过QQ/微信/邮件报Bug?
Experience innovation and iteration through the development of lucky draw mini-programs
Service discovery of kubernetes
DCM middleware family welcomes a new member
Shengxin Weekly Issue 38
随机推荐
应用层基础 —— 认识URL
Addition logic for SAP Commerce Cloud Product Review
lotus-local-net 2k v1.17.0-rc4
结构化查询语言SQL-关系数据库标准语言
MySql模糊查询大全
学习笔记 Golang 写入文件(io.WriteString、ioutil.WriteFile、file.Write、write.WriteString)
Shengxin Weekly Issue 38
DCM 中间件家族迎来新成员
pycharm汉化教程(碧蓝幻想汉化插件安装)
多线程学习笔记-2.final关键字和不变性
mysql 自动添加创建时间、更新时间
“带薪划水”偷刷阿里老哥的面经宝典,三次挑战字节,终成正果
2022/7/28
3.网页信息解析方法:Xpath与BeautifulSoup
Use Excel to read data exposed by SAP ABAP CDS View through ODBC
Redis - Basics
下课看着文档走回实验室,我重新拾起了遗忘的SQL运算符
准确率(Accuracy)、精度(Precision)、召回率(Recall)和 mAP 的图解
VBA实现双击单元格自动输出对号再次双击取消对号
JVS开发套件产品定位