PCIe驱动开发-设备打开/关闭
来源:互联网 发布:unity3d安卓真机调试 编辑:程序博客网 时间:2024/06/05 03:57
上篇中,我们从驱动层面上探讨了系统是如何为我们PCIe设备分配资源以及如何启动它的。现在的问题是,我们的上层软件如何才能对我们的设备进行访问呢。这其中首先涉及的就是设备的开打与关闭。
1:设备打开
针对本次PCI设备,上层程序打开设备函数的具体代码如下。
- /********************************************************************/
- /* Open device ident=0, b--FALSE or TRUE */
- /********************************************************************/
- DLLEXP HANDLE CCONV ClLib_Open( unsigned char ident, BOOLEAN b )
- {
- HANDLE hHandle = INVALID_HANDLE_VALUE;
- GUID *pGuid=(LPGUID)&DEMOPCI_GUID;
- HDEVINFO hDevInfo;
- SP_INTERFACE_DEVICE_DATA IfDevData;
- SP_INTERFACE_DEVICE_DETAIL_DATA *IfDevDetail = NULL;
- DWORD ReqLen;
- // HDEVINFO as all source device is generated
- hDevInfo = SetupDiGetClassDevs(pGuid,
- 0, // Enumerator
- 0, //
- DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
- if (hDevInfo == INVALID_HANDLE_VALUE)
- {
- // Error processing
- return (INVALID_HANDLE_VALUE);
- }
- // All device is enumerated
- IfDevData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
- if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, pGuid, ident, &IfDevData))
- {
- // A necessary amount of the memory in the buffer is obtained
- SetupDiGetDeviceInterfaceDetail(hDevInfo ,&IfDevData, NULL, 0, &ReqLen, NULL);
- // Memory allocation to acquire detailed information
- IfDevDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA *)(new char[ReqLen]);
- if(!IfDevDetail)
- {
- return (INVALID_HANDLE_VALUE);
- }
- IfDevDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
- // Detailed information (pass) is actually acquired
- if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&IfDevData, IfDevDetail, ReqLen, NULL, NULL))
- {
- // Open the driver
- if(b == TRUE)
- {
- sg_bOverlapFlag = 1;
- hHandle=CreateFile(IfDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
- NULL);
- }
- else
- {
- sg_bOverlapFlag = 0;
- hHandle=CreateFile(IfDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- NULL);
- }
- }
- // Opening of allocated memory
- delete IfDevDetail;
- }
- // Cleanup
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return (hHandle);
- }
- /********************************************************************/
- /* Open device ident=0, b--FALSE or TRUE */
- /********************************************************************/
- DLLEXP HANDLE CCONV ClLib_Open( unsigned char ident, BOOLEAN b )
- {
- HANDLE hHandle = INVALID_HANDLE_VALUE;
- GUID *pGuid=(LPGUID)&DEMOPCI_GUID;
- HDEVINFO hDevInfo;
- SP_INTERFACE_DEVICE_DATA IfDevData;
- SP_INTERFACE_DEVICE_DETAIL_DATA *IfDevDetail = NULL;
- DWORD ReqLen;
- // HDEVINFO as all source device is generated
- hDevInfo = SetupDiGetClassDevs(pGuid,
- 0, // Enumerator
- 0, //
- DIGCF_PRESENT | DIGCF_INTERFACEDEVICE );
- if (hDevInfo == INVALID_HANDLE_VALUE)
- {
- // Error processing
- return (INVALID_HANDLE_VALUE);
- }
- // All device is enumerated
- IfDevData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
- if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, pGuid, ident, &IfDevData))
- {
- // A necessary amount of the memory in the buffer is obtained
- SetupDiGetDeviceInterfaceDetail(hDevInfo ,&IfDevData, NULL, 0, &ReqLen, NULL);
- // Memory allocation to acquire detailed information
- IfDevDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA *)(new char[ReqLen]);
- if(!IfDevDetail)
- {
- return (INVALID_HANDLE_VALUE);
- }
- IfDevDetail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
- // Detailed information (pass) is actually acquired
- if(SetupDiGetDeviceInterfaceDetail(hDevInfo,&IfDevData, IfDevDetail, ReqLen, NULL, NULL))
- {
- // Open the driver
- if(b == TRUE)
- {
- sg_bOverlapFlag = 1;
- hHandle=CreateFile(IfDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
- NULL);
- }
- else
- {
- sg_bOverlapFlag = 0;
- hHandle=CreateFile(IfDevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- NULL);
- }
- }
- // Opening of allocated memory
- delete IfDevDetail;
- }
- // Cleanup
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return (hHandle);
- }
来看几个关键函数:
HDEVINFO SetupDiGetClassDevs( __in_opt const GUID *ClassGuid, __in_opt PCTSTR Enumerator, __in_opt HWND hwndParent, __in DWORD Flags);
该函数用于获取指定类别的设备信息结构的句柄。值得注意的是参数*ClassGuid应指定成我们驱动安装时的.inf文件中Guid号(DEMOPCI_GUID),这样才能保证正确得到对应的设备句柄。BOOL SetupDiEnumDeviceInterfaces( __in HDEVINFO DeviceInfoSet, __in_opt PSP_DEVINFO_DATA DeviceInfoData, __in const GUID *InterfaceClassGuid, __in DWORD MemberIndex, __out PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
该函数枚举所有指定类别的设备接口。BOOL SetupDiGetDeviceInterfaceDetail( __in HDEVINFO DeviceInfoSet, __in PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, __out_opt PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, __in DWORD DeviceInterfaceDetailDataSize, __out_opt PDWORD RequiredSize, __out_opt PSP_DEVINFO_DATA DeviceInfoData);该函数返回设备接口的设置信息。
HANDLE WINAPI CreateFile( __in LPCTSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile);该函数应用很广泛,可以用来创建或者打开文件或者设备。本例中我们可以通过设置参数dwFlagsAndAttributes(FILE_FLAG_OVERLAPPED)来决定设备是异步还是同步方式打开。
2:设备关闭
相比起前面的设备打开程序,设备关闭显得要简单许多,直接调用CloseHandle函数注销设备句柄即可。
- /********************************************************************/
- /* Close device */
- /********************************************************************/
- DLLEXP int CCONV ClLib_Close( HANDLE hHandle )
- {
- BOOL bRet;
- bRet = CloseHandle(hHandle);
- if(bRet)
- return RTN_OK;
- else
- return RTN_ERR;
- }
- /********************************************************************/
- /* Close device */
- /********************************************************************/
- DLLEXP int CCONV ClLib_Close( HANDLE hHandle )
- {
- BOOL bRet;
- bRet = CloseHandle(hHandle);
- if(bRet)
- return RTN_OK;
- else
- return RTN_ERR;
- }
小结:通过上述打开设备函数,我们已经得到相应设备的句柄,后续操作中直接使用该句柄就能实现对设备的访问了(如寄存器读写等)。
阅读全文
0 0
- PCIe驱动开发-设备打开/关闭
- PCIe驱动开发-设备打开/关闭
- linux设备驱动之PCIE驱动开发
- PCIe设备漫游记----设备打开/关闭篇
- PCIe驱动开发-BOIS
- PCIe驱动开发-BOIS
- linux下pcie设备驱动
- PCIe驱动开发-驱动加载
- PCIe驱动开发-驱动加载
- PCIe驱动开发-寄存器读写
- PCIe驱动开发接口函数
- PCIe设备漫游记----驱动加载篇
- PCIe-块设备驱动-Single DMA
- PCIe-块设备驱动-SG DMA
- PCIe设备漫游记----驱动加载篇
- 驱动开发之 应用程序通过设备接口打开设备
- 打开,关闭设备
- SylixOS 的 PCIe 驱动开发 【第一篇】PCIe 基础知识
- redis详解-- 面试题
- 测试常识-术语行话
- (112)流程控制
- 如何通过curl完成一些功能
- 问题总结
- PCIe驱动开发-设备打开/关闭
- 使用websocket 实现即时消息
- Python数据库操作(PyMysql)
- 第一阶段第三天(数据类型,运算符)
- Java学习笔记-《Java程序员面试宝典》-第四章基础知识-4.1基本概念(4.1.3)
- 使用Linux系统开发php程序(如:ubuntu)
- 基于python的添加和删除安全组的脚本
- 堆排序 C++
- Filter(过滤器)