阅读:1764回复:2
Win CE中流驱动支持临界区的问题!
写了一个简单的流驱动,大体是这样的:
在DLL文件中,定义一个全局变量: unsigned char chBuffer[BUFSIZE]; 在XXX_Init中对其进行初始化为全0; DWORD COM_Init(DWORD dwContext) EnterCriticalSection(&(pDrv->InitCS)); memset (chBuffer, 0, BUFSIZE * sizeof(unsigned char)); LeaveCriticalSection(&(pDrv->InitCS)); 在XXX_Write()中对其写入数据,例如一个固定的字符串; DWORD COM_Write(HANDLE hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes) EnterCriticalSection(&(pDrv->WriteCS)); dwRet = min(BUFSIZE, NumberOfBytes); memcpy(chBuffer, (PBYTE)pSourceBytes, dwRet); LeaveCriticalSection(&(pDrv->WriteCS)); 在XXX_Read中把写入的数据读出; DWORD COM_Read(HANDLE hOpenContext, LPVOID pBuffer, DWORD Count) EnterCriticalSection(&(pDrv->ReadCS)); // Copy the smaller of buffer size or string size. DWORD dwcbBuffer = strlen((char *)chBuffer); dwRet = min(dwcbBuffer, Count); memcpy((unsigned char *)pBuffer, chBuffer, dwRet); LeaveCriticalSection(&(pDrv->ReadCS)); 大体就是这个样子,我在初始化,读,写里面加了临界区保护数据,DLL文件可以编译通过,但是生成NK文件,对流驱动进行操作时确同问题,调试口给出的信息是: Data Abort: Thread=8fe8b6d8 Proc=8e626160 'device.exe' AKY=00000005 PC=03f92490(coredll.dll+0x00022490) RA=06039a38(device.exe+0x00029a 38) BVA=06039a39 FSR=00000003 RaiseException: Thread=8fe8b6d8 Proc=8e626160 'device.exe' AKY=00000005 PC=03f8dff8(coredll.dll+0x0001dff8) RA=8c22a6d4(NK.EXE+0x0002a6d4) BVA=00000001 FSR=00000001 但是我把监界区保护去掉,程序驱动可以正常加载和调用,只要一出现临界区保护:EnterCriticalSection(); LeaveCriticalSection(); 就会出现上面的错误,会是那里的原因呢? |
|
沙发#
发布于:2008-01-28 14:33
这是驱动代码:
// VirtualCom.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "VirtualCom.h" HANDLE g_hInstance; #define BUFSIZE 2048 unsigned char chBuffer[BUFSIZE]; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hInstance = hModule; RETAILMSG(1,(TEXT("VirtualCom: DLL_PROCESS_ATTACH\n"))); DisableThreadLibraryCalls ((HMODULE)g_hInstance); break; //case DLL_THREAD_ATTACH: // RETAILMSG(1,(TEXT("VirtualCom: DLL_THREAD_ATTACH\n"))); // break; //case DLL_THREAD_DETACH: // RETAILMSG(1,(TEXT("VirtualCom: DLL_THREAD_DETACH\n"))); // break; case DLL_PROCESS_DETACH: RETAILMSG(1,(TEXT("VirtualCom: DLL_PROCESS_DETACH\n"))); break; } return TRUE; } // This is an example of an exported variable VirtualCom_API int nVirtualCom=0; // This is an example of an exported function. VirtualCom_API int fnVirtualCom(void) { return 42; } // This is the constructor of a class that has been exported. // see VirtualCom.h for the class definition CVirtualCom::CVirtualCom() { return; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DWORD COM_Init(DWORD dwContext) { PDRVCONTEXT pDrv; DWORD dwRet = 0; RETAILMSG(1,(TEXT("VirtualCom: COM_Init\n"))); //Allocate a driver instance struct pDrv = (PDRVCONTEXT)LocalAlloc(LPTR,sizeof(PDRVCONTEXT)); //allocate driver instance struct failed if(pDrv == NULL) { RETAILMSG(1,(TEXT("COM_Init:Allocate driver instance struct failed!\n"))); return 0; } //initialize driver instance struct memset((PBYTE)pDrv,0,sizeof(PDRVCONTEXT)); pDrv->dwSize = sizeof(PDRVCONTEXT); //initialize critical section variable InitializeCriticalSection(&(pDrv->InitCS)); InitializeCriticalSection(&(pDrv->CloseCS)); InitializeCriticalSection(&(pDrv->ReadCS)); InitializeCriticalSection(&(pDrv->WriteCS)); // Initialize buffer to zero. EnterCriticalSection(&(pDrv->InitCS)); RETAILMSG(1,(TEXT("COM_Init:EnterCriticalSection(&(pDrv->InitCS))\n"))); memset (chBuffer, 0, BUFSIZE * sizeof(unsigned char)); LeaveCriticalSection(&(pDrv->InitCS)); RETAILMSG(1,(TEXT("COM_Init:LeaveCriticalSection(&(pDrv->InitCS))\n"))); // Set return value to non-zero. dwRet = 1; return dwRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- BOOL COM_Deinit(DWORD hDeviceContext) { PDRVCONTEXT pDrv = (PDRVCONTEXT) hDeviceContext; BOOL bRet = TRUE; RETAILMSG(1,(TEXT("VirtualCom: COM_Deinit\n"))); if(pDrv&&(pDrv->dwSize == sizeof(PDRVCONTEXT))) { LocalFree((PBYTE)pDrv); RETAILMSG(1,(TEXT("COM_Deinit:LocalFree((PBYTE)pDrv)\n"))); } //Delete Critical Section //DeleteCriticalSection(&(pDrv->InitCS)); DeleteCriticalSection(&(pDrv->CloseCS)); DeleteCriticalSection(&(pDrv->ReadCS)); DeleteCriticalSection(&(pDrv->WriteCS)); return bRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DWORD COM_Open(HANDLE hDeviceContext, DWORD AccessCode, DWORD ShareMode) { PDRVCONTEXT pDrv = (PDRVCONTEXT)hDeviceContext; DWORD dwRet = 0; RETAILMSG(1,(TEXT("VirtualCom: COM_Open\n"))); //Verify that the context handle is valid //if(pDrv && (pDrv->dwSize != sizeof(PDRVCONTEXT))) //{ // RETAILMSG(1,(TEXT("COM_Open:context handle is invalid\n"))); // return 0; //} //count the number of opens RETAILMSG(1,(TEXT("COM_Open:Enter InterlockedIncrement\r\n"))); //InterlockedIncrement((long *)&pDrv->nNumOpens); RETAILMSG(1,(TEXT("COM_Open:pDrv->nNumOpens++\n"))); dwRet = 1; // Have to make non-zero for this call to succeed. return dwRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- BOOL COM_Close(DWORD hOpenContext) { PDRVCONTEXT pDrv = (PDRVCONTEXT)hOpenContext; BOOL bRet = TRUE; RETAILMSG(1,(TEXT("VirtualCom: COM_Close\n"))); //Verify that the context handle is valid if(pDrv && (pDrv->dwSize != sizeof(PDRVCONTEXT))) { return FALSE; } //Close stream driver and increase counter. //if(pDrv->nNumOpens) // pDrv->nNumOpens--; //Clear data buffer EnterCriticalSection(&(pDrv->CloseCS)); memset(chBuffer,0,sizeof(unsigned char)*BUFSIZE); LeaveCriticalSection(&(pDrv->CloseCS)); return bRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DWORD COM_Read(HANDLE hOpenContext, LPVOID pBuffer, DWORD Count) { PDRVCONTEXT pDrv = (PDRVCONTEXT)hOpenContext; DWORD dwRet = 0; RETAILMSG(1,(TEXT("VirtualCom: COM_Read\n"))); //Verify that the context handle is valid //if(pDrv && (pDrv->dwSize != sizeof(PDRVCONTEXT))) //{ // RETAILMSG(1,(TEXT("COM_Read:context handle is invalid\n"))); // return 0; //} RETAILMSG(1,(TEXT("VirtualCom: EnterCriticalSection(&(pDrv->ReadCS))\n"))); EnterCriticalSection(&(pDrv->ReadCS)); RETAILMSG(1,(TEXT("VirtualCom: Enter aleady CriticalSection(&(pDrv->ReadCS))\n"))); // Copy the smaller of buffer size or string size. //DWORD cbBuffer = wcslen(chBuffer); DWORD dwcbBuffer = strlen((char *)chBuffer); dwRet = min(dwcbBuffer, Count); memcpy((unsigned char *)pBuffer, chBuffer, dwRet); LeaveCriticalSection(&(pDrv->ReadCS)); RETAILMSG(1,(TEXT("VirtualCom: LeaveCriticalSection(&(pDrv->ReadCS))\n"))); // Return number of bytes read. return dwRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DWORD COM_Write(HANDLE hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes) { PDRVCONTEXT pDrv = (PDRVCONTEXT)hOpenContext; DWORD dwRet = 0; RETAILMSG(1,(TEXT("VirtualCom: COM_Write\n"))); //Verify that the context handle is valid //if(pDrv && (pDrv->dwSize != sizeof(PDRVCONTEXT))) //{ // RETAILMSG(1,(TEXT("COM_Write:context handle is invalid\n"))); // return 0; //} RETAILMSG(1,(TEXT("COM_Write:EnterCriticalSection(&(pDrv->WriteCS))\n"))); EnterCriticalSection(&(pDrv->WriteCS)); RETAILMSG(1,(TEXT("VirtualCom: Enter aleady CriticalSection(&(pDrv->WriteCS))\n"))); // Copy the smaller of buffer size or number of bytes they send us. dwRet = min(BUFSIZE, NumberOfBytes); memcpy(chBuffer, (PBYTE)pSourceBytes, dwRet); LeaveCriticalSection(&(pDrv->WriteCS)); RETAILMSG(1,(TEXT("COM_Write:LeaveCriticalSection(&(pDrv->WriteCS))\n"))); // Return number of bytes written. return dwRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- BOOL COM_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut) { BOOL bRet = TRUE; RETAILMSG(1,(TEXT("VirtualCom: COM_IOControl\n"))); return bRet; } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void COM_PowerDown(DWORD hDeviceContext) { RETAILMSG(1,(TEXT("VirtualCom: COM_PowerDown\n"))); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void COM_PowerUp(DWORD hDeviceContext) { RETAILMSG(1,(TEXT("VirtualCom: COM_PowerUp\n"))); } //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- DWORD COM_Seek(DWORD hOpenContext, long Amount, DWORD Type) { DWORD dwRet = 0; RETAILMSG(1,(TEXT("VirtualCom: COM_Seek\n"))); return dwRet; } |
|
板凳#
发布于:2008-01-28 14:35
PDRVCONTEXT是我定义的一个结构体.
typedef struct { DWORD dwSize; INT nNumOpens; CRITICAL_SECTION InitCS; CRITICAL_SECTION ReadCS; CRITICAL_SECTION WriteCS; CRITICAL_SECTION CloseCS; } DRVCONTEXT, *PDRVCONTEXT; |
|