博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PowerManager & Wake-up Function of USB Client
阅读量:5925 次
发布时间:2019-06-19

本文共 2082 字,大约阅读时间需要 6 分钟。

今天下午只是大概了解了一下,流程中的一些地方看不到代码, 所以这些看不到代码的地方只能猜想WINCE的行为了.

首先是注意到bul_usbfn.cpp里的BulUsbDevice::SetPowerState函数. 这是由UfnPdd_IOControl调用的, 这和WINCE HELP里的要求一致. 而根据WINCE HELP, 设备应该有D0~D4五种电源状态,而实际上PXA27X的USB只有POWER ON和POWER OFF两种状态, 所以该函数的开头作了一下几种状态的判断转换.  

接下来驱动里调用了一个API: SetDevicePowerState,   这个API的具体代码看不到.文档上说This function requests that the bus driver set this device to the power state specified by PowerState. 但比较纳闷的是这函数不应该从硬件上操作模块的寄存器啊,因为这是下一步做的.

然后就调用BulUsbDevice::PowerMgr(FLASE)进行硬件操作, 把UDE关掉.值得注意的是在USB初始化和关闭函数中,UDE的开启关闭和USB CLOCK的开启关闭都是同时的,但是这里的USB的CLOCK并没有关闭. 我个人猜测这应该就是为了后面把USB的SYSINTR发给系统WAKE-UP用的. 也就是说UDE关掉,CLOCK开启, 那么模块的IRQ还是能进来并转换为SYSINTR的.

下面几行就是针对D0~D4进行操作, 其中D1,D2状态已经合并到D0状态.其中注意各状态和IOCTL_HAL_DISABLE_WAKE, IOCTL_HAL_ENABLE_WAKE的对应关系. 而这两个IOCTL操作, 是在oal_ioctl_tab.h里和OAL函数相对应成一个TABLE. 我们只看与电源管理相关的三个:

{ IOCTL_HAL_DISABLE_WAKE,                   0,  OALIoCtlHalDisableWake      },

{ IOCTL_HAL_ENABLE_WAKE,                    0,  OALIoCtlHalEnableWake       },
{ IOCTL_HAL_GET_WAKE_SOURCE,          0,  OALIoCtlHalGetWakeSource    },

所对应的三个函数在platformname\src\common\power\pxa27x\ioctl.c里面可以看到.这个是由OEM完成的. 也就是说, 驱动里调了KernelIoControl, KernelIoControl里又调了OALIoCtlHalxxxxxxx. 而KernelIoControl里面的操作是不可见的.

好象扯远了,回头看BulUsbDevice::SetwerState函数, 调用KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &m_dwSysIntr,  sizeof(m_dwSysIntr), NULL, 0, NULL) 就是让USB的系统中断号SYSINTR能够把系统从SLEEP状态里WAKE-UP起来. 而具体这步操作, 在PM的OALIoCtlHalEnableWake函数里实现, 修改了PXA27X Clock & Power Manager里面的寄存器, 在硬件上ENABLE指定模块的唤醒功能.

再下面是要求开电源时, 操作硬件开启UDE的代码.

那么总结一下流程,假设现在USB CLIENT的电源状态为D0,全开, 而这时系统要进入SLEEP状态, 这时候系统就根据注册表中的值来决定把USB CLIENT切换到D3状态. 通过IOCTL函数告知USB CLIENT DRIVER, 一路走到SetPowerState. 这时候D3<D0, 所以把UDE关闭, 但保持USB CLIENT CLOCK开启. 接着通过KernelIoControl去和那个IOCTL映射表去修改power manager register,使能USB CLIENT的唤醒功能.

系统进入SLEEP状态并且USB CLIENT WAKE-UP ENABLE后,如果来了个USB CLIENT的中断,那么我个人猜想该IRQ转换成SYSINTR后应该不是去走USB驱动里的IST了,而是通知系统WAKE-UP.系统被唤醒后,反过来改变USB CLIENT的POWER STATE为D0, 从而禁能USB CLIENT的WAKE-UP功能, 同时开启UDE. 然后是个人猜测UDE被开启后才使得该IRQ进到驱动的IST中处理 . 系统完全运行起来.

这篇文章是为了记录下午的思路, 很多地方没有看到代码或没有严格论证,想当然地推倒, 是很不严谨的.

本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2006/02/05/325594.html,如需转载请自行联系原作者

你可能感兴趣的文章
ResourceManager中的Resource Estimator框架介绍与算法剖析
查看>>
5分钟内看懂机器学习和深度学习的区别
查看>>
使用Network Recycle Bin启用映射网络驱动器上的回收站
查看>>
量子计算机的现状和趋势
查看>>
iOS - block变量捕获原理
查看>>
Kotlin Weekly 中文周报
查看>>
Angular 4.x 事件管理器及自定义EventManagerPlugin
查看>>
Java8新的异步编程方式 CompletableFuture(三)
查看>>
基于DeepConvLSTM的传感器信号分类
查看>>
【JS第34期】BOM-window对象
查看>>
Android ContentProvider支持跨进程数据共享与"互斥、同步" 杂谈
查看>>
使用CADisplayLink实现UILabel动画特效
查看>>
iOS11、iPhone X 适配简单,但你的Apple思维适配做好了么?
查看>>
JS设计模式五:职责链模式
查看>>
图片加载框架Picasso - 源码分析
查看>>
[单刷 APUE 系列] 第十四章——高级 I/O
查看>>
app启动广告页的实现,解决了广告图片要实时更新的问题
查看>>
朱晔的互联网架构实践心得S1E7:三十种架构设计模式(上)
查看>>
SpringBoot整合Redis
查看>>
使用Java API的5个技巧
查看>>