当前位置:网站首页>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);
-
}
边栏推荐
- Docker installs canal and mysql for simple testing and achieves cache consistency between redis and mysql
- 给你一个大厂面试的机会,你能面试上吗?进来看看!
- 学习爬虫之Scrapy框架学习(1)---Scrapy框架初学习及豆瓣top250电影信息获取的实战!
- Obsidian设置图床
- musl Reference Manual
- 分布式事务Seata详细使用教程
- DCM 中间件家族迎来新成员
- 数据持久化技术——MP
- xmind使用指南(XMind具有下列哪些功能)
- 【虚拟化生态平台】树莓派安装虚拟化平台操作流程
猜你喜欢
随机推荐
3D激光SLAM:LeGO-LOAM论文解读---完整篇
5 open source Rust web development frameworks, which one do you choose?
Different lower_case_table_names settings for server ('1') and data dictionary ('0') solution
最新MySql安装教学,非常详细
第十二章 使用中的 OpenAPI 属性
透过开发抽奖小程序,体会创新与迭代
3D激光SLAM:LeGO-LOAM论文解读---点云分割部分
[Virtualization ecological platform] Raspberry Pi installation virtualization platform operation process
在 Excel 里使用 ODBC 读取 SAP BTP 平台上 CDS view 的数据
学自动化测试哪个培训机构好 试听课程后就选了这个地方学习
apisix-入门使用篇
ESP8266-Arduino编程实例-PIR(被动红外)传感器驱动
安装MYSQL遇到问题:write configuration file卡主
deeplab implements its own remote sensing geological segmentation dataset
keras自带数据集(横线生成器)
MySQL row-level locks (row locks, adjacent key locks, gap locks)
R语言做面板panelvar例子
[ 图 论 ]二分图判定及其匹配(基础+提高)
Distributed Transactions - Introduction to Distributed Transactions, Distributed Transaction Framework Seata (AT Mode, Tcc Mode, Tcc Vs AT), Distributed Transactions - MQ
cesium-Web网页优化进阶









