已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
arm电源管理(1)-apm.c - 内核版本比较旧了由于arm系统中没有bios设备, 所以只能为arm系统创建一个虚拟的字符设备与用户空间进行通讯. 这就是/arch/arm/kernel/amp.c1. 工作原理: 这个apm中实现一个misc设备,实质上也是一个字符设备, misc设备的主设备号是10, 而apm_bios作为一个misc设备, 次设备号是134. 定义为:/* The apm_bios device is one of the misc char devices.* This is its minor number.*/#define APM_MINOR_DEV 134 这个apm_bios设备通过ioctl系统调用和用户空间进行通讯, 即当用户进程通过ioctl发来suspend命令时, 它就传给内核, 使系统进入suspend状态. 2. 初始化static int _init apm_init(void) int ret; if (apm_disabled) printk(KERN_NOTICE apm: disabled on user request.n); return -ENODEV; if (PM_IS_ACTIVE() printk(KERN_NOTICE apm: overridden by ACPI.n); return -EINVAL; pm_active = 1; /创建一个线程, 用于处理事件队列, 工作函数是kapmd /这个线程好像在arm中没有作用? ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); if (ret suser = capable(CAP_SYS_ADMIN); as-writer = (filp-f_mode & FMODE_WRITE) = FMODE_WRITE; as-reader = (filp-f_mode & FMODE_READ) = FMODE_READ; /将这个用户加入用户队列 down_write(&user_list_lock); list_add(&as-list, &apm_user_list); up_write(&user_list_lock); /这是一个传递私有数据的一个通用方式 filp-private_data = as; return as ? 0 : -ENOMEM;当用户空间进程去读这个设备时, 这个函数就会被调用. 这个函数的主要作用是将事件读出到用户空间static ssize_t apm_read(struct file *fp, char _user *buf, size_t count, loff_t *ppos) struct apm_user *as = fp-private_data; apm_event_t event; int i = count, ret = 0; if (count queue) & fp-f_flags & O_NONBLOCK) return -EAGAIN; /否则等待到队列非空为止, wait_event_interruptible(apm_waitqueue, !queue_empty(&as-queue); /将队列中的事件复制给用户空间 while (i = sizeof(event) & !queue_empty(&as-queue) event = queue_get_event(&as-queue); ret = -EFAULT; if (copy_to_user(buf, &event, sizeof(event) break; /设置状态 if (event = APM_SYS_SUSPEND | event = APM_USER_SUSPEND) as-suspend_state = SUSPEND_READ; buf += sizeof(event); i -= sizeof(event); if (i private_data; poll_wait(fp, &apm_waitqueue, wait); return queue_empty(&as-queue) ? 0 : POLLIN | POLLRDNORM;/这个是这个设备的核心函数, 用于内核与用户空间交互/* apm_ioctl - handle APM ioctl* APM_IOC_SUSPEND* This IOCTL is overloaded, and performs two functions. It is used to:* - initiate a suspend* - acknowledge a suspend read from /dev/apm_bios.* Only when everyone who has opened /dev/apm_bios with write permission* has acknowledge does the actual suspend happen.*/static intapm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) struct apm_user *as = filp-private_data; unsigned long flags; int err = -EINVAL; if (!as-suser | !as-writer) return -EPERM; switch (cmd) case APM_IOC_SUSPEND: as-suspend_result = -EINTR; if (as-suspend_state = SUSPEND_READ) /* * If we read a suspend command from /dev/apm_bios, * then the corresponding APM_IOC_SUSPEND ioctl is * interpreted as an acknowledge. */ as-suspend_state = SUSPEND_ACKED; suspends_pending-; else /* * Otherwise it is a request to suspend the system. * Queue an event for all readers, and expect an * acknowledge from all writers who havent already * acknowledged. */ queue_event(APM_USER_SUSPEND, as); /* * If there are no further acknowledges required, suspend * the system. */ if (suspends_pending = 0) apm_suspend(); /系统进入suspend状态 /从suspend中返回 /* * Wait for the suspend/resume to complete. If there are * pending acknowledges, we wait here for them. * * Note that we need to ensure that the PM subsystem does * not kick us out of the wait when it suspends the threads. */ flags = current-flags; current-flags |= PF_NOFREEZE; /* * Note: do not allow a thread which is acking the suspend * to escape until the resume is complete. */ if (as-suspend_state = SUSPEND_ACKED) wait_event(apm_suspend_waitqueue, as-suspend_state = SUSPEND_DONE); else wait_event_interruptible(apm_suspend_waitqueue, as-suspend_state = SUSPEND_DONE); current-flags = flags; err = as-suspend_result; as-suspend_state = SUSPEND_NONE; break; return err;4. 事件队列函数static void queue_event(apm_event_t event, struct apm_user *sender) struct apm_user *as; down_read(&user_list_lock); /将事件加入其他USER,除自己外 list_for_each_entry(as, &apm_user_list, list) if (as != sender & as-reader) queue_event_one_user(as, event); up_read(&user_list_lock); /唤醒等待读的进程 wake_up_interruptible(&apm_waitqueue);static void queue_event_one_user(struct apm_user *as, apm_event_t event) if (as-suser & as-writer) switch (event) case APM_SYS_SUSPEND: case APM_USER_SUSPEND: /* * If this user already has a suspend pending, * dont queue another one. */ if (as-suspend_state != SUSPEND_NONE) return; as-suspend_state = SUSPEND_PENDING; suspends_pending+; break; queue_add_event(&as-queue, event);static void queue_add_event(struct apm_queue *q, apm_event_t event) q-event_head = (q-event_head + 1) % APM_MAX_EVENTS; if (q-event_head = q-event_tail) /满了 static int notified; if (notified+ = 0) printk(KERN_ERR apm: an event queue overflowedn); q-event_tail = (q-event_tail + 1) % APM_MAX_EVENTS; q-eventsq-event_head = event; 加入队头在来看一个出队的函数:/在队尾出列static inline apm_event_t queue_get_event(struct apm_queue *q) q-event_tail = (q-event_tail + 1) % APM_MAX_EVENTS; return q-eventsq-event_tail;/* APM event queue management.*/static inline int queue_empty(struct apm_queue *q) return q-event_head = q-event_tail;/队列的结构/* Maximum number of events stored*/#define APM_MAX_EVENTS 16struct apm_queue unsigned int event_head; unsigned int event_tail; apm_event_t eventsAPM_MAX_EVENTS;5. apm_suspend()这里才是整个设备想做的事情-将系统转入suspend状态static void apm_suspend(void) struct apm_user *as; /调用体系无关的接口,将系统转入suspend状态 int err = pm_suspend(PM_SUSPEND_MEM); /从suspend返回 /* * Anyone on the APM queues will think were still suspended. * Send a message so everyone knows were now awake again. */ /发送一个resume事件 queue_event(APM_NORMAL
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026二上数学第五单元动画课件
- 胰十二指肠切除术围手术期引流管管理专家共识总结2026
- 2026北师大二下买电器情境课件
- 2025-2026学年九年级物理(天津专用)上学期期末模拟试卷(含答案)
- 《商务数据分析与应用》 课件 项目一 商务数据认知
- 2026北师大二下小蝌蚪成长情境课件
- 基于高通量测序法的胎儿染色体非整倍体(T21、T18、T13)检测试剂盒注册审查指导原则(2026年修订版)(2026年第22号)
- Unit 4 The Earth Section 1 Experiencing and understanding language Reading 教学设计2026-2027学年沪教版英语七年级上册
- 2026四下数学小数的意义性质同步课件
- 2026四下数学观察物体二新课标课件
- 2026年新教师班级管理入门培训课件
- 2026年北京市海淀区教育系统事业编人员招聘笔试参考试题及答案详解
- 2026年高校辅导员面试题(附答案)
- 2026年消防安全知识考试试卷(附答案)
- MOOC 研究生学术规范与学术诚信-南京大学 中国大学慕课答案
- 赵本山小品心病台词赵本山小品心病
- 超市设备采购招标文件
- 聚合物近代仪器分析
- 美学概论(第四版)PPT完整全套教学课件
- 提篮式方箱拱桥钢结构安装施工组织方案
- GB/T 23577-2009道路施工与养护机械设备基本类型识别与描述
评论
0/150
提交评论