一个最简单的问题:CreateFile()函数与COM_Open()函数的关系

fqwefqwef   2009-3-27 17:33 楼主
请教大家一个最基本的问:
    这两天研究了一下串口驱动程序(MDD,PDD),发现这么一个问题:CreateFile(L"COM1:",....)中的"COM1"的信息是怎样记录到COM_Open()的句柄中的。COM_init()(有DeviceArrayIndex和Priority256)和HWinit(有memory window,interrupt,physical base) 中好像没有对COM index的记录?有的话,麻烦指点下!,COM_Read()又是如何判断要读数据的口是COM1还是其他口的呢?我看了好几遍了都没看明白 ,请高手指点下!不胜感激!

回复评论 (9)

L"COM1:"参数,就是用于COM_Read判断的
应该去研究CreateFile创建的句柄中,COM1:对应于什么信息,这个信息就是以后相关API判断操作那个文件或设备的依据。

不知道我有没有理解LZ的问题
点赞  2009-3-27 17:41
HANDLE COM_Init(
  ULONG Identifier
);

这个吧
点赞  2009-3-27 17:44
二楼说的也对,但是就是不知道COM_Read是根据那个记录信息来判断的.
点赞  2009-3-28 08:42
COM_Read()代码开始是对参数检查,包括对存取权限,OpenCnt等。之后计算超时时间,如果设定了超时读取动作会在超时后返回,不管是否读到了足够长度的数据。随后就是简单对软件缓冲进行读取的操作了,读取的操作是在RX_CS中完成的。最后在读取的过程中需要处理流控制的成本了,包括软件流和硬件流. 那么它从软件缓冲读取数据时,怎么知道是哪个口的数据呢?
点赞  2009-3-28 08:50
大家帮忙顶一下阿!
点赞  2009-3-28 16:05
你在 COM_Init(ULONG Identifier) 中, 應可透過 OpenDeviceKey 來得到其 registry setting (若不知如何使用, 請參考 %_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\SERIAL\COM_MDD2\mdd2.c 的程式). 如此即可得知其載入的 Index, 或是透過 RegOpenKeyEx(HKEY_LOCAL_MACHINE, Identifier, ...) 的方式, 來直接得到 "Activate" 的值, 將值記錄在 COM_Init 的回傳值 (return value) 中, 該值即為 COM_Open 的第一個 parameter, 而 COM_Open 的回傳值, 即為 COM_Read 的 first parameter.

Paul, Chao @ Techware
点赞  2009-3-28 16:25
Paul,chao,我的两个真实串口的注册表如下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial]
   "Order"=dword:0
   "InterfaceType"=dword:0
   "IoBase"=dword:10030000
   "IoLen"=dword:20
   "Irq"=dword:9
   "DeviceArrayIndex"=dword:0
   "Prefix"="COM"
   "Index"=dword:3
   "Dll"="Serial.dll"
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial2]
   "Order"=dword:0
   "InterfaceType"=dword:0
   "IoBase"=dword:10031000
   "IoLen"=dword:20
   "Irq"=dword:8
   "DeviceArrayIndex"=dword:1
   "Prefix"="COM"
   "Index"=dword:2
   "Dll"="Serial.dll"
我研究了一下mdd.c中的COM_Init()发现没有对COM Index的记录呀
  DEBUGMSG (ZONE_INIT,(TEXT("Try to open %s\r\n"), (LPCTSTR)Identifier));
    hKey = OpenDeviceKey((LPCTSTR)Identifier);
    if ( !hKey ) {DEBUGMSG (ZONE_INIT | ZONE_ERROR,(TEXT("Failed to open devkeypath, COM_Init failed\r\n")));
           LocalFree(pSerialHead);
           return(NULL);
    }
    datasize = sizeof(DWORD);
    if ( RegQueryValueEx(hKey, L"有这个DeviceArrayIndex", NULL, &kvaluetype,(LPBYTE)&DevIndex, &datasize) ) {
        DEBUGMSG (ZONE_INIT | ZONE_ERROR,(TEXT("Failed to get DeviceArrayIndex value, COM_Init failed\r\n")));
        RegCloseKey (hKey);
        LocalFree(pSerialHead);
        return(NULL);
    }
    datasize = sizeof(DWORD);
    if ( RegQueryValueEx(hKey, L"有这个Priority256", NULL, &kvaluetype,
                         (LPBYTE)&pSerialHead->Priority256, &datasize) ) {
        pSerialHead->Priority256 = DEFAULT_CE_THREAD_PRIORITY;
        DEBUGMSG (ZONE_INIT | ZONE_WARN,(TEXT("Failed to get Priority256 value, defaulting to %d\r\n"), pSerialHead->Priority256));
    }
    RegCloseKey (hKey);
    DEBUGMSG (ZONE_INIT,
              (TEXT("DevIndex %X\r\n"), DevIndex));
    // Initialize hardware dependent data.
    pSerialHead->pHWObj = GetSerialObject( DevIndex );
    if ( !pSerialHead->pHWObj ) {
        DEBUGMSG(ZONE_ERROR | ZONE_INIT,
                 (TEXT("Error in GetSerialObject, COM_Init failed\n\r")));
        LocalFree(pSerialHead);
        return(NULL);
    }
    DEBUGMSG (ZONE_INIT, (TEXT("About to call HWInit(%s,0x%X)\r\n"),Identifier, pSerialHead));
    pHWHead = pSerialHead->pHWObj->pFuncTbl->HWInit(Identifier, pSerialHead, pSerialHead->pHWObj);
    pSerialHead->pHWHead = pHWHead;

只有DeviceArrayIndex和Priority256

况且即使有,按照流驱动的加载顺序:
1)加载驱动。在当系统启动时,设备管理器搜寻注册表的HKEY_LOCAL_MACHINE\Driver\BuiltIn键下面的子键,并逐一加载子键下的每个驱动,此过程叫BusEnum。
2)设备管理器从注册表的dll键值中获取驱动程序所在的DLL文件名。
3)设备管理器调用LoadDriver()函数把DLL加载到自己的虚拟地址空间内。
4)设备管理器在注册表的HKEY_LOCAL_MACHINE\Driver\Active下面,记录所有已经加载的驱动程序[2]。
5)设备管理器调用驱动中的XXX_Init()函数。
6)在XXX_Init()中,通常对硬件进行一些基本的初始化操作。通过以上6步,流接口驱动被成功加载。
7)应用程序使用该设备。首先它调用CreateFile()打开设备。CreateFile()是在FileSys.exe中实现的。但是FileSys.exe只作简单判断,如果发现打开的设备驱动程序而不是一个文件,那么就重新把主动权交还给设备管理器。
由此可见COM_Init()的执行要先于CreateFile(),那么COM_Init()执行完毕之后我注册表中的两个个串口的Index会同时被记录的呀
点赞  2009-3-28 17:27
把驱动加载流程搞懂,这些都不是问题了
点赞  2009-3-28 22:01
顶下,目前也遇到这个问题。
点赞  2009-4-8 09:00
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复