时钟 IoTimer

  1 /*
  2     例程是在运行在DISPATCH_LEVEL的IRQL级别
  3     例程中不能使用分页内存
  4     另外在函数首部使用 #pragma LOCKEDCODE
  5 */
  6
  7 #include "Driver.h"
  8
  9 #define DeviceName L"\\Device\\MyDDKDevice"
 10
 11 #pragma INITCODE
 12 extern "C" NTSTATUS DriverEntry (
 13             IN PDRIVER_OBJECT pDriverObject,
 14             IN PUNICODE_STRING pRegistryPath    )
 15 {
 16     NTSTATUS status;
 17     KdPrint(("Enter DriverEntry\n"));
 18
 19     pDriverObject->DriverUnload = UnloadDriver;
 20
 21     //设置派遣函数
 22
 23     /*
 24         ARRAY_SIZE 定义设备结构体的个数
 25         #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr))
 26
 27     */
 28
 29     for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i)    //ARRAY_SIZE 定义设备结构体的个数
 30         pDriverObject->MajorFunction[i] = DispatchFunction;
 31
 32
 33
 34     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl;
 35
 36     //创建驱动设备对象
 37     status = CreateDevice(pDriverObject);
 38
 39     KdPrint(("Leave DriverEntry\n"));
 40     return status;
 41 }
 42
 43 #pragma LOCKEDCODE
 44 VOID OnTimer(
 45     IN PDEVICE_OBJECT DeviceObject,
 46     IN PVOID Context)
 47 {
 48     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
 49         DeviceObject->DeviceExtension;
 50     KdPrint(("Enter OnTimer!\n"));
 51
 52     //将计数器自锁减一
 53     InterlockedDecrement(&pDevExt->lTimerCount);
 54
 55     /*如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算
 56     LONG __cdecl InterlockedCompareExchange(
 57
 58       __inout  LONG volatile *Destination, //当前值
 59
 60       __in     LONG Exchange, //当比较值与当前值相同时 替换当前值
 61
 62       __in     LONG Comparand //比较值
 63
 64     PVOID __cdecl InterlockedCompareExchangePointer(
 65
 66       __inout  PVOID volatile *Destination,
 67
 68       __in     PVOID Exchange,
 69
 70       __in     PVOID Comparand
 71
 72     这两个函数以原子方式执行一个测试和设置操作。对32位应用程序来说,这两个函数都对32位值进行操作;
 73     在64位应用程序中,InterlockedCompareExchange对32位值进行操作而InterlockedCompareExchangePointer对64位值进行操作。
 74     函数会将当前值(Destination指向的)与参数Comparand进行比较,如果两个值相同,那么函数会将*Destination修改为Exchange参数指定的值。
 75     若不等,则*Destination保持不变。函数会返回*Destination原来的值。所有这些操作都是一个原子执行单元来完成的。
 76
 77     */
 78     LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0);
 79
 80     //每隔三秒,计数器一个循环,输出以下log
 81     if (previousCount==0)
 82     {
 83         KdPrint(("%d seconds time out!\n",TIMER_OUT));
 84     }
 85
 86     //证明该线程运行在任意线程上下文的
 87     /*
 88     PEPROCESS pEProcess = IoGetCurrentProcess();
 89     PTSTR ProcessName = (PTSTR) ((ULONG)pEProcess + 0x174);
 90     */
 91     PEPROCESS pEProcess = IoGetCurrentProcess();
 92
 93     PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程
 94
 95     KdPrint(("The current process is %s\n",ProcessName));
 96 }
 97
 98
 99 /************************************************************************
100 * 函数名称:CreateDevice
101 * 功能描述:初始化设备对象
102 * 参数列表:
103       pDriverObject:从I/O管理器中传进来的驱动对象
104 * 返回 值:返回初始化状态
105 *************************************************************************/
106 #pragma INITCODE
107 NTSTATUS CreateDevice (
108         IN PDRIVER_OBJECT    pDriverObject)
109 {
110     NTSTATUS status;
111     PDEVICE_OBJECT pDevObj;
112     PDEVICE_EXTENSION pDevExt;
113
114     //创建设备名称
115     UNICODE_STRING devName;
116     RtlInitUnicodeString(&devName,DeviceName);
117
118     //创建设备
119     status = IoCreateDevice( pDriverObject,
120                         sizeof(DEVICE_EXTENSION),
121                         &(UNICODE_STRING)devName,
122                         FILE_DEVICE_UNKNOWN,
123                         0, TRUE,
124                         &pDevObj );
125     if (!NT_SUCCESS(status))
126         return status;
127
128     pDevObj->Flags |= DO_DIRECT_IO;
129     pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
130     pDevExt->pDevice = pDevObj;
131     pDevExt->ustrDeviceName = devName;
132
133     IoInitializeTimer(pDevObj,OnTimer,NULL);    // 初始化IoTimer
134
135     //创建符号链接
136     // 不进行Ring3层的交互  则不需要进行创建符号链接
137     NICODE_STRING symLinkName;
138     RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
139     pDevExt->ustrSymLinkName = symLinkName;
140     status = IoCreateSymbolicLink( &symLinkName,&devName );
141     if (!NT_SUCCESS(status))
142     {
143         IoDeleteDevice( pDevObj );
144         return status;
145     }
146     return STATUS_SUCCESS;
147 }
148
149 /************************************************************************
150 * 函数名称:HelloDDKUnload
151 * 功能描述:负责驱动程序的卸载操作
152 * 参数列表:
153       pDriverObject:驱动对象
154 * 返回 值:返回状态
155 *************************************************************************/
156 #pragma PAGEDCODE
157 VOID UnloadDriver (IN PDRIVER_OBJECT pDriverObject)
158 {
159     PDEVICE_OBJECT    pNextObj;
160     KdPrint(("Enter DriverUnload\n"));
161     pNextObj = pDriverObject->DeviceObject;
162     while (pNextObj != NULL)
163     {
164         PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
165             pNextObj->DeviceExtension;
166         //删除符号链接
167         UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
168         IoDeleteSymbolicLink(&pLinkName);
169         pNextObj = pNextObj->NextDevice;
170         IoDeleteDevice( pDevExt->pDevice );
171     }
172 }
173
174 /************************************************************************
175 * 函数名称:HelloDDKDispatchRoutin
176 * 功能描述:对读IRP进行处理
177 * 参数列表:
178       pDevObj:功能设备对象
179       pIrp:从IO请求包
180
181
182       默认派遣例程
183 * 返回 值:返回状态
184 *************************************************************************/
185 #pragma PAGEDCODE
186 NTSTATUS DispatchFunction(IN PDEVICE_OBJECT pDevObj,
187                                  IN PIRP pIrp)
188 {
189
190
191     KdPrint(("Enter HelloDDKDispatchRoutin\n"));
192
193     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
194     //建立一个字符串数组与IRP类型对应起来
195     static char* irpname[] =
196     {
197         "IRP_MJ_CREATE",
198         "IRP_MJ_CREATE_NAMED_PIPE",
199         "IRP_MJ_CLOSE",
200         "IRP_MJ_READ",
201         "IRP_MJ_WRITE",
202         "IRP_MJ_QUERY_INFORMATION",
203         "IRP_MJ_SET_INFORMATION",
204         "IRP_MJ_QUERY_EA",
205         "IRP_MJ_SET_EA",
206         "IRP_MJ_FLUSH_BUFFERS",
207         "IRP_MJ_QUERY_VOLUME_INFORMATION",
208         "IRP_MJ_SET_VOLUME_INFORMATION",
209         "IRP_MJ_DIRECTORY_CONTROL",
210         "IRP_MJ_FILE_SYSTEM_CONTROL",
211         "IRP_MJ_DEVICE_CONTROL",
212         "IRP_MJ_INTERNAL_DEVICE_CONTROL",
213         "IRP_MJ_SHUTDOWN",
214         "IRP_MJ_LOCK_CONTROL",
215         "IRP_MJ_CLEANUP",
216         "IRP_MJ_CREATE_MAILSLOT",
217         "IRP_MJ_QUERY_SECURITY",
218         "IRP_MJ_SET_SECURITY",
219         "IRP_MJ_POWER",
220         "IRP_MJ_SYSTEM_CONTROL",
221         "IRP_MJ_DEVICE_CHANGE",
222         "IRP_MJ_QUERY_QUOTA",
223         "IRP_MJ_SET_QUOTA",
224         "IRP_MJ_PNP",
225     };
226
227     UCHAR type = stack->MajorFunction;
228     if (type >= arraysize(irpname))
229         KdPrint((" - Unknown IRP, major type %X\n", type));
230     else
231         KdPrint(("\t%s\n", irpname[type]));
232
233     NTSTATUS status = STATUS_SUCCESS;
234     // 完成IRP
235     pIrp->IoStatus.Status = status;
236     pIrp->IoStatus.Information = 0;    // bytes xfered
237     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
238
239     KdPrint(("Leave HelloDDKDispatchRoutin\n"));
240
241     return status;
242 }
243
244 #pragma PAGEDCODE
245 NTSTATUS DeviceIOControl(IN PDEVICE_OBJECT pDevObj,
246                                  IN PIRP pIrp)
247 {
248     NTSTATUS status = STATUS_SUCCESS;
249     KdPrint(("Enter HelloDDKDeviceIOControl\n"));
250
251     //获得当前IRP堆栈
252     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
253     //得到输入缓冲区大小
254     ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
255     //得到输出缓冲区大小
256     ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
257     //得到IOCTL码
258     ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
259
260     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
261         pDevObj->DeviceExtension;
262
263     ULONG info = 0;
264
265     switch (code)
266     {                        // process request
267         case IOCTL_START_TIMER:
268         {
269             KdPrint(("IOCTL_START_TIMER\n"));
270             pDevExt->lTimerCount = TIMER_OUT;
271             IoStartTimer(pDevObj);        //激活时钟
272             break;
273         }
274         case IOCTL_STOP:
275         {
276             KdPrint(("IOCTL_STOP\n"));
277             IoStopTimer(pDevObj);        // 停止时钟
278             break;
279         }
280         default:
281             status = STATUS_INVALID_VARIANT;
282     }
283
284     // 完成IRP
285     pIrp->IoStatus.Status = status;
286     pIrp->IoStatus.Information = info;    // bytes xfered
287     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
288
289     KdPrint(("Leave HelloDDKDeviceIOControl\n"));
290
291     return status;
292 }

代码

时间: 2024-08-03 15:43:43

时钟 IoTimer的相关文章

门控时钟-理论分析 ---- 转载

转载自:http://www.chipsbank.com/news_detail/newsId=123.html 门控的基本要求: 1. 所需要的沿(对于正沿触发的寄存器是正沿,对于负沿触发的寄存器是负沿)不增加,不减少: 1. 不会产生毛刺: 1. 使用后功耗要能够降低: 1. 最好面积还会减小. 1. 上升沿触发的门控时钟的结构研究:应用与上升沿触发的寄存器的门控. 1. 直接与门结构: 1. 高电平使能Latch + 与门结构: 1. 低电平使能Latch + 与门结构: 1. 波形研究:

【JAVA语言程序设计基础篇】--图形-- 三种时钟--增强对类的理解和应用

1.显示任意时间时钟 2.设置三个可见性属性 分别表示时针,分针,秒针的可见性 3.一个精细的时钟 主类:StillClock @SuppressWarnings("serial") class DetailedClock extends JPanel { private int hour; private int minute; private int second; protected int xCenter, yCenter; protected int clockRadius;

第三部分:S5PV210_时钟部分_1

时钟部分 (1)时钟域 S5PV210一共有三个时钟域:MSYS,DSYS,PSYS MSYS:(main system)主时钟域,包括CPU,DDR内存条,IROM和IRAM等 DSYS:(display system)显示时钟域,就是一般的和视频有关的就在这个时钟域中,如HDMI,TVENC... PSYS:(peripheral system)外围时钟域,就是GPIO接口,I2C接口,UART接口等这些外围设备就在这个时钟域上. 每个时钟域通过一条BRG(异步总线的桥梁)连接在一起. (2

Android 开发第七弹:简易时钟(秒表)

本文承接,Android 开发第五弹:简易时钟(闹钟) 和 Android 开发第六弹:简易时钟(计时器),这一部分是关于秒表的. 布局 同样是新建一个类(StopWatchView)并扩展自LinearLayout,并将其用作布局. <myapplication.nomasp.com.clock.StopWatchView android : id = "@+id/tabStopWatch" android : layout_width = "match_parent

(16)给树莓派B+ 安装一个实时时钟芯片DS1302

在这里首先感谢glgoo在google被墙的情况下提供搜索功能,还要感谢 http://wiringpi.com/ 以及github,尽管自己眼瞎,几经波折还是发现了尘封已久的少林"七十二绝技",没错,每种绝技都能克制一个树莓派GPIO控制外设的问题,七十二绝技的核心就是wiringpi这个为Pi GPIO写的C语言库了,而每种绝技则暗藏在wiringPi/examples/目录下,这里就不一一罗列了,大家想学什么招式,就去看每个example,都非常简短. 其实早在第9篇文章&quo

AppWidget 如android桌面上的时钟

一. 1.App widget 是在home桌面的一个空间,比如时钟,播放器播放时小图标可以点击下一首等那个. 2.AppWidgetProviderInfo 对象: 为App Widget 提供元数据,包括布局,更新频率等数据,这个对象被定义在xml文件当中. 3.AppWidgetProvider : 定义一个App Widget 的基本生命周期函数. 二.创建App Widget步骤: 1.定义AppWidgetProviderInfo : 在res/xml文件夹中定义 example_a

时钟+温度+遥控设置,综合时钟例子

时钟+温度+遥控设置,综合时钟例子6月30日到手的二手单片机开发板,今天做个综合的时钟例子,包含代码和仿真.做个近期的学习总结. 按独立键盘K1和红外遥控的EQ为设置键.按独立键盘K2和红外遥控的VOL+为加键.按独立键盘K3和红外遥控的VOL-为减键. 手摸温度传感器,当温度超过 34℃ 的时候点亮LED灯,模拟启动的设备. 程序有很多细节没有优化,主要是学习,lcd1602显示,独立建扫描,红外遥控,ds1302时钟芯片,ds18b20温度传感器. 实时时钟综合应用,源代码和仿真下载http

第35天:时钟效果

时钟效果案例 1.得到现在的时分秒2.旋转角度原理一圈360°   60s   1s/6°旋转second.style.WebkitTransform="rotate(60deg)";//每秒旋转60度 案例: 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>时钟效果</

张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231

原文:张高兴的 Windows 10 IoT 开发笔记:RTC 时钟模块 DS3231 GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/DS3231 注意:不包含闹钟设置